├── LICENSE ├── addons └── sourcemod │ ├── configs │ └── mapchooser_extended │ │ ├── maps │ │ ├── csgo.txt │ │ ├── cstrike.txt │ │ ├── dods.txt │ │ ├── hl2mp.txt │ │ └── tf.txt │ │ └── sounds │ │ └── tf.cfg │ ├── scripting │ ├── include │ │ └── mapchooser_extended.inc │ ├── mapchooser_extended.sp │ ├── mapchooser_extended_sounds.sp │ ├── nominations_extended.sp │ └── rockthevote_extended.sp │ └── translations │ ├── chi │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── cze │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── da │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── de │ └── mapchooser_extended.phrases.txt │ ├── es │ └── mapchooser_extended.phrases.txt │ ├── fr │ ├── mapchooser_extended.phrases.old.txt │ └── mapchooser_extended.phrases.txt │ ├── hu │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── it │ └── mapchooser_extended.phrases.txt │ ├── jp │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── ko │ └── mapchooser_extended.phrases.txt │ ├── lv │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── mapchooser_extended.phrases.txt │ ├── nl │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── no │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ ├── pl │ └── mapchooser_extended.phrases.txt │ ├── pt │ └── mapchooser_extended.phrases.txt │ ├── ru │ └── mapchooser_extended.phrases.txt │ ├── sv │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt │ └── tr │ ├── incomplete.txt │ └── mapchooser_extended.phrases.txt └── sound_sets ├── hl1 ├── addons │ └── sourcemod │ │ └── configs │ │ └── mapchooser_extended │ │ └── sounds │ │ └── hl1.cfg └── sound │ └── mapchooser │ └── hl1 │ ├── bell_warning.mp3 │ ├── bell_warning.wav │ ├── eight.mp3 │ ├── eight.wav │ ├── endofvote.mp3 │ ├── five.mp3 │ ├── five.wav │ ├── four.mp3 │ ├── four.wav │ ├── gman_choose2.mp3 │ ├── gman_choose2.wav │ ├── nine.mp3 │ ├── nine.wav │ ├── one.mp3 │ ├── one.wav │ ├── seven.mp3 │ ├── seven.wav │ ├── six.mp3 │ ├── six.wav │ ├── sixty_seconds.mp3 │ ├── sixty_seconds.wav │ ├── startyourvoting.mp3 │ ├── ten_seconds.mp3 │ ├── ten_seconds.wav │ ├── thirty_seconds.mp3 │ ├── thirty_seconds.wav │ ├── three.mp3 │ ├── three.wav │ ├── twenty_seconds.mp3 │ ├── twenty_seconds.wav │ ├── two.mp3 │ └── two.wav ├── tf ├── addons │ └── sourcemod │ │ └── configs │ │ └── mapchooser_extended │ │ └── sounds │ │ └── tf.cfg └── sound │ └── mapchooser │ └── tf2 │ ├── announcer_begins_1sec.mp3 │ ├── announcer_begins_2sec.mp3 │ ├── announcer_begins_3sec.mp3 │ ├── announcer_begins_4sec.mp3 │ ├── announcer_begins_5sec.mp3 │ ├── announcer_dec_missionbegins10s01.mp3 │ ├── announcer_dec_missionbegins30s01.mp3 │ ├── announcer_dec_missionbegins60s03.mp3 │ ├── vote_failure.mp3 │ ├── vote_started.mp3 │ └── vote_success.mp3 └── tf_merasmus ├── addons └── sourcemod │ └── configs │ └── mapchooser_extended │ └── sounds │ └── tf.cfg └── sound └── mapchooser └── tf2_merasmus ├── sf14_merasmus_begins_01sec.mp3 ├── sf14_merasmus_begins_02sec.mp3 ├── sf14_merasmus_begins_03sec.mp3 ├── sf14_merasmus_begins_04sec.mp3 ├── sf14_merasmus_begins_05sec.mp3 ├── sf14_merasmus_minigame_fp_reveal07.mp3 ├── sf14_merasmus_minigame_overtime_03.mp3 ├── sf14_merasmus_necromasher_miss_10.mp3 └── sf14_merasmus_round_start_short_01.mp3 /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | 3 |
GNU GENERAL PUBLIC LICENSE
  4 |                        Version 3, 29 June 2007
  5 | 
  6 |  Copyright (C) 2007 Free Software Foundation, Inc. {http://fsf.org/}
  7 |  Everyone is permitted to copy and distribute verbatim copies
  8 |  of this license document, but changing it is not allowed.
  9 | 
 10 |                             Preamble
 11 | 
 12 |   The GNU General Public License is a free, copyleft license for
 13 | software and other kinds of works.
 14 | 
 15 |   The licenses for most software and other practical works are designed
 16 | to take away your freedom to share and change the works.  By contrast,
 17 | the GNU General Public License is intended to guarantee your freedom to
 18 | share and change all versions of a program--to make sure it remains free
 19 | software for all its users.  We, the Free Software Foundation, use the
 20 | GNU General Public License for most of our software; it applies also to
 21 | any other work released this way by its authors.  You can apply it to
 22 | your programs, too.
 23 | 
 24 |   When we speak of free software, we are referring to freedom, not
 25 | price.  Our General Public Licenses are designed to make sure that you
 26 | have the freedom to distribute copies of free software (and charge for
 27 | them if you wish), that you receive source code or can get it if you
 28 | want it, that you can change the software or use pieces of it in new
 29 | free programs, and that you know you can do these things.
 30 | 
 31 |   To protect your rights, we need to prevent others from denying you
 32 | these rights or asking you to surrender the rights.  Therefore, you have
 33 | certain responsibilities if you distribute copies of the software, or if
 34 | you modify it: responsibilities to respect the freedom of others.
 35 | 
 36 |   For example, if you distribute copies of such a program, whether
 37 | gratis or for a fee, you must pass on to the recipients the same
 38 | freedoms that you received.  You must make sure that they, too, receive
 39 | or can get the source code.  And you must show them these terms so they
 40 | know their rights.
 41 | 
 42 |   Developers that use the GNU GPL protect your rights with two steps:
 43 | (1) assert copyright on the software, and (2) offer you this License
 44 | giving you legal permission to copy, distribute and/or modify it.
 45 | 
 46 |   For the developers' and authors' protection, the GPL clearly explains
 47 | that there is no warranty for this free software.  For both users' and
 48 | authors' sake, the GPL requires that modified versions be marked as
 49 | changed, so that their problems will not be attributed erroneously to
 50 | authors of previous versions.
 51 | 
 52 |   Some devices are designed to deny users access to install or run
 53 | modified versions of the software inside them, although the manufacturer
 54 | can do so.  This is fundamentally incompatible with the aim of
 55 | protecting users' freedom to change the software.  The systematic
 56 | pattern of such abuse occurs in the area of products for individuals to
 57 | use, which is precisely where it is most unacceptable.  Therefore, we
 58 | have designed this version of the GPL to prohibit the practice for those
 59 | products.  If such problems arise substantially in other domains, we
 60 | stand ready to extend this provision to those domains in future versions
 61 | of the GPL, as needed to protect the freedom of users.
 62 | 
 63 |   Finally, every program is threatened constantly by software patents.
 64 | States should not allow patents to restrict development and use of
 65 | software on general-purpose computers, but in those that do, we wish to
 66 | avoid the special danger that patents applied to a free program could
 67 | make it effectively proprietary.  To prevent this, the GPL assures that
 68 | patents cannot be used to render the program non-free.
 69 | 
 70 |   The precise terms and conditions for copying, distribution and
 71 | modification follow.
 72 | 
 73 |                        TERMS AND CONDITIONS
 74 | 
 75 |   0. Definitions.
 76 | 
 77 |   "This License" refers to version 3 of the GNU General Public License.
 78 | 
 79 |   "Copyright" also means copyright-like laws that apply to other kinds of
 80 | works, such as semiconductor masks.
 81 | 
 82 |   "The Program" refers to any copyrightable work licensed under this
 83 | License.  Each licensee is addressed as "you".  "Licensees" and
 84 | "recipients" may be individuals or organizations.
 85 | 
 86 |   To "modify" a work means to copy from or adapt all or part of the work
 87 | in a fashion requiring copyright permission, other than the making of an
 88 | exact copy.  The resulting work is called a "modified version" of the
 89 | earlier work or a work "based on" the earlier work.
 90 | 
 91 |   A "covered work" means either the unmodified Program or a work based
 92 | on the Program.
 93 | 
 94 |   To "propagate" a work means to do anything with it that, without
 95 | permission, would make you directly or secondarily liable for
 96 | infringement under applicable copyright law, except executing it on a
 97 | computer or modifying a private copy.  Propagation includes copying,
 98 | distribution (with or without modification), making available to the
 99 | public, and in some countries other activities as well.
100 | 
101 |   To "convey" a work means any kind of propagation that enables other
102 | parties to make or receive copies.  Mere interaction with a user through
103 | a computer network, with no transfer of a copy, is not conveying.
104 | 
105 |   An interactive user interface displays "Appropriate Legal Notices"
106 | to the extent that it includes a convenient and prominently visible
107 | feature that (1) displays an appropriate copyright notice, and (2)
108 | tells the user that there is no warranty for the work (except to the
109 | extent that warranties are provided), that licensees may convey the
110 | work under this License, and how to view a copy of this License.  If
111 | the interface presents a list of user commands or options, such as a
112 | menu, a prominent item in the list meets this criterion.
113 | 
114 |   1. Source Code.
115 | 
116 |   The "source code" for a work means the preferred form of the work
117 | for making modifications to it.  "Object code" means any non-source
118 | form of a work.
119 | 
120 |   A "Standard Interface" means an interface that either is an official
121 | standard defined by a recognized standards body, or, in the case of
122 | interfaces specified for a particular programming language, one that
123 | is widely used among developers working in that language.
124 | 
125 |   The "System Libraries" of an executable work include anything, other
126 | than the work as a whole, that (a) is included in the normal form of
127 | packaging a Major Component, but which is not part of that Major
128 | Component, and (b) serves only to enable use of the work with that
129 | Major Component, or to implement a Standard Interface for which an
130 | implementation is available to the public in source code form.  A
131 | "Major Component", in this context, means a major essential component
132 | (kernel, window system, and so on) of the specific operating system
133 | (if any) on which the executable work runs, or a compiler used to
134 | produce the work, or an object code interpreter used to run it.
135 | 
136 |   The "Corresponding Source" for a work in object code form means all
137 | the source code needed to generate, install, and (for an executable
138 | work) run the object code and to modify the work, including scripts to
139 | control those activities.  However, it does not include the work's
140 | System Libraries, or general-purpose tools or generally available free
141 | programs which are used unmodified in performing those activities but
142 | which are not part of the work.  For example, Corresponding Source
143 | includes interface definition files associated with source files for
144 | the work, and the source code for shared libraries and dynamically
145 | linked subprograms that the work is specifically designed to require,
146 | such as by intimate data communication or control flow between those
147 | subprograms and other parts of the work.
148 | 
149 |   The Corresponding Source need not include anything that users
150 | can regenerate automatically from other parts of the Corresponding
151 | Source.
152 | 
153 |   The Corresponding Source for a work in source code form is that
154 | same work.
155 | 
156 |   2. Basic Permissions.
157 | 
158 |   All rights granted under this License are granted for the term of
159 | copyright on the Program, and are irrevocable provided the stated
160 | conditions are met.  This License explicitly affirms your unlimited
161 | permission to run the unmodified Program.  The output from running a
162 | covered work is covered by this License only if the output, given its
163 | content, constitutes a covered work.  This License acknowledges your
164 | rights of fair use or other equivalent, as provided by copyright law.
165 | 
166 |   You may make, run and propagate covered works that you do not
167 | convey, without conditions so long as your license otherwise remains
168 | in force.  You may convey covered works to others for the sole purpose
169 | of having them make modifications exclusively for you, or provide you
170 | with facilities for running those works, provided that you comply with
171 | the terms of this License in conveying all material for which you do
172 | not control copyright.  Those thus making or running the covered works
173 | for you must do so exclusively on your behalf, under your direction
174 | and control, on terms that prohibit them from making any copies of
175 | your copyrighted material outside their relationship with you.
176 | 
177 |   Conveying under any other circumstances is permitted solely under
178 | the conditions stated below.  Sublicensing is not allowed; section 10
179 | makes it unnecessary.
180 | 
181 |   3. Protecting Users' Legal Rights From Anti-Circumvention Law.
182 | 
183 |   No covered work shall be deemed part of an effective technological
184 | measure under any applicable law fulfilling obligations under article
185 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
186 | similar laws prohibiting or restricting circumvention of such
187 | measures.
188 | 
189 |   When you convey a covered work, you waive any legal power to forbid
190 | circumvention of technological measures to the extent such circumvention
191 | is effected by exercising rights under this License with respect to
192 | the covered work, and you disclaim any intention to limit operation or
193 | modification of the work as a means of enforcing, against the work's
194 | users, your or third parties' legal rights to forbid circumvention of
195 | technological measures.
196 | 
197 |   4. Conveying Verbatim Copies.
198 | 
199 |   You may convey verbatim copies of the Program's source code as you
200 | receive it, in any medium, provided that you conspicuously and
201 | appropriately publish on each copy an appropriate copyright notice;
202 | keep intact all notices stating that this License and any
203 | non-permissive terms added in accord with section 7 apply to the code;
204 | keep intact all notices of the absence of any warranty; and give all
205 | recipients a copy of this License along with the Program.
206 | 
207 |   You may charge any price or no price for each copy that you convey,
208 | and you may offer support or warranty protection for a fee.
209 | 
210 |   5. Conveying Modified Source Versions.
211 | 
212 |   You may convey a work based on the Program, or the modifications to
213 | produce it from the Program, in the form of source code under the
214 | terms of section 4, provided that you also meet all of these conditions:
215 | 
216 |     a) The work must carry prominent notices stating that you modified
217 |     it, and giving a relevant date.
218 | 
219 |     b) The work must carry prominent notices stating that it is
220 |     released under this License and any conditions added under section
221 |     7.  This requirement modifies the requirement in section 4 to
222 |     "keep intact all notices".
223 | 
224 |     c) You must license the entire work, as a whole, under this
225 |     License to anyone who comes into possession of a copy.  This
226 |     License will therefore apply, along with any applicable section 7
227 |     additional terms, to the whole of the work, and all its parts,
228 |     regardless of how they are packaged.  This License gives no
229 |     permission to license the work in any other way, but it does not
230 |     invalidate such permission if you have separately received it.
231 | 
232 |     d) If the work has interactive user interfaces, each must display
233 |     Appropriate Legal Notices; however, if the Program has interactive
234 |     interfaces that do not display Appropriate Legal Notices, your
235 |     work need not make them do so.
236 | 
237 |   A compilation of a covered work with other separate and independent
238 | works, which are not by their nature extensions of the covered work,
239 | and which are not combined with it such as to form a larger program,
240 | in or on a volume of a storage or distribution medium, is called an
241 | "aggregate" if the compilation and its resulting copyright are not
242 | used to limit the access or legal rights of the compilation's users
243 | beyond what the individual works permit.  Inclusion of a covered work
244 | in an aggregate does not cause this License to apply to the other
245 | parts of the aggregate.
246 | 
247 |   6. Conveying Non-Source Forms.
248 | 
249 |   You may convey a covered work in object code form under the terms
250 | of sections 4 and 5, provided that you also convey the
251 | machine-readable Corresponding Source under the terms of this License,
252 | in one of these ways:
253 | 
254 |     a) Convey the object code in, or embodied in, a physical product
255 |     (including a physical distribution medium), accompanied by the
256 |     Corresponding Source fixed on a durable physical medium
257 |     customarily used for software interchange.
258 | 
259 |     b) Convey the object code in, or embodied in, a physical product
260 |     (including a physical distribution medium), accompanied by a
261 |     written offer, valid for at least three years and valid for as
262 |     long as you offer spare parts or customer support for that product
263 |     model, to give anyone who possesses the object code either (1) a
264 |     copy of the Corresponding Source for all the software in the
265 |     product that is covered by this License, on a durable physical
266 |     medium customarily used for software interchange, for a price no
267 |     more than your reasonable cost of physically performing this
268 |     conveying of source, or (2) access to copy the
269 |     Corresponding Source from a network server at no charge.
270 | 
271 |     c) Convey individual copies of the object code with a copy of the
272 |     written offer to provide the Corresponding Source.  This
273 |     alternative is allowed only occasionally and noncommercially, and
274 |     only if you received the object code with such an offer, in accord
275 |     with subsection 6b.
276 | 
277 |     d) Convey the object code by offering access from a designated
278 |     place (gratis or for a charge), and offer equivalent access to the
279 |     Corresponding Source in the same way through the same place at no
280 |     further charge.  You need not require recipients to copy the
281 |     Corresponding Source along with the object code.  If the place to
282 |     copy the object code is a network server, the Corresponding Source
283 |     may be on a different server (operated by you or a third party)
284 |     that supports equivalent copying facilities, provided you maintain
285 |     clear directions next to the object code saying where to find the
286 |     Corresponding Source.  Regardless of what server hosts the
287 |     Corresponding Source, you remain obligated to ensure that it is
288 |     available for as long as needed to satisfy these requirements.
289 | 
290 |     e) Convey the object code using peer-to-peer transmission, provided
291 |     you inform other peers where the object code and Corresponding
292 |     Source of the work are being offered to the general public at no
293 |     charge under subsection 6d.
294 | 
295 |   A separable portion of the object code, whose source code is excluded
296 | from the Corresponding Source as a System Library, need not be
297 | included in conveying the object code work.
298 | 
299 |   A "User Product" is either (1) a "consumer product", which means any
300 | tangible personal property which is normally used for personal, family,
301 | or household purposes, or (2) anything designed or sold for incorporation
302 | into a dwelling.  In determining whether a product is a consumer product,
303 | doubtful cases shall be resolved in favor of coverage.  For a particular
304 | product received by a particular user, "normally used" refers to a
305 | typical or common use of that class of product, regardless of the status
306 | of the particular user or of the way in which the particular user
307 | actually uses, or expects or is expected to use, the product.  A product
308 | is a consumer product regardless of whether the product has substantial
309 | commercial, industrial or non-consumer uses, unless such uses represent
310 | the only significant mode of use of the product.
311 | 
312 |   "Installation Information" for a User Product means any methods,
313 | procedures, authorization keys, or other information required to install
314 | and execute modified versions of a covered work in that User Product from
315 | a modified version of its Corresponding Source.  The information must
316 | suffice to ensure that the continued functioning of the modified object
317 | code is in no case prevented or interfered with solely because
318 | modification has been made.
319 | 
320 |   If you convey an object code work under this section in, or with, or
321 | specifically for use in, a User Product, and the conveying occurs as
322 | part of a transaction in which the right of possession and use of the
323 | User Product is transferred to the recipient in perpetuity or for a
324 | fixed term (regardless of how the transaction is characterized), the
325 | Corresponding Source conveyed under this section must be accompanied
326 | by the Installation Information.  But this requirement does not apply
327 | if neither you nor any third party retains the ability to install
328 | modified object code on the User Product (for example, the work has
329 | been installed in ROM).
330 | 
331 |   The requirement to provide Installation Information does not include a
332 | requirement to continue to provide support service, warranty, or updates
333 | for a work that has been modified or installed by the recipient, or for
334 | the User Product in which it has been modified or installed.  Access to a
335 | network may be denied when the modification itself materially and
336 | adversely affects the operation of the network or violates the rules and
337 | protocols for communication across the network.
338 | 
339 |   Corresponding Source conveyed, and Installation Information provided,
340 | in accord with this section must be in a format that is publicly
341 | documented (and with an implementation available to the public in
342 | source code form), and must require no special password or key for
343 | unpacking, reading or copying.
344 | 
345 |   7. Additional Terms.
346 | 
347 |   "Additional permissions" are terms that supplement the terms of this
348 | License by making exceptions from one or more of its conditions.
349 | Additional permissions that are applicable to the entire Program shall
350 | be treated as though they were included in this License, to the extent
351 | that they are valid under applicable law.  If additional permissions
352 | apply only to part of the Program, that part may be used separately
353 | under those permissions, but the entire Program remains governed by
354 | this License without regard to the additional permissions.
355 | 
356 |   When you convey a copy of a covered work, you may at your option
357 | remove any additional permissions from that copy, or from any part of
358 | it.  (Additional permissions may be written to require their own
359 | removal in certain cases when you modify the work.)  You may place
360 | additional permissions on material, added by you to a covered work,
361 | for which you have or can give appropriate copyright permission.
362 | 
363 |   Notwithstanding any other provision of this License, for material you
364 | add to a covered work, you may (if authorized by the copyright holders of
365 | that material) supplement the terms of this License with terms:
366 | 
367 |     a) Disclaiming warranty or limiting liability differently from the
368 |     terms of sections 15 and 16 of this License; or
369 | 
370 |     b) Requiring preservation of specified reasonable legal notices or
371 |     author attributions in that material or in the Appropriate Legal
372 |     Notices displayed by works containing it; or
373 | 
374 |     c) Prohibiting misrepresentation of the origin of that material, or
375 |     requiring that modified versions of such material be marked in
376 |     reasonable ways as different from the original version; or
377 | 
378 |     d) Limiting the use for publicity purposes of names of licensors or
379 |     authors of the material; or
380 | 
381 |     e) Declining to grant rights under trademark law for use of some
382 |     trade names, trademarks, or service marks; or
383 | 
384 |     f) Requiring indemnification of licensors and authors of that
385 |     material by anyone who conveys the material (or modified versions of
386 |     it) with contractual assumptions of liability to the recipient, for
387 |     any liability that these contractual assumptions directly impose on
388 |     those licensors and authors.
389 | 
390 |   All other non-permissive additional terms are considered "further
391 | restrictions" within the meaning of section 10.  If the Program as you
392 | received it, or any part of it, contains a notice stating that it is
393 | governed by this License along with a term that is a further
394 | restriction, you may remove that term.  If a license document contains
395 | a further restriction but permits relicensing or conveying under this
396 | License, you may add to a covered work material governed by the terms
397 | of that license document, provided that the further restriction does
398 | not survive such relicensing or conveying.
399 | 
400 |   If you add terms to a covered work in accord with this section, you
401 | must place, in the relevant source files, a statement of the
402 | additional terms that apply to those files, or a notice indicating
403 | where to find the applicable terms.
404 | 
405 |   Additional terms, permissive or non-permissive, may be stated in the
406 | form of a separately written license, or stated as exceptions;
407 | the above requirements apply either way.
408 | 
409 |   8. Termination.
410 | 
411 |   You may not propagate or modify a covered work except as expressly
412 | provided under this License.  Any attempt otherwise to propagate or
413 | modify it is void, and will automatically terminate your rights under
414 | this License (including any patent licenses granted under the third
415 | paragraph of section 11).
416 | 
417 |   However, if you cease all violation of this License, then your
418 | license from a particular copyright holder is reinstated (a)
419 | provisionally, unless and until the copyright holder explicitly and
420 | finally terminates your license, and (b) permanently, if the copyright
421 | holder fails to notify you of the violation by some reasonable means
422 | prior to 60 days after the cessation.
423 | 
424 |   Moreover, your license from a particular copyright holder is
425 | reinstated permanently if the copyright holder notifies you of the
426 | violation by some reasonable means, this is the first time you have
427 | received notice of violation of this License (for any work) from that
428 | copyright holder, and you cure the violation prior to 30 days after
429 | your receipt of the notice.
430 | 
431 |   Termination of your rights under this section does not terminate the
432 | licenses of parties who have received copies or rights from you under
433 | this License.  If your rights have been terminated and not permanently
434 | reinstated, you do not qualify to receive new licenses for the same
435 | material under section 10.
436 | 
437 |   9. Acceptance Not Required for Having Copies.
438 | 
439 |   You are not required to accept this License in order to receive or
440 | run a copy of the Program.  Ancillary propagation of a covered work
441 | occurring solely as a consequence of using peer-to-peer transmission
442 | to receive a copy likewise does not require acceptance.  However,
443 | nothing other than this License grants you permission to propagate or
444 | modify any covered work.  These actions infringe copyright if you do
445 | not accept this License.  Therefore, by modifying or propagating a
446 | covered work, you indicate your acceptance of this License to do so.
447 | 
448 |   10. Automatic Licensing of Downstream Recipients.
449 | 
450 |   Each time you convey a covered work, the recipient automatically
451 | receives a license from the original licensors, to run, modify and
452 | propagate that work, subject to this License.  You are not responsible
453 | for enforcing compliance by third parties with this License.
454 | 
455 |   An "entity transaction" is a transaction transferring control of an
456 | organization, or substantially all assets of one, or subdividing an
457 | organization, or merging organizations.  If propagation of a covered
458 | work results from an entity transaction, each party to that
459 | transaction who receives a copy of the work also receives whatever
460 | licenses to the work the party's predecessor in interest had or could
461 | give under the previous paragraph, plus a right to possession of the
462 | Corresponding Source of the work from the predecessor in interest, if
463 | the predecessor has it or can get it with reasonable efforts.
464 | 
465 |   You may not impose any further restrictions on the exercise of the
466 | rights granted or affirmed under this License.  For example, you may
467 | not impose a license fee, royalty, or other charge for exercise of
468 | rights granted under this License, and you may not initiate litigation
469 | (including a cross-claim or counterclaim in a lawsuit) alleging that
470 | any patent claim is infringed by making, using, selling, offering for
471 | sale, or importing the Program or any portion of it.
472 | 
473 |   11. Patents.
474 | 
475 |   A "contributor" is a copyright holder who authorizes use under this
476 | License of the Program or a work on which the Program is based.  The
477 | work thus licensed is called the contributor's "contributor version".
478 | 
479 |   A contributor's "essential patent claims" are all patent claims
480 | owned or controlled by the contributor, whether already acquired or
481 | hereafter acquired, that would be infringed by some manner, permitted
482 | by this License, of making, using, or selling its contributor version,
483 | but do not include claims that would be infringed only as a
484 | consequence of further modification of the contributor version.  For
485 | purposes of this definition, "control" includes the right to grant
486 | patent sublicenses in a manner consistent with the requirements of
487 | this License.
488 | 
489 |   Each contributor grants you a non-exclusive, worldwide, royalty-free
490 | patent license under the contributor's essential patent claims, to
491 | make, use, sell, offer for sale, import and otherwise run, modify and
492 | propagate the contents of its contributor version.
493 | 
494 |   In the following three paragraphs, a "patent license" is any express
495 | agreement or commitment, however denominated, not to enforce a patent
496 | (such as an express permission to practice a patent or covenant not to
497 | sue for patent infringement).  To "grant" such a patent license to a
498 | party means to make such an agreement or commitment not to enforce a
499 | patent against the party.
500 | 
501 |   If you convey a covered work, knowingly relying on a patent license,
502 | and the Corresponding Source of the work is not available for anyone
503 | to copy, free of charge and under the terms of this License, through a
504 | publicly available network server or other readily accessible means,
505 | then you must either (1) cause the Corresponding Source to be so
506 | available, or (2) arrange to deprive yourself of the benefit of the
507 | patent license for this particular work, or (3) arrange, in a manner
508 | consistent with the requirements of this License, to extend the patent
509 | license to downstream recipients.  "Knowingly relying" means you have
510 | actual knowledge that, but for the patent license, your conveying the
511 | covered work in a country, or your recipient's use of the covered work
512 | in a country, would infringe one or more identifiable patents in that
513 | country that you have reason to believe are valid.
514 | 
515 |   If, pursuant to or in connection with a single transaction or
516 | arrangement, you convey, or propagate by procuring conveyance of, a
517 | covered work, and grant a patent license to some of the parties
518 | receiving the covered work authorizing them to use, propagate, modify
519 | or convey a specific copy of the covered work, then the patent license
520 | you grant is automatically extended to all recipients of the covered
521 | work and works based on it.
522 | 
523 |   A patent license is "discriminatory" if it does not include within
524 | the scope of its coverage, prohibits the exercise of, or is
525 | conditioned on the non-exercise of one or more of the rights that are
526 | specifically granted under this License.  You may not convey a covered
527 | work if you are a party to an arrangement with a third party that is
528 | in the business of distributing software, under which you make payment
529 | to the third party based on the extent of your activity of conveying
530 | the work, and under which the third party grants, to any of the
531 | parties who would receive the covered work from you, a discriminatory
532 | patent license (a) in connection with copies of the covered work
533 | conveyed by you (or copies made from those copies), or (b) primarily
534 | for and in connection with specific products or compilations that
535 | contain the covered work, unless you entered into that arrangement,
536 | or that patent license was granted, prior to 28 March 2007.
537 | 
538 |   Nothing in this License shall be construed as excluding or limiting
539 | any implied license or other defenses to infringement that may
540 | otherwise be available to you under applicable patent law.
541 | 
542 |   12. No Surrender of Others' Freedom.
543 | 
544 |   If conditions are imposed on you (whether by court order, agreement or
545 | otherwise) that contradict the conditions of this License, they do not
546 | excuse you from the conditions of this License.  If you cannot convey a
547 | covered work so as to satisfy simultaneously your obligations under this
548 | License and any other pertinent obligations, then as a consequence you may
549 | not convey it at all.  For example, if you agree to terms that obligate you
550 | to collect a royalty for further conveying from those to whom you convey
551 | the Program, the only way you could satisfy both those terms and this
552 | License would be to refrain entirely from conveying the Program.
553 | 
554 |   13. Use with the GNU Affero General Public License.
555 | 
556 |   Notwithstanding any other provision of this License, you have
557 | permission to link or combine any covered work with a work licensed
558 | under version 3 of the GNU Affero General Public License into a single
559 | combined work, and to convey the resulting work.  The terms of this
560 | License will continue to apply to the part which is the covered work,
561 | but the special requirements of the GNU Affero General Public License,
562 | section 13, concerning interaction through a network will apply to the
563 | combination as such.
564 | 
565 |   14. Revised Versions of this License.
566 | 
567 |   The Free Software Foundation may publish revised and/or new versions of
568 | the GNU General Public License from time to time.  Such new versions will
569 | be similar in spirit to the present version, but may differ in detail to
570 | address new problems or concerns.
571 | 
572 |   Each version is given a distinguishing version number.  If the
573 | Program specifies that a certain numbered version of the GNU General
574 | Public License "or any later version" applies to it, you have the
575 | option of following the terms and conditions either of that numbered
576 | version or of any later version published by the Free Software
577 | Foundation.  If the Program does not specify a version number of the
578 | GNU General Public License, you may choose any version ever published
579 | by the Free Software Foundation.
580 | 
581 |   If the Program specifies that a proxy can decide which future
582 | versions of the GNU General Public License can be used, that proxy's
583 | public statement of acceptance of a version permanently authorizes you
584 | to choose that version for the Program.
585 | 
586 |   Later license versions may give you additional or different
587 | permissions.  However, no additional obligations are imposed on any
588 | author or copyright holder as a result of your choosing to follow a
589 | later version.
590 | 
591 |   15. Disclaimer of Warranty.
592 | 
593 |   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
594 | APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
595 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
596 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
597 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
598 | PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
599 | IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
600 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
601 | 
602 |   16. Limitation of Liability.
603 | 
604 |   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
605 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
606 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
607 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
608 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
609 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
610 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
611 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
612 | SUCH DAMAGES.
613 | 
614 |   17. Interpretation of Sections 15 and 16.
615 | 
616 |   If the disclaimer of warranty and limitation of liability provided
617 | above cannot be given local legal effect according to their terms,
618 | reviewing courts shall apply local law that most closely approximates
619 | an absolute waiver of all civil liability in connection with the
620 | Program, unless a warranty or assumption of liability accompanies a
621 | copy of the Program in return for a fee.
622 | 
623 |                      END OF TERMS AND CONDITIONS
624 | 
625 |             How to Apply These Terms to Your New Programs
626 | 
627 |   If you develop a new program, and you want it to be of the greatest
628 | possible use to the public, the best way to achieve this is to make it
629 | free software which everyone can redistribute and change under these terms.
630 | 
631 |   To do so, attach the following notices to the program.  It is safest
632 | to attach them to the start of each source file to most effectively
633 | state the exclusion of warranty; and each file should have at least
634 | the "copyright" line and a pointer to where the full notice is found.
635 | 
636 |     {one line to give the program's name and a brief idea of what it does.}
637 |     Copyright (C) {year}  {name of author}
638 | 
639 |     This program is free software: you can redistribute it and/or modify
640 |     it under the terms of the GNU General Public License as published by
641 |     the Free Software Foundation, either version 3 of the License, or
642 |     (at your option) any later version.
643 | 
644 |     This program is distributed in the hope that it will be useful,
645 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
646 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
647 |     GNU General Public License for more details.
648 | 
649 |     You should have received a copy of the GNU General Public License
650 |     along with this program.  If not, see {http://www.gnu.org/licenses/}.
651 | 
652 | Also add information on how to contact you by electronic and paper mail.
653 | 
654 |   If the program does terminal interaction, make it output a short
655 | notice like this when it starts in an interactive mode:
656 | 
657 |     sourcemod-optin-multimod  Copyright (C) 2013  Ross Bemrose
658 |     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
659 |     This is free software, and you are welcome to redistribute it
660 |     under certain conditions; type `show c' for details.
661 | 
662 | The hypothetical commands `show w' and `show c' should show the appropriate
663 | parts of the General Public License.  Of course, your program's commands
664 | might be different; for a GUI interface, you would use an "about box".
665 | 
666 |   You should also get your employer (if you work as a programmer) or school,
667 | if any, to sign a "copyright disclaimer" for the program, if necessary.
668 | For more information on this, and how to apply and follow the GNU GPL, see
669 | {http://www.gnu.org/licenses/}.
670 | 
671 |   The GNU General Public License does not permit incorporating your program
672 | into proprietary programs.  If your program is a subroutine library, you
673 | may consider it more useful to permit linking proprietary applications with
674 | the library.  If this is what you want to do, use the GNU Lesser General
675 | Public License instead of this License.  But first, please read
676 | {http://www.gnu.org/philosophy/why-not-lgpl.html}.
677 | 
-------------------------------------------------------------------------------- /addons/sourcemod/configs/mapchooser_extended/maps/csgo.txt: -------------------------------------------------------------------------------- 1 | ar_baggage 2 | ar_monastery 3 | ar_shoots 4 | cs_agency 5 | cs_assault 6 | cs_backalley 7 | cs_cruise 8 | cs_downtown 9 | cs_insertion 10 | cs_italy 11 | cs_militia 12 | cs_motel 13 | cs_office 14 | cs_rush 15 | cs_thunder 16 | cs_workout 17 | de_ali 18 | de_aztec 19 | de_bank 20 | de_bazaar 21 | de_blackgold 22 | de_cache 23 | de_castle 24 | de_cbble 25 | de_coast 26 | de_dust 27 | de_dust2 28 | de_empire 29 | de_facade 30 | de_favela 31 | de_inferno 32 | de_lake 33 | de_log 34 | de_marquis 35 | de_mikla 36 | de_mirage 37 | de_mist 38 | de_nuke 39 | de_overgrown 40 | de_overpass 41 | de_rails 42 | de_resort 43 | de_royal 44 | de_safehouse 45 | de_santorini 46 | de_seaside 47 | de_season 48 | de_shortdust 49 | de_shorttrain 50 | de_stmarc 51 | de_sugarcane 52 | de_train 53 | de_tulip 54 | de_vertigo 55 | de_zoo 56 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/mapchooser_extended/maps/cstrike.txt: -------------------------------------------------------------------------------- 1 | as_oilrig 2 | cs_747 3 | cs_assault 4 | cs_backalley 5 | cs_compound 6 | cs_estate 7 | cs_havana 8 | cs_italy 9 | cs_militia 10 | cs_office 11 | cs_siege 12 | de_airstrip 13 | de_aztec 14 | de_cbble 15 | de_chateau 16 | de_dust2 17 | de_dust 18 | de_inferno 19 | de_nuke 20 | de_piranesi 21 | de_port 22 | de_prodigy 23 | de_storm 24 | de_survivor 25 | de_tides 26 | de_torn 27 | de_train 28 | de_vertigo 29 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/mapchooser_extended/maps/dods.txt: -------------------------------------------------------------------------------- 1 | dod_anzio 2 | dod_argentan 3 | dod_avalanche 4 | dod_colmar 5 | dod_donner 6 | dod_flash 7 | dod_jagd 8 | dod_kalt 9 | dod_palermo 10 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/mapchooser_extended/maps/hl2mp.txt: -------------------------------------------------------------------------------- 1 | dm_lockdown 2 | dm_overwatch 3 | dm_runoff 4 | dm_steamlab 5 | dm_underpass 6 | dm_resistance 7 | dm_powerhouse 8 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/mapchooser_extended/maps/tf.txt: -------------------------------------------------------------------------------- 1 | tc_hydro 2 | cp_well 3 | cp_granary 4 | cp_dustbowl 5 | cp_gravelpit 6 | ctf_2fort 7 | ctf_well 8 | cp_badlands 9 | pl_goldrush 10 | cp_fastlane 11 | ctf_turbine 12 | pl_badwater 13 | cp_steel 14 | arena_badlands 15 | arena_granary 16 | arena_lumberyard 17 | arena_ravine 18 | arena_well 19 | cp_egypt_final 20 | cp_junction_final 21 | arena_watchtower 22 | plr_pipeline 23 | arena_sawmill 24 | arena_nucleus 25 | pl_hoodoo_final 26 | koth_sawmill 27 | koth_nucleus 28 | koth_viaduct 29 | ctf_sawmill 30 | arena_offblast_final 31 | cp_yukon_final 32 | koth_harvest_final 33 | koth_harvest_event 34 | ctf_doublecross 35 | cp_gorge 36 | cp_freight_final1 37 | pl_upward 38 | plr_hightower 39 | pl_thundermountain 40 | cp_coldfront 41 | cp_mountainlab 42 | cp_manor_event 43 | cp_degrootkeep 44 | cp_5gorge 45 | pl_frontier_final 46 | plr_nightfall_final 47 | koth_lakeside_final 48 | koth_badlands 49 | pl_barnblitz 50 | cp_gullywash_final1 51 | koth_viaduct_event 52 | cp_foundry 53 | sd_doomsday 54 | koth_king 55 | mvm_mannworks 56 | mvm_coaltown 57 | mvm_decoy 58 | koth_lakeside_event 59 | mvm_bigrock 60 | cp_process_final 61 | cp_standin_final 62 | plr_hightower_event 63 | cp_snakewater_final1 64 | mvm_mannhattan 65 | mvm_rottenburg 66 | pl_cactuscanyon 67 | rd_asteroid 68 | sd_doomsday_event 69 | ctf_foundry 70 | ctf_gorge 71 | ctf_thundermountain 72 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/mapchooser_extended/sounds/tf.cfg: -------------------------------------------------------------------------------- 1 | "MapchooserSoundsList" 2 | { 3 | "tf" 4 | { 5 | "counter" 6 | { 7 | "1" 8 | { 9 | "sound" "mapchooser/tf2/announcer_begins_1sec.mp3" 10 | "builtin" "vo/announcer_begins_1sec.mp3" 11 | "event" "Announcer.RoundBegins1Seconds" 12 | } 13 | "2" 14 | { 15 | "sound" "mapchooser/tf2/announcer_begins_2sec.mp3" 16 | "builtin" "vo/announcer_begins_2sec.mp3" 17 | "event" "Announcer.RoundBegins2Seconds" 18 | } 19 | "3" 20 | { 21 | "sound" "mapchooser/tf2/announcer_begins_3sec.mp3" 22 | "builtin" "vo/announcer_begins_3sec.mp3" 23 | "event" "Announcer.RoundBegins3Seconds" 24 | } 25 | "4" 26 | { 27 | "sound" "mapchooser/tf2/announcer_begins_4sec.mp3" 28 | "builtin" "vo/announcer_begins_4sec.mp3" 29 | "event" "Announcer.RoundBegins4Seconds" 30 | } 31 | "5" 32 | { 33 | "sound" "mapchooser/tf2/announcer_begins_5sec.mp3" 34 | "builtin" "vo/announcer_begins_5sec.mp3" 35 | "event" "Announcer.RoundBegins5Seconds" 36 | } 37 | "10" 38 | { 39 | "sound" "mapchooser/tf2/announcer_dec_missionbegins10s01.mp3" 40 | "builtin" "vo/announcer_dec_missionbegins10s01.mp3" 41 | } 42 | "30" 43 | { 44 | "sound" "mapchooser/tf2/announcer_dec_missionbegins30s01.mp3" 45 | "builtin" "vo/announcer_dec_missionbegins30s01.mp3" 46 | } 47 | } 48 | "vote start" 49 | { 50 | "sound" "mapchooser/tf2/vote_started.mp3" 51 | "event" "Vote.Created" 52 | "builtin" "ui/vote_started.wav" 53 | } 54 | "vote end" 55 | { 56 | "sound" "mapchooser/tf2/vote_success.mp3" 57 | "event" "Vote.Passed" 58 | "builtin" "ui/vote_success.wav" 59 | } 60 | "vote warning" 61 | { 62 | "sound" "mapchooser/tf2/announcer_dec_missionbegins60s03.mp3" 63 | "builtin" "vo/announcer_dec_missionbegins60s03.mp3" 64 | } 65 | "runoff warning" 66 | { 67 | "sound" "mapchooser/tf2/vote_failure.mp3" 68 | "event" "Vote.Failed" 69 | "builtin" "ui/vote_failure.wav" 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/mapchooser_extended.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * MapChooser Extended 5 | * Creates a map vote at appropriate times, setting sm_nextmap to the winning 6 | * vote 7 | * 8 | * MapChooser Extended (C)2011-2013 Powerlord (Ross Bemrose) 9 | * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. 10 | * ============================================================================= 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, version 3.0, as published by the 14 | * Free Software Foundation. 15 | * 16 | * This program 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 the GNU General Public License for more 19 | * details. 20 | * 21 | * You should have received a copy of the GNU General Public License along with 22 | * this program. If not, see . 23 | * 24 | * As a special exception, AlliedModders LLC gives you permission to link the 25 | * code of this program (as well as its derivative works) to "Half-Life 2," the 26 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 27 | * by the Valve Corporation. You must obey the GNU General Public License in 28 | * all respects for all other code used. Additionally, AlliedModders LLC grants 29 | * this exception to all derivative works. AlliedModders LLC defines further 30 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 31 | * or . 32 | * 33 | * Version: $Id$ 34 | */ 35 | 36 | #if defined _mapchooser_extended_included_ 37 | #endinput 38 | #endif 39 | #define _mapchooser_extended_included_ 40 | #include 41 | 42 | // MCE 1.9 series 43 | 44 | enum CanNominateResult 45 | { 46 | CanNominate_No_VoteFull, /** No, nominations list is full */ 47 | CanNominate_No_VoteInProgress, /** No, map vote is in progress */ 48 | CanNominate_No_VoteComplete, /** No, map vote is completed */ 49 | CanNominate_Yes, /** Yes, you can nominate */ 50 | }; 51 | 52 | 53 | /** 54 | * Called whenever warning timer starts 55 | * 56 | */ 57 | forward OnMapVoteWarningStart(); 58 | 59 | /** 60 | * Called whenever runoff warning timer starts 61 | */ 62 | forward OnMapVoteRunnoffWarningStart(); 63 | 64 | /** 65 | * Called whenever the timer ticks 66 | */ 67 | forward OnMapVoteWarningTick(time); 68 | 69 | /** 70 | * Called whenever vote starts 71 | * 72 | * @deprecated Will be removed in MapChooser 1.8. Use OnMapVoteStarted instead. 73 | */ 74 | forward OnMapVoteStart(); 75 | 76 | /** 77 | * Called whenever vote ends 78 | */ 79 | forward OnMapVoteEnd(const String:map[]); 80 | 81 | /** 82 | * Is a map on the current game's official list? 83 | * This should be treated as informative only. 84 | * 85 | * @param map Name of map to check 86 | * @return true if it's on the list of official maps for this game 87 | */ 88 | native bool:IsMapOfficial(const String:map[]); 89 | 90 | /** 91 | * Is nominate allowed? 92 | * 93 | * @return A CanNominateResult corresponding to whether a vote is allowed or not 94 | */ 95 | native CanNominateResult:CanNominate(); 96 | 97 | public SharedPlugin:__pl_mapchooser_extended = 98 | { 99 | name = "mapchooser", 100 | file = "mapchooser_extended.smx", 101 | #if defined REQUIRE_PLUGIN 102 | required = 1, 103 | #else 104 | required = 0, 105 | #endif 106 | }; 107 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/mapchooser_extended.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * MapChooser Extended 5 | * Creates a map vote at appropriate times, setting sm_nextmap to the winning 6 | * vote. Includes extra options not present in the SourceMod MapChooser 7 | * 8 | * MapChooser Extended (C)2011-2013 Powerlord (Ross Bemrose) 9 | * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. 10 | * ============================================================================= 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, version 3.0, as published by the 14 | * Free Software Foundation. 15 | * 16 | * This program 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 the GNU General Public License for more 19 | * details. 20 | * 21 | * You should have received a copy of the GNU General Public License along with 22 | * this program. If not, see . 23 | * 24 | * As a special exception, AlliedModders LLC gives you permission to link the 25 | * code of this program (as well as its derivative works) to "Half-Life 2," the 26 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 27 | * by the Valve Corporation. You must obey the GNU General Public License in 28 | * all respects for all other code used. Additionally, AlliedModders LLC grants 29 | * this exception to all derivative works. AlliedModders LLC defines further 30 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 31 | * or . 32 | * 33 | * Version: $Id$ 34 | */ 35 | 36 | //#define DEBUG 37 | 38 | #if defined DEBUG 39 | #define assert(%1) if (!(%1)) ThrowError("Debug Assertion Failed"); 40 | #define assert_msg(%1,%2) if (!(%1)) ThrowError(%2); 41 | #else 42 | #define assert(%1) 43 | #define assert_msg(%1,%2) 44 | #endif 45 | 46 | #pragma semicolon 1 47 | #include 48 | #include 49 | #include "include/mapchooser_extended" 50 | #include 51 | #include 52 | #include 53 | 54 | #undef REQUIRE_PLUGIN 55 | #include 56 | 57 | #define MCE_VERSION "1.10.2" 58 | 59 | #define NV "nativevotes" 60 | 61 | enum RoundCounting 62 | { 63 | RoundCounting_Standard = 0, 64 | RoundCounting_MvM, 65 | RoundCounting_ArmsRace, 66 | } 67 | 68 | // CSGO requires two cvars to get the game type 69 | enum 70 | { 71 | GameType_Classic = 0, 72 | GameType_GunGame = 1, 73 | GameType_Training = 2, 74 | GameType_Custom = 3, 75 | } 76 | 77 | enum 78 | { 79 | GunGameMode_ArmsRace = 0, 80 | GunGameMode_Demolition = 1, 81 | GunGameMode_DeathMatch = 2, 82 | } 83 | 84 | public Plugin:myinfo = 85 | { 86 | name = "MapChooser Extended", 87 | author = "Powerlord, Zuko, and AlliedModders LLC", 88 | description = "Automated Map Voting with Extensions", 89 | version = MCE_VERSION, 90 | url = "https://forums.alliedmods.net/showthread.php?t=156974" 91 | }; 92 | 93 | /* Valve ConVars */ 94 | new Handle:g_Cvar_Winlimit = INVALID_HANDLE; 95 | new Handle:g_Cvar_Maxrounds = INVALID_HANDLE; 96 | new Handle:g_Cvar_Fraglimit = INVALID_HANDLE; 97 | new Handle:g_Cvar_Bonusroundtime = INVALID_HANDLE; 98 | new Handle:g_Cvar_MatchClinch = INVALID_HANDLE; 99 | new Handle:g_Cvar_VoteNextLevel = INVALID_HANDLE; 100 | new Handle:g_Cvar_GameType = INVALID_HANDLE; 101 | new Handle:g_Cvar_GameMode = INVALID_HANDLE; 102 | 103 | /* Plugin ConVars */ 104 | new Handle:g_Cvar_StartTime = INVALID_HANDLE; 105 | new Handle:g_Cvar_StartRounds = INVALID_HANDLE; 106 | new Handle:g_Cvar_StartFrags = INVALID_HANDLE; 107 | new Handle:g_Cvar_ExtendTimeStep = INVALID_HANDLE; 108 | new Handle:g_Cvar_ExtendRoundStep = INVALID_HANDLE; 109 | new Handle:g_Cvar_ExtendFragStep = INVALID_HANDLE; 110 | new Handle:g_Cvar_ExcludeMaps = INVALID_HANDLE; 111 | new Handle:g_Cvar_IncludeMaps = INVALID_HANDLE; 112 | new Handle:g_Cvar_NoVoteMode = INVALID_HANDLE; 113 | new Handle:g_Cvar_Extend = INVALID_HANDLE; 114 | new Handle:g_Cvar_DontChange = INVALID_HANDLE; 115 | new Handle:g_Cvar_EndOfMapVote = INVALID_HANDLE; 116 | new Handle:g_Cvar_VoteDuration = INVALID_HANDLE; 117 | 118 | new Handle:g_VoteTimer = INVALID_HANDLE; 119 | new Handle:g_RetryTimer = INVALID_HANDLE; 120 | new Handle:g_WarningTimer = INVALID_HANDLE; 121 | 122 | /* Data Handles */ 123 | new Handle:g_MapList = INVALID_HANDLE; 124 | new Handle:g_NominateList = INVALID_HANDLE; 125 | new Handle:g_NominateOwners = INVALID_HANDLE; 126 | new Handle:g_OldMapList = INVALID_HANDLE; 127 | new Handle:g_NextMapList = INVALID_HANDLE; 128 | new Handle:g_VoteMenu = INVALID_HANDLE; 129 | 130 | new g_Extends; 131 | new g_TotalRounds; 132 | new bool:g_HasVoteStarted; 133 | new bool:g_WaitingForVote; 134 | new bool:g_MapVoteCompleted; 135 | new bool:g_ChangeMapAtRoundEnd; 136 | new bool:g_ChangeMapInProgress; 137 | new bool:g_HasIntermissionStarted = false; 138 | new g_mapFileSerial = -1; 139 | 140 | new g_NominateCount = 0; 141 | new MapChange:g_ChangeTime; 142 | 143 | new Handle:g_NominationsResetForward = INVALID_HANDLE; 144 | new Handle:g_MapVoteStartedForward = INVALID_HANDLE; 145 | 146 | /* Mapchooser Extended Plugin ConVars */ 147 | 148 | new Handle:g_Cvar_RunOff = INVALID_HANDLE; 149 | new Handle:g_Cvar_RunOffPercent = INVALID_HANDLE; 150 | new Handle:g_Cvar_BlockSlots = INVALID_HANDLE; 151 | new Handle:g_Cvar_MaxRunOffs = INVALID_HANDLE; 152 | new Handle:g_Cvar_StartTimePercent = INVALID_HANDLE; 153 | new Handle:g_Cvar_StartTimePercentEnable = INVALID_HANDLE; 154 | new Handle:g_Cvar_WarningTime = INVALID_HANDLE; 155 | new Handle:g_Cvar_RunOffWarningTime = INVALID_HANDLE; 156 | new Handle:g_Cvar_MenuStyle = INVALID_HANDLE; 157 | new Handle:g_Cvar_TimerLocation = INVALID_HANDLE; 158 | new Handle:g_Cvar_ExtendPosition = INVALID_HANDLE; 159 | new Handle:g_Cvar_MarkCustomMaps = INVALID_HANDLE; 160 | new Handle:g_Cvar_RandomizeNominations = INVALID_HANDLE; 161 | new Handle:g_Cvar_HideTimer = INVALID_HANDLE; 162 | new Handle:g_Cvar_NoVoteOption = INVALID_HANDLE; 163 | 164 | /* Mapchooser Extended Data Handles */ 165 | new Handle:g_OfficialList = INVALID_HANDLE; 166 | 167 | /* Mapchooser Extended Forwards */ 168 | new Handle:g_MapVoteWarningStartForward = INVALID_HANDLE; 169 | new Handle:g_MapVoteWarningTickForward = INVALID_HANDLE; 170 | new Handle:g_MapVoteStartForward = INVALID_HANDLE; 171 | new Handle:g_MapVoteEndForward = INVALID_HANDLE; 172 | new Handle:g_MapVoteRunoffStartForward = INVALID_HANDLE; 173 | 174 | /* Mapchooser Extended Globals */ 175 | new g_RunoffCount = 0; 176 | new g_mapOfficialFileSerial = -1; 177 | new bool:g_NativeVotes = false; 178 | new String:g_GameModName[64]; 179 | new bool:g_WarningInProgress = false; 180 | new bool:g_AddNoVote = false; 181 | 182 | new RoundCounting:g_RoundCounting = RoundCounting_Standard; 183 | 184 | /* Upper bound of how many team there could be */ 185 | #define MAXTEAMS 10 186 | new g_winCount[MAXTEAMS]; 187 | 188 | new bool:g_BlockedSlots = false; 189 | new g_ObjectiveEnt = -1; 190 | 191 | enum TimerLocation 192 | { 193 | TimerLocation_Hint = 0, 194 | TimerLocation_Center = 1, 195 | TimerLocation_Chat = 2, 196 | } 197 | 198 | enum WarningType 199 | { 200 | WarningType_Vote, 201 | WarningType_Revote, 202 | } 203 | 204 | #define VOTE_EXTEND "##extend##" 205 | #define VOTE_DONTCHANGE "##dontchange##" 206 | 207 | /* Mapchooser Extended Defines */ 208 | #define LINE_ONE "##lineone##" 209 | #define LINE_TWO "##linetwo##" 210 | #define LINE_SPACER "##linespacer##" 211 | #define FAILURE_TIMER_LENGTH 5 212 | 213 | public OnPluginStart() 214 | { 215 | LoadTranslations("mapchooser_extended.phrases"); 216 | LoadTranslations("basevotes.phrases"); 217 | LoadTranslations("common.phrases"); 218 | 219 | new arraySize = ByteCountToCells(PLATFORM_MAX_PATH); 220 | g_MapList = CreateArray(arraySize); 221 | g_NominateList = CreateArray(arraySize); 222 | g_NominateOwners = CreateArray(1); 223 | g_OldMapList = CreateArray(arraySize); 224 | g_NextMapList = CreateArray(arraySize); 225 | g_OfficialList = CreateArray(arraySize); 226 | 227 | GetGameFolderName(g_GameModName, sizeof(g_GameModName)); 228 | 229 | g_Cvar_EndOfMapVote = CreateConVar("mce_endvote", "1", "Specifies if MapChooser should run an end of map vote", _, true, 0.0, true, 1.0); 230 | 231 | g_Cvar_StartTime = CreateConVar("mce_starttime", "10.0", "Specifies when to start the vote based on time remaining.", _, true, 1.0); 232 | g_Cvar_StartRounds = CreateConVar("mce_startround", "2.0", "Specifies when to start the vote based on rounds remaining. Use 0 on DoD:S, CS:S, and TF2 to start vote during bonus round time", _, true, 0.0); 233 | g_Cvar_StartFrags = CreateConVar("mce_startfrags", "5.0", "Specifies when to start the vote base on frags remaining.", _, true, 1.0); 234 | g_Cvar_ExtendTimeStep = CreateConVar("mce_extend_timestep", "15", "Specifies how much many more minutes each extension makes", _, true, 5.0); 235 | g_Cvar_ExtendRoundStep = CreateConVar("mce_extend_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 1.0); 236 | g_Cvar_ExtendFragStep = CreateConVar("mce_extend_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0); 237 | g_Cvar_ExcludeMaps = CreateConVar("mce_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0); 238 | g_Cvar_IncludeMaps = CreateConVar("mce_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0); 239 | g_Cvar_NoVoteMode = CreateConVar("mce_novote", "1", "Specifies whether or not MapChooser should pick a map if no votes are received.", _, true, 0.0, true, 1.0); 240 | g_Cvar_Extend = CreateConVar("mce_extend", "0", "Number of extensions allowed each map.", _, true, 0.0); 241 | g_Cvar_DontChange = CreateConVar("mce_dontchange", "1", "Specifies if a 'Don't Change' option should be added to early votes", _, true, 0.0); 242 | g_Cvar_VoteDuration = CreateConVar("mce_voteduration", "20", "Specifies how long the mapvote should be available for.", _, true, 5.0); 243 | 244 | // MapChooser Extended cvars 245 | CreateConVar("mce_version", MCE_VERSION, "MapChooser Extended Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD); 246 | 247 | g_Cvar_RunOff = CreateConVar("mce_runoff", "1", "Hold run off votes if winning choice has less than a certain percentage of votes", _, true, 0.0, true, 1.0); 248 | g_Cvar_RunOffPercent = CreateConVar("mce_runoffpercent", "50", "If winning choice has less than this percent of votes, hold a runoff", _, true, 0.0, true, 100.0); 249 | g_Cvar_BlockSlots = CreateConVar("mce_blockslots", "1", "Block slots to prevent accidental votes. Only applies when Voice Command style menus are in use.", _, true, 0.0, true, 1.0); 250 | //g_Cvar_BlockSlotsCount = CreateConVar("mce_blockslots_count", "2", "Number of slots to block.", _, true, 1.0, true, 3.0); 251 | g_Cvar_MaxRunOffs = CreateConVar("mce_maxrunoffs", "1", "Number of run off votes allowed each map.", _, true, 0.0); 252 | g_Cvar_StartTimePercent = CreateConVar("mce_start_percent", "35.0", "Specifies when to start the vote based on percents.", _, true, 0.0, true, 100.0); 253 | g_Cvar_StartTimePercentEnable = CreateConVar("mce_start_percent_enable", "0", "Enable or Disable percentage calculations when to start vote.", _, true, 0.0, true, 1.0); 254 | g_Cvar_WarningTime = CreateConVar("mce_warningtime", "15.0", "Warning time in seconds.", _, true, 0.0, true, 60.0); 255 | g_Cvar_RunOffWarningTime = CreateConVar("mce_runoffvotewarningtime", "5.0", "Warning time for runoff vote in seconds.", _, true, 0.0, true, 30.0); 256 | g_Cvar_MenuStyle = CreateConVar("mce_menustyle", "0", "Menu Style. 0 is the game's default, 1 is the older Valve style that requires you to press Escape to see the menu, 2 is the newer 1-9 button Voice Command style, unavailable in some games. Ignored on TF2 if NativeVotes Plugin is loaded.", _, true, 0.0, true, 2.0); 257 | g_Cvar_TimerLocation = CreateConVar("mce_warningtimerlocation", "0", "Location for the warning timer text. 0 is HintBox, 1 is Center text, 2 is Chat. Defaults to HintBox.", _, true, 0.0, true, 2.0); 258 | g_Cvar_MarkCustomMaps = CreateConVar("mce_markcustommaps", "1", "Mark custom maps in the vote list. 0 = Disabled, 1 = Mark with *, 2 = Mark with phrase.", _, true, 0.0, true, 2.0); 259 | g_Cvar_ExtendPosition = CreateConVar("mce_extendposition", "0", "Position of Extend/Don't Change options. 0 = at end, 1 = at start.", _, true, 0.0, true, 1.0); 260 | g_Cvar_RandomizeNominations = CreateConVar("mce_randomizeorder", "0", "Randomize map order?", _, true, 0.0, true, 1.0); 261 | g_Cvar_HideTimer = CreateConVar("mce_hidetimer", "0", "Hide the MapChooser Extended warning timer", _, true, 0.0, true, 1.0); 262 | g_Cvar_NoVoteOption = CreateConVar("mce_addnovote", "1", "Add \"No Vote\" to vote menu?", _, true, 0.0, true, 1.0); 263 | 264 | RegAdminCmd("sm_mapvote", Command_Mapvote, ADMFLAG_CHANGEMAP, "sm_mapvote - Forces MapChooser to attempt to run a map vote now."); 265 | RegAdminCmd("sm_setnextmap", Command_SetNextmap, ADMFLAG_CHANGEMAP, "sm_setnextmap "); 266 | 267 | // Mapchooser Extended Commands 268 | RegAdminCmd("mce_reload_maplist", Command_ReloadMaps, ADMFLAG_CHANGEMAP, "mce_reload_maplist - Reload the Official Maplist file."); 269 | 270 | g_Cvar_Winlimit = FindConVar("mp_winlimit"); 271 | g_Cvar_Maxrounds = FindConVar("mp_maxrounds"); 272 | g_Cvar_Fraglimit = FindConVar("mp_fraglimit"); 273 | 274 | new EngineVersion:version = GetEngineVersionCompat(); 275 | 276 | decl String:mapListPath[PLATFORM_MAX_PATH]; 277 | 278 | BuildPath(Path_SM, mapListPath, PLATFORM_MAX_PATH, "configs/mapchooser_extended/maps/%s.txt", g_GameModName); 279 | SetMapListCompatBind("official", mapListPath); 280 | 281 | switch (version) 282 | { 283 | case Engine_TF2: 284 | { 285 | g_Cvar_VoteNextLevel = FindConVar("sv_vote_issue_nextlevel_allowed"); 286 | g_Cvar_Bonusroundtime = FindConVar("mp_bonusroundtime"); 287 | } 288 | 289 | case Engine_CSGO: 290 | { 291 | g_Cvar_VoteNextLevel = FindConVar("mp_endmatch_votenextmap"); 292 | g_Cvar_GameType = FindConVar("game_type"); 293 | g_Cvar_GameMode = FindConVar("game_mode"); 294 | g_Cvar_Bonusroundtime = FindConVar("mp_round_restart_delay"); 295 | } 296 | 297 | case Engine_DODS: 298 | { 299 | g_Cvar_Bonusroundtime = FindConVar("dod_bonusroundtime"); 300 | } 301 | 302 | case Engine_CSS: 303 | { 304 | g_Cvar_Bonusroundtime = FindConVar("mp_round_restart_delay"); 305 | } 306 | 307 | default: 308 | { 309 | g_Cvar_Bonusroundtime = FindConVar("mp_bonusroundtime"); 310 | } 311 | } 312 | 313 | if (g_Cvar_Winlimit != INVALID_HANDLE || g_Cvar_Maxrounds != INVALID_HANDLE) 314 | { 315 | switch (version) 316 | { 317 | case Engine_TF2: 318 | { 319 | HookEvent("teamplay_win_panel", Event_TeamPlayWinPanel); 320 | HookEvent("teamplay_restart_round", Event_TFRestartRound); 321 | HookEvent("arena_win_panel", Event_TeamPlayWinPanel); 322 | HookEvent("pve_win_panel", Event_MvMWinPanel); 323 | } 324 | 325 | case Engine_NuclearDawn: 326 | { 327 | HookEvent("round_win", Event_RoundEnd); 328 | } 329 | 330 | case Engine_CSGO: 331 | { 332 | HookEvent("round_end", Event_RoundEnd); 333 | HookEvent("cs_intermission", Event_Intermission); 334 | HookEvent("announce_phase_end", Event_PhaseEnd); 335 | g_Cvar_MatchClinch = FindConVar("mp_match_can_clinch"); 336 | } 337 | 338 | case Engine_DODS: 339 | { 340 | HookEvent("dod_round_win", Event_RoundEnd); 341 | } 342 | 343 | default: 344 | { 345 | HookEvent("round_end", Event_RoundEnd); 346 | } 347 | } 348 | } 349 | 350 | if (g_Cvar_Fraglimit != INVALID_HANDLE) 351 | { 352 | HookEvent("player_death", Event_PlayerDeath); 353 | } 354 | 355 | AutoExecConfig(true, "mapchooser_extended"); 356 | 357 | //Change the mp_bonusroundtime max so that we have time to display the vote 358 | //If you display a vote during bonus time good defaults are 17 vote duration and 19 mp_bonustime 359 | if (g_Cvar_Bonusroundtime != INVALID_HANDLE) 360 | { 361 | SetConVarBounds(g_Cvar_Bonusroundtime, ConVarBound_Upper, true, 30.0); 362 | } 363 | 364 | g_NominationsResetForward = CreateGlobalForward("OnNominationRemoved", ET_Ignore, Param_String, Param_Cell); 365 | g_MapVoteStartedForward = CreateGlobalForward("OnMapVoteStarted", ET_Ignore); 366 | 367 | //MapChooser Extended Forwards 368 | g_MapVoteStartForward = CreateGlobalForward("OnMapVoteStart", ET_Ignore); // Deprecated 369 | g_MapVoteEndForward = CreateGlobalForward("OnMapVoteEnd", ET_Ignore, Param_String); 370 | g_MapVoteWarningStartForward = CreateGlobalForward("OnMapVoteWarningStart", ET_Ignore); 371 | g_MapVoteWarningTickForward = CreateGlobalForward("OnMapVoteWarningTick", ET_Ignore, Param_Cell); 372 | g_MapVoteRunoffStartForward = CreateGlobalForward("OnMapVoteRunnoffWarningStart", ET_Ignore); 373 | 374 | } 375 | 376 | public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) 377 | { 378 | if (LibraryExists("mapchooser")) 379 | { 380 | strcopy(error, err_max, "MapChooser already loaded, aborting."); 381 | return APLRes_Failure; 382 | } 383 | 384 | RegPluginLibrary("mapchooser"); 385 | 386 | MarkNativeAsOptional("GetEngineVersion"); 387 | 388 | CreateNative("NominateMap", Native_NominateMap); 389 | CreateNative("RemoveNominationByMap", Native_RemoveNominationByMap); 390 | CreateNative("RemoveNominationByOwner", Native_RemoveNominationByOwner); 391 | CreateNative("InitiateMapChooserVote", Native_InitiateVote); 392 | CreateNative("CanMapChooserStartVote", Native_CanVoteStart); 393 | CreateNative("HasEndOfMapVoteFinished", Native_CheckVoteDone); 394 | CreateNative("GetExcludeMapList", Native_GetExcludeMapList); 395 | CreateNative("GetNominatedMapList", Native_GetNominatedMapList); 396 | CreateNative("EndOfMapVoteEnabled", Native_EndOfMapVoteEnabled); 397 | 398 | // MapChooser Extended natives 399 | CreateNative("IsMapOfficial", Native_IsMapOfficial); 400 | CreateNative("CanNominate", Native_CanNominate); 401 | 402 | return APLRes_Success; 403 | } 404 | 405 | public OnAllPluginsLoaded() 406 | { 407 | g_NativeVotes = LibraryExists(NV) && NativeVotes_IsVoteTypeSupported(NativeVotesType_NextLevelMult); 408 | } 409 | 410 | public OnLibraryAdded(const String:name[]) 411 | { 412 | if (StrEqual(name, NV) && NativeVotes_IsVoteTypeSupported(NativeVotesType_NextLevelMult)) 413 | { 414 | g_NativeVotes = true; 415 | } 416 | } 417 | 418 | public OnLibraryRemoved(const String:name[]) 419 | { 420 | if (StrEqual(name, NV)) 421 | { 422 | g_NativeVotes = false; 423 | } 424 | } 425 | 426 | public OnMapStart() 427 | { 428 | decl String:folder[64]; 429 | GetGameFolderName(folder, sizeof(folder)); 430 | 431 | g_RoundCounting = RoundCounting_Standard; 432 | g_ObjectiveEnt = -1; 433 | 434 | if (strcmp(folder, "tf") == 0 && GameRules_GetProp("m_bPlayingMannVsMachine")) 435 | { 436 | g_RoundCounting = RoundCounting_MvM; 437 | g_ObjectiveEnt = EntIndexToEntRef(FindEntityByClassname(-1, "tf_objective_resource")); 438 | } 439 | else if (strcmp(folder, "csgo") == 0 && GetConVarInt(g_Cvar_GameType) == GameType_GunGame && 440 | GetConVarInt(g_Cvar_GameMode) == GunGameMode_ArmsRace) 441 | { 442 | g_RoundCounting = RoundCounting_ArmsRace; 443 | } 444 | } 445 | 446 | public OnConfigsExecuted() 447 | { 448 | if (ReadMapList(g_MapList, 449 | g_mapFileSerial, 450 | "mapchooser", 451 | MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_MAPSFOLDER) 452 | != INVALID_HANDLE) 453 | 454 | { 455 | if (g_mapFileSerial == -1) 456 | { 457 | LogError("Unable to create a valid map list."); 458 | } 459 | } 460 | 461 | // Disable the next level vote in TF2 and CS:GO 462 | // In TF2, this has two effects: 1. Stop the next level vote (which overlaps rtv functionality). 463 | // 2. Stop the built-in end level vote. This is the only thing that happens in CS:GO 464 | if (g_Cvar_VoteNextLevel != INVALID_HANDLE) 465 | { 466 | SetConVarBool(g_Cvar_VoteNextLevel, false); 467 | } 468 | 469 | CreateNextVote(); 470 | SetupTimeleftTimer(); 471 | 472 | g_TotalRounds = 0; 473 | 474 | g_Extends = 0; 475 | 476 | g_MapVoteCompleted = false; 477 | 478 | g_NominateCount = 0; 479 | ClearArray(g_NominateList); 480 | ClearArray(g_NominateOwners); 481 | 482 | for (new i=0; i GetConVarInt(g_Cvar_ExcludeMaps)) 517 | { 518 | RemoveFromArray(g_OldMapList, 0); 519 | } 520 | } 521 | 522 | public OnClientDisconnect(client) 523 | { 524 | new index = FindValueInArray(g_NominateOwners, client); 525 | 526 | if (index == -1) 527 | { 528 | return; 529 | } 530 | 531 | new String:oldmap[PLATFORM_MAX_PATH]; 532 | GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH); 533 | Call_StartForward(g_NominationsResetForward); 534 | Call_PushString(oldmap); 535 | Call_PushCell(GetArrayCell(g_NominateOwners, index)); 536 | Call_Finish(); 537 | 538 | RemoveFromArray(g_NominateOwners, index); 539 | RemoveFromArray(g_NominateList, index); 540 | g_NominateCount--; 541 | } 542 | 543 | public Action:Command_SetNextmap(client, args) 544 | { 545 | if (args < 1) 546 | { 547 | CReplyToCommand(client, "[MCE] Usage: sm_setnextmap "); 548 | return Plugin_Handled; 549 | } 550 | 551 | decl String:map[PLATFORM_MAX_PATH]; 552 | GetCmdArg(1, map, PLATFORM_MAX_PATH); 553 | 554 | if (!IsMapValid(map)) 555 | { 556 | CReplyToCommand(client, "[MCE] %t", "Map was not found", map); 557 | return Plugin_Handled; 558 | } 559 | 560 | ShowActivity(client, "%t", "Changed Next Map", map); 561 | LogAction(client, -1, "\"%L\" changed nextmap to \"%s\"", client, map); 562 | 563 | SetNextMap(map); 564 | g_MapVoteCompleted = true; 565 | 566 | return Plugin_Handled; 567 | } 568 | 569 | public Action:Command_ReloadMaps(client, args) 570 | { 571 | InitializeOfficialMapList(); 572 | } 573 | 574 | public OnMapTimeLeftChanged() 575 | { 576 | if (GetArraySize(g_MapList)) 577 | { 578 | SetupTimeleftTimer(); 579 | } 580 | } 581 | 582 | SetupTimeleftTimer() 583 | { 584 | new time; 585 | if (GetMapTimeLeft(time) && time > 0) 586 | { 587 | new startTime; 588 | if (GetConVarBool(g_Cvar_StartTimePercentEnable)) 589 | { 590 | new timeLimit; 591 | if (GetMapTimeLimit(timeLimit) && timeLimit > 0) 592 | { 593 | startTime = GetConVarInt(g_Cvar_StartTimePercent) * (timeLimit * 60) / 100; 594 | } 595 | } 596 | else 597 | { 598 | startTime = GetConVarInt(g_Cvar_StartTime) * 60; 599 | } 600 | 601 | if (time - startTime < 0 && GetConVarBool(g_Cvar_EndOfMapVote) && !g_MapVoteCompleted && !g_HasVoteStarted) 602 | { 603 | SetupWarningTimer(WarningType_Vote); 604 | } 605 | else 606 | { 607 | if (g_WarningTimer == INVALID_HANDLE) 608 | { 609 | if (g_VoteTimer != INVALID_HANDLE) 610 | { 611 | KillTimer(g_VoteTimer); 612 | g_VoteTimer = INVALID_HANDLE; 613 | } 614 | 615 | //g_VoteTimer = CreateTimer(float(time - startTime), Timer_StartMapVoteTimer_StartMapVote, _, TIMER_FLAG_NO_MAPCHANGE); 616 | g_VoteTimer = CreateTimer(float(time - startTime), Timer_StartWarningTimer, _, TIMER_FLAG_NO_MAPCHANGE); 617 | } 618 | } 619 | } 620 | } 621 | 622 | public Action:Timer_StartWarningTimer(Handle:timer) 623 | { 624 | g_VoteTimer = INVALID_HANDLE; 625 | 626 | if (!g_WarningInProgress || g_WarningTimer == INVALID_HANDLE) 627 | { 628 | SetupWarningTimer(WarningType_Vote); 629 | } 630 | } 631 | 632 | public Action:Timer_StartMapVote(Handle:timer, Handle:data) 633 | { 634 | static timePassed; 635 | 636 | // This is still necessary because InitiateVote still calls this directly via the retry timer 637 | if (!GetArraySize(g_MapList) || !GetConVarBool(g_Cvar_EndOfMapVote) || g_MapVoteCompleted || g_HasVoteStarted) 638 | { 639 | g_WarningTimer = INVALID_HANDLE; 640 | return Plugin_Stop; 641 | } 642 | 643 | ResetPack(data); 644 | new warningMaxTime = ReadPackCell(data); 645 | new warningTimeRemaining = warningMaxTime - timePassed; 646 | 647 | new String:warningPhrase[32]; 648 | ReadPackString(data, warningPhrase, sizeof(warningPhrase)); 649 | 650 | // Tick timer for external plugins 651 | Call_StartForward(g_MapVoteWarningTickForward); 652 | Call_PushCell(warningTimeRemaining); 653 | Call_Finish(); 654 | 655 | if (timePassed == 0 || !GetConVarBool(g_Cvar_HideTimer)) 656 | { 657 | new TimerLocation:timerLocation = TimerLocation:GetConVarInt(g_Cvar_TimerLocation); 658 | 659 | switch(timerLocation) 660 | { 661 | case TimerLocation_Center: 662 | { 663 | PrintCenterTextAll("%t", warningPhrase, warningTimeRemaining); 664 | } 665 | 666 | case TimerLocation_Chat: 667 | { 668 | PrintToChatAll("%t", warningPhrase, warningTimeRemaining); 669 | } 670 | 671 | default: 672 | { 673 | PrintHintTextToAll("%t", warningPhrase, warningTimeRemaining); 674 | } 675 | } 676 | } 677 | 678 | if (timePassed++ >= warningMaxTime) 679 | { 680 | if (timer == g_RetryTimer) 681 | { 682 | g_WaitingForVote = false; 683 | g_RetryTimer = INVALID_HANDLE; 684 | } 685 | else 686 | { 687 | g_WarningTimer = INVALID_HANDLE; 688 | } 689 | 690 | timePassed = 0; 691 | new MapChange:mapChange = MapChange:ReadPackCell(data); 692 | new Handle:hndl = Handle:ReadPackCell(data); 693 | 694 | InitiateVote(mapChange, hndl); 695 | 696 | return Plugin_Stop; 697 | } 698 | return Plugin_Continue; 699 | } 700 | 701 | public Event_TFRestartRound(Handle:event, const String:name[], bool:dontBroadcast) 702 | { 703 | /* Game got restarted - reset our round count tracking */ 704 | g_TotalRounds = 0; 705 | } 706 | 707 | public Event_TeamPlayWinPanel(Handle:event, const String:name[], bool:dontBroadcast) 708 | { 709 | if (g_ChangeMapAtRoundEnd) 710 | { 711 | g_ChangeMapAtRoundEnd = false; 712 | CreateTimer(2.0, Timer_ChangeMap, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE); 713 | g_ChangeMapInProgress = true; 714 | } 715 | 716 | new bluescore = GetEventInt(event, "blue_score"); 717 | new redscore = GetEventInt(event, "red_score"); 718 | 719 | if(GetEventInt(event, "round_complete") == 1 || StrEqual(name, "arena_win_panel")) 720 | { 721 | g_TotalRounds++; 722 | 723 | if (!GetArraySize(g_MapList) || g_HasVoteStarted || g_MapVoteCompleted || !GetConVarBool(g_Cvar_EndOfMapVote)) 724 | { 725 | return; 726 | } 727 | 728 | CheckMaxRounds(g_TotalRounds); 729 | 730 | switch(GetEventInt(event, "winning_team")) 731 | { 732 | case 3: 733 | { 734 | CheckWinLimit(bluescore); 735 | } 736 | case 2: 737 | { 738 | CheckWinLimit(redscore); 739 | } 740 | //We need to do nothing on winning_team == 0 this indicates stalemate. 741 | default: 742 | { 743 | return; 744 | } 745 | } 746 | } 747 | } 748 | 749 | public Event_MvMWinPanel(Handle:event, const String:name[], bool:dontBroadcast) 750 | { 751 | if (GetEventInt(event, "winning_team") == 2) 752 | { 753 | new objectiveEnt = EntRefToEntIndex(g_ObjectiveEnt); 754 | if (objectiveEnt != INVALID_ENT_REFERENCE) 755 | { 756 | g_TotalRounds = GetEntProp(g_ObjectiveEnt, Prop_Send, "m_nMannVsMachineWaveCount"); 757 | CheckMaxRounds(g_TotalRounds); 758 | } 759 | } 760 | } 761 | 762 | public Event_Intermission(Handle:event, const String:name[], bool:dontBroadcast) 763 | { 764 | g_HasIntermissionStarted = true; 765 | } 766 | 767 | public Event_PhaseEnd(Handle:event, const String:name[], bool:dontBroadcast) 768 | { 769 | /* announce_phase_end fires for both half time and the end of the map, but intermission fires first for end of the map. */ 770 | if (g_HasIntermissionStarted) 771 | { 772 | return; 773 | } 774 | 775 | /* No intermission yet, so this must be half time. Swap the score counters. */ 776 | new t_score = g_winCount[2]; 777 | g_winCount[2] = g_winCount[3]; 778 | g_winCount[3] = t_score; 779 | } 780 | 781 | public Event_WeaponRank(Handle:event, const String:name[], bool:dontBroadcast) 782 | { 783 | new rank = GetEventInt(event, "weaponrank"); 784 | if (rank > g_TotalRounds) 785 | { 786 | g_TotalRounds = rank; 787 | CheckMaxRounds(g_TotalRounds); 788 | } 789 | } 790 | 791 | /* You ask, why don't you just use team_score event? And I answer... Because CSS doesn't. */ 792 | public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast) 793 | { 794 | if (g_RoundCounting == RoundCounting_ArmsRace) 795 | { 796 | return; 797 | } 798 | 799 | if (g_ChangeMapAtRoundEnd) 800 | { 801 | g_ChangeMapAtRoundEnd = false; 802 | CreateTimer(2.0, Timer_ChangeMap, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE); 803 | g_ChangeMapInProgress = true; 804 | } 805 | 806 | new winner; 807 | if (strcmp(name, "round_win") == 0 || strcmp(name, "dod_round_win") == 0) 808 | { 809 | // Nuclear Dawn & DoD:S 810 | winner = GetEventInt(event, "team"); 811 | } 812 | else 813 | { 814 | winner = GetEventInt(event, "winner"); 815 | } 816 | 817 | if (winner == 0 || winner == 1 || !GetConVarBool(g_Cvar_EndOfMapVote)) 818 | { 819 | return; 820 | } 821 | 822 | if (winner >= MAXTEAMS) 823 | { 824 | SetFailState("Mod exceed maximum team count - Please file a bug report."); 825 | } 826 | 827 | g_TotalRounds++; 828 | 829 | g_winCount[winner]++; 830 | 831 | if (!GetArraySize(g_MapList) || g_HasVoteStarted || g_MapVoteCompleted) 832 | { 833 | return; 834 | } 835 | 836 | CheckWinLimit(g_winCount[winner]); 837 | CheckMaxRounds(g_TotalRounds); 838 | } 839 | 840 | public CheckWinLimit(winner_score) 841 | { 842 | if (g_Cvar_Winlimit != INVALID_HANDLE) 843 | { 844 | new winlimit = GetConVarInt(g_Cvar_Winlimit); 845 | if (winlimit) 846 | { 847 | if (winner_score >= (winlimit - GetConVarInt(g_Cvar_StartRounds))) 848 | { 849 | if (!g_WarningInProgress || g_WarningTimer == INVALID_HANDLE) 850 | { 851 | SetupWarningTimer(WarningType_Vote, MapChange_MapEnd); 852 | //InitiateVote(MapChange_MapEnd, INVALID_HANDLE); 853 | } 854 | } 855 | } 856 | } 857 | 858 | if (g_Cvar_MatchClinch != INVALID_HANDLE && g_Cvar_Maxrounds != INVALID_HANDLE) 859 | { 860 | new bool:clinch = GetConVarBool(g_Cvar_MatchClinch); 861 | 862 | if (clinch) 863 | { 864 | new maxrounds = GetConVarInt(g_Cvar_Maxrounds); 865 | new winlimit = RoundFloat(maxrounds / 2.0); 866 | 867 | if(winner_score == winlimit - 1) 868 | { 869 | if (!g_WarningInProgress || g_WarningTimer == INVALID_HANDLE) 870 | { 871 | SetupWarningTimer(WarningType_Vote, MapChange_MapEnd); 872 | //InitiateVote(MapChange_MapEnd, INVALID_HANDLE); 873 | } 874 | } 875 | } 876 | } 877 | } 878 | 879 | public CheckMaxRounds(roundcount) 880 | { 881 | new maxrounds = 0; 882 | 883 | if (g_RoundCounting == RoundCounting_ArmsRace) 884 | { 885 | maxrounds = GameRules_GetProp("m_iNumGunGameProgressiveWeaponsCT"); 886 | } 887 | else if (g_RoundCounting == RoundCounting_MvM) 888 | { 889 | maxrounds = GetEntProp(g_ObjectiveEnt, Prop_Send, "m_nMannVsMachineMaxWaveCount"); 890 | } 891 | else if (g_Cvar_Maxrounds != INVALID_HANDLE) 892 | { 893 | maxrounds = GetConVarInt(g_Cvar_Maxrounds); 894 | } 895 | else 896 | { 897 | return; 898 | } 899 | 900 | if (maxrounds) 901 | { 902 | if (roundcount >= (maxrounds - GetConVarInt(g_Cvar_StartRounds))) 903 | { 904 | if (!g_WarningInProgress || g_WarningTimer == INVALID_HANDLE) 905 | { 906 | SetupWarningTimer(WarningType_Vote, MapChange_MapEnd); 907 | //InitiateVote(MapChange_MapEnd, INVALID_HANDLE); 908 | } 909 | } 910 | } 911 | } 912 | 913 | public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) 914 | { 915 | if (!GetArraySize(g_MapList) || g_Cvar_Fraglimit == INVALID_HANDLE || g_HasVoteStarted) 916 | { 917 | return; 918 | } 919 | 920 | if (!GetConVarInt(g_Cvar_Fraglimit) || !GetConVarBool(g_Cvar_EndOfMapVote)) 921 | { 922 | return; 923 | } 924 | 925 | if (g_MapVoteCompleted) 926 | { 927 | return; 928 | } 929 | 930 | new fragger = GetClientOfUserId(GetEventInt(event, "attacker")); 931 | 932 | if (!fragger) 933 | { 934 | return; 935 | } 936 | 937 | if (GetClientFrags(fragger) >= (GetConVarInt(g_Cvar_Fraglimit) - GetConVarInt(g_Cvar_StartFrags))) 938 | { 939 | if (!g_WarningInProgress || g_WarningTimer == INVALID_HANDLE) 940 | { 941 | SetupWarningTimer(WarningType_Vote, MapChange_MapEnd); 942 | //InitiateVote(MapChange_MapEnd, INVALID_HANDLE); 943 | } 944 | } 945 | } 946 | 947 | public Action:Command_Mapvote(client, args) 948 | { 949 | ShowActivity2(client, "[MCE] ", "%t", "Initiated Vote Map"); 950 | 951 | SetupWarningTimer(WarningType_Vote, MapChange_MapEnd, INVALID_HANDLE, true); 952 | 953 | //InitiateVote(MapChange_MapEnd, INVALID_HANDLE); 954 | 955 | return Plugin_Handled; 956 | } 957 | 958 | /** 959 | * Starts a new map vote 960 | * 961 | * @param when When the resulting map change should occur. 962 | * @param inputlist Optional list of maps to use for the vote, otherwise an internal list of nominations + random maps will be used. 963 | */ 964 | InitiateVote(MapChange:when, Handle:inputlist=INVALID_HANDLE) 965 | { 966 | g_WaitingForVote = true; 967 | g_WarningInProgress = false; 968 | 969 | // Check if a nativevotes vots is in progress first 970 | // NativeVotes running at the same time as a regular vote can cause hintbox problems, 971 | // so always check for a standard vote 972 | if (IsVoteInProgress() || (g_NativeVotes && NativeVotes_IsVoteInProgress())) 973 | { 974 | // Can't start a vote, try again in 5 seconds. 975 | //g_RetryTimer = CreateTimer(5.0, Timer_StartMapVote, _, TIMER_FLAG_NO_MAPCHANGE); 976 | 977 | CPrintToChatAll("[MCE] %t", "Cannot Start Vote", FAILURE_TIMER_LENGTH); 978 | new Handle:data; 979 | g_RetryTimer = CreateDataTimer(1.0, Timer_StartMapVote, data, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); 980 | 981 | /* Mapchooser Extended */ 982 | WritePackCell(data, FAILURE_TIMER_LENGTH); 983 | 984 | if (GetConVarBool(g_Cvar_RunOff) && g_RunoffCount > 0) 985 | { 986 | WritePackString(data, "Revote Warning"); 987 | } else { 988 | WritePackString(data, "Vote Warning"); 989 | } 990 | /* End Mapchooser Extended */ 991 | 992 | WritePackCell(data, _:when); 993 | WritePackCell(data, _:inputlist); 994 | ResetPack(data); 995 | return; 996 | } 997 | 998 | /* If the main map vote has completed (and chosen result) and its currently changing (not a delayed change) we block further attempts */ 999 | if (g_MapVoteCompleted && g_ChangeMapInProgress) 1000 | { 1001 | return; 1002 | } 1003 | 1004 | g_ChangeTime = when; 1005 | 1006 | g_WaitingForVote = false; 1007 | 1008 | g_HasVoteStarted = true; 1009 | 1010 | if (g_NativeVotes) 1011 | { 1012 | g_VoteMenu = NativeVotes_Create(Handler_MapVoteMenu, NativeVotesType_NextLevelMult, MenuAction_End | MenuAction_VoteCancel | MenuAction_Display | MenuAction_DisplayItem); 1013 | NativeVotes_SetResultCallback(g_VoteMenu, Handler_NativeVoteFinished); 1014 | } 1015 | else 1016 | { 1017 | new Handle:menuStyle = GetMenuStyleHandle(MenuStyle:GetConVarInt(g_Cvar_MenuStyle)); 1018 | 1019 | if (menuStyle != INVALID_HANDLE) 1020 | { 1021 | g_VoteMenu = CreateMenuEx(menuStyle, Handler_MapVoteMenu, MenuAction_End | MenuAction_Display | MenuAction_DisplayItem | MenuAction_VoteCancel); 1022 | } 1023 | else 1024 | { 1025 | // You chose... poorly 1026 | g_VoteMenu = CreateMenu(Handler_MapVoteMenu, MenuAction_End | MenuAction_Display | MenuAction_DisplayItem | MenuAction_VoteCancel); 1027 | } 1028 | 1029 | g_AddNoVote = GetConVarBool(g_Cvar_NoVoteOption); 1030 | 1031 | // Block Vote Slots 1032 | if (GetConVarBool(g_Cvar_BlockSlots)) 1033 | { 1034 | new Handle:radioStyle = GetMenuStyleHandle(MenuStyle_Radio); 1035 | 1036 | if (GetMenuStyle(g_VoteMenu) == radioStyle) 1037 | { 1038 | g_BlockedSlots = true; 1039 | AddMenuItem(g_VoteMenu, LINE_ONE, "Choose something...", ITEMDRAW_DISABLED); 1040 | AddMenuItem(g_VoteMenu, LINE_TWO, "...will ya?", ITEMDRAW_DISABLED); 1041 | if (!g_AddNoVote) 1042 | { 1043 | AddMenuItem(g_VoteMenu, LINE_SPACER, "", ITEMDRAW_SPACER); 1044 | } 1045 | } else { 1046 | g_BlockedSlots = false; 1047 | } 1048 | } 1049 | 1050 | if (g_AddNoVote) 1051 | { 1052 | SetMenuOptionFlags(g_VoteMenu, MENUFLAG_BUTTON_NOVOTE); 1053 | } 1054 | 1055 | SetMenuTitle(g_VoteMenu, "Vote Nextmap"); 1056 | SetVoteResultCallback(g_VoteMenu, Handler_MapVoteFinished); 1057 | } 1058 | 1059 | /* Call OnMapVoteStarted() Forward */ 1060 | // Call_StartForward(g_MapVoteStartedForward); 1061 | // Call_Finish(); 1062 | 1063 | /** 1064 | * TODO: Make a proper decision on when to clear the nominations list. 1065 | * Currently it clears when used, and stays if an external list is provided. 1066 | * Is this the right thing to do? External lists will probably come from places 1067 | * like sm_mapvote from the adminmenu in the future. 1068 | */ 1069 | 1070 | decl String:map[PLATFORM_MAX_PATH]; 1071 | 1072 | /* No input given - User our internal nominations and maplist */ 1073 | if (inputlist == INVALID_HANDLE) 1074 | { 1075 | new Handle:randomizeList = INVALID_HANDLE; 1076 | if (GetConVarBool(g_Cvar_RandomizeNominations)) 1077 | { 1078 | randomizeList = CloneArray(g_NominateList); 1079 | } 1080 | 1081 | new nominateCount = GetArraySize(g_NominateList); 1082 | 1083 | new voteSize = GetVoteSize(); 1084 | 1085 | // The if and else if could be combined, but it looks extremely messy 1086 | // This is a hack to lower the vote menu size by 1 when Don't Change or Extend Map should appear 1087 | if (g_NativeVotes) 1088 | { 1089 | if ((when == MapChange_Instant || when == MapChange_RoundEnd) && GetConVarBool(g_Cvar_DontChange)) 1090 | { 1091 | voteSize--; 1092 | } 1093 | else if (GetConVarBool(g_Cvar_Extend) && g_Extends < GetConVarInt(g_Cvar_Extend)) 1094 | { 1095 | voteSize--; 1096 | } 1097 | } 1098 | 1099 | /* Smaller of the two - It should be impossible for nominations to exceed the size though (cvar changed mid-map?) */ 1100 | new nominationsToAdd = nominateCount >= voteSize ? voteSize : nominateCount; 1101 | 1102 | new bool:extendFirst = GetConVarBool(g_Cvar_ExtendPosition); 1103 | 1104 | if (extendFirst) 1105 | { 1106 | AddExtendToMenu(g_VoteMenu, when); 1107 | } 1108 | 1109 | for (new i=0; i= availableMaps) 1176 | { 1177 | //Run out of maps, this will have to do. 1178 | break; 1179 | } 1180 | } 1181 | 1182 | if (randomizeList != INVALID_HANDLE) 1183 | { 1184 | // Fisher-Yates Shuffle 1185 | for (new j = GetArraySize(randomizeList) - 1; j >= 1; j--) 1186 | { 1187 | new k = GetRandomInt(0, j); 1188 | SwapArrayItems(randomizeList, j, k); 1189 | } 1190 | 1191 | for (new j = 0; j < GetArraySize(randomizeList); j++) 1192 | { 1193 | GetArrayString(randomizeList, j, map, PLATFORM_MAX_PATH); 1194 | AddMapItem(map); 1195 | } 1196 | 1197 | CloseHandle(randomizeList); 1198 | randomizeList = INVALID_HANDLE; 1199 | } 1200 | 1201 | /* Wipe out our nominations list - Nominations have already been informed of this */ 1202 | g_NominateCount = 0; 1203 | ClearArray(g_NominateOwners); 1204 | ClearArray(g_NominateList); 1205 | 1206 | if (!extendFirst) 1207 | { 1208 | AddExtendToMenu(g_VoteMenu, when); 1209 | } 1210 | } 1211 | else //We were given a list of maps to start the vote with 1212 | { 1213 | new size = GetArraySize(inputlist); 1214 | 1215 | for (new i=0; i 0) 1319 | { 1320 | ExtendMapTimeLimit(GetConVarInt(g_Cvar_ExtendTimeStep)*60); 1321 | } 1322 | } 1323 | 1324 | if (g_Cvar_Winlimit != INVALID_HANDLE) 1325 | { 1326 | new winlimit = GetConVarInt(g_Cvar_Winlimit); 1327 | if (winlimit) 1328 | { 1329 | SetConVarInt(g_Cvar_Winlimit, winlimit + GetConVarInt(g_Cvar_ExtendRoundStep)); 1330 | } 1331 | } 1332 | 1333 | if (g_Cvar_Maxrounds != INVALID_HANDLE) 1334 | { 1335 | new maxrounds = GetConVarInt(g_Cvar_Maxrounds); 1336 | if (maxrounds) 1337 | { 1338 | SetConVarInt(g_Cvar_Maxrounds, maxrounds + GetConVarInt(g_Cvar_ExtendRoundStep)); 1339 | } 1340 | } 1341 | 1342 | if (g_Cvar_Fraglimit != INVALID_HANDLE) 1343 | { 1344 | new fraglimit = GetConVarInt(g_Cvar_Fraglimit); 1345 | if (fraglimit) 1346 | { 1347 | SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep)); 1348 | } 1349 | } 1350 | 1351 | if (g_NativeVotes) 1352 | { 1353 | NativeVotes_DisplayPassEx(menu, NativeVotesPass_Extend); 1354 | } 1355 | 1356 | CPrintToChatAll("[MCE] %t", "Current Map Extended", RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes); 1357 | LogAction(-1, -1, "Voting for next map has finished. The current map has been extended."); 1358 | 1359 | // We extended, so we'll have to vote again. 1360 | g_HasVoteStarted = false; 1361 | CreateNextVote(); 1362 | SetupTimeleftTimer(); 1363 | 1364 | } 1365 | else if (strcmp(map, VOTE_DONTCHANGE, false) == 0) 1366 | { 1367 | if (g_NativeVotes) 1368 | { 1369 | NativeVotes_DisplayPassEx(menu, NativeVotesPass_Extend); 1370 | } 1371 | 1372 | CPrintToChatAll("[MCE] %t", "Current Map Stays", RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes); 1373 | LogAction(-1, -1, "Voting for next map has finished. 'No Change' was the winner"); 1374 | 1375 | g_HasVoteStarted = false; 1376 | CreateNextVote(); 1377 | SetupTimeleftTimer(); 1378 | } 1379 | else 1380 | { 1381 | if (g_ChangeTime == MapChange_MapEnd) 1382 | { 1383 | SetNextMap(map); 1384 | if (g_NativeVotes) 1385 | { 1386 | NativeVotes_DisplayPass(menu, map); 1387 | } 1388 | } 1389 | else if (g_ChangeTime == MapChange_Instant) 1390 | { 1391 | new Handle:data; 1392 | CreateDataTimer(4.0, Timer_ChangeMap, data); 1393 | WritePackString(data, map); 1394 | g_ChangeMapInProgress = false; 1395 | if (g_NativeVotes) 1396 | { 1397 | NativeVotes_DisplayPassEx(menu, NativeVotesPass_ChgLevel, map); 1398 | } 1399 | } 1400 | else // MapChange_RoundEnd 1401 | { 1402 | SetNextMap(map); 1403 | g_ChangeMapAtRoundEnd = true; 1404 | 1405 | if (g_NativeVotes) 1406 | { 1407 | NativeVotes_DisplayPass(menu, map); 1408 | } 1409 | } 1410 | 1411 | g_HasVoteStarted = false; 1412 | g_MapVoteCompleted = true; 1413 | 1414 | CPrintToChatAll("[MCE] %t", "Nextmap Voting Finished", map, RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes); 1415 | LogAction(-1, -1, "Voting for next map has finished. Nextmap: %s.", map); 1416 | } 1417 | } 1418 | 1419 | public Handler_MapVoteFinished(Handle:menu, 1420 | num_votes, 1421 | num_clients, 1422 | const client_info[][2], 1423 | num_items, 1424 | const item_info[][2]) 1425 | { 1426 | // Implement revote logic - Only run this` block if revotes are enabled and this isn't the last revote 1427 | if (GetConVarBool(g_Cvar_RunOff) && num_items > 1 && g_RunoffCount < GetConVarInt(g_Cvar_MaxRunOffs)) 1428 | { 1429 | g_RunoffCount++; 1430 | new highest_votes = item_info[0][VOTEINFO_ITEM_VOTES]; 1431 | new required_percent = GetConVarInt(g_Cvar_RunOffPercent); 1432 | new required_votes = RoundToCeil(float(num_votes) * float(required_percent) / 100); 1433 | 1434 | if (highest_votes == item_info[1][VOTEINFO_ITEM_VOTES]) 1435 | { 1436 | g_HasVoteStarted = false; 1437 | 1438 | //Revote is needed 1439 | new arraySize = ByteCountToCells(PLATFORM_MAX_PATH); 1440 | new Handle:mapList = CreateArray(arraySize); 1441 | 1442 | for (new i = 0; i < num_items; i++) 1443 | { 1444 | if (item_info[i][VOTEINFO_ITEM_VOTES] == highest_votes) 1445 | { 1446 | decl String:map[PLATFORM_MAX_PATH]; 1447 | 1448 | GetMapItem(menu, item_info[i][VOTEINFO_ITEM_INDEX], map, PLATFORM_MAX_PATH); 1449 | PushArrayString(mapList, map); 1450 | } 1451 | else 1452 | { 1453 | break; 1454 | } 1455 | } 1456 | 1457 | if (g_NativeVotes) 1458 | { 1459 | NativeVotes_DisplayFail(menu, NativeVotesFail_NotEnoughVotes); 1460 | } 1461 | 1462 | CPrintToChatAll("[MCE] %t", "Tie Vote", GetArraySize(mapList)); 1463 | SetupWarningTimer(WarningType_Revote, MapChange:g_ChangeTime, mapList); 1464 | return; 1465 | } 1466 | else if (highest_votes < required_votes) 1467 | { 1468 | g_HasVoteStarted = false; 1469 | 1470 | //Revote is needed 1471 | new arraySize = ByteCountToCells(PLATFORM_MAX_PATH); 1472 | new Handle:mapList = CreateArray(arraySize); 1473 | 1474 | decl String:map1[PLATFORM_MAX_PATH]; 1475 | GetMapItem(menu, item_info[0][VOTEINFO_ITEM_INDEX], map1, PLATFORM_MAX_PATH); 1476 | 1477 | PushArrayString(mapList, map1); 1478 | 1479 | // We allow more than two maps for a revote if they are tied 1480 | for (new i = 1; i < num_items; i++) 1481 | { 1482 | if (GetArraySize(mapList) < 2 || item_info[i][VOTEINFO_ITEM_VOTES] == item_info[i - 1][VOTEINFO_ITEM_VOTES]) 1483 | { 1484 | decl String:map[PLATFORM_MAX_PATH]; 1485 | GetMapItem(menu, item_info[i][VOTEINFO_ITEM_INDEX], map, PLATFORM_MAX_PATH); 1486 | PushArrayString(mapList, map); 1487 | } 1488 | else 1489 | { 1490 | break; 1491 | } 1492 | } 1493 | 1494 | if (g_NativeVotes) 1495 | { 1496 | NativeVotes_DisplayFail(menu, NativeVotesFail_NotEnoughVotes); 1497 | } 1498 | 1499 | CPrintToChatAll("[MCE] %t", "Revote Is Needed", required_percent); 1500 | SetupWarningTimer(WarningType_Revote, MapChange:g_ChangeTime, mapList); 1501 | return; 1502 | } 1503 | } 1504 | 1505 | // No revote needed, continue as normal. 1506 | Handler_VoteFinishedGeneric(menu, num_votes, num_clients, client_info, num_items, item_info); 1507 | } 1508 | 1509 | // This is shared by NativeVotes now, but NV doesn't support Display or DisplayItem 1510 | public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2) 1511 | { 1512 | switch (action) 1513 | { 1514 | case MenuAction_End: 1515 | { 1516 | g_VoteMenu = INVALID_HANDLE; 1517 | if (g_NativeVotes) 1518 | { 1519 | NativeVotes_Close(menu); 1520 | } 1521 | else 1522 | { 1523 | CloseHandle(menu); 1524 | } 1525 | } 1526 | 1527 | case MenuAction_Display: 1528 | { 1529 | // NativeVotes uses the standard TF2/CSGO vote screen 1530 | if (!g_NativeVotes) 1531 | { 1532 | decl String:buffer[255]; 1533 | Format(buffer, sizeof(buffer), "%T", "Vote Nextmap", param1); 1534 | new Handle:panel = Handle:param2; 1535 | SetPanelTitle(panel, buffer); 1536 | } 1537 | } 1538 | 1539 | case MenuAction_DisplayItem: 1540 | { 1541 | new String:map[PLATFORM_MAX_PATH]; 1542 | new String:buffer[255]; 1543 | new mark = GetConVarInt(g_Cvar_MarkCustomMaps); 1544 | 1545 | if (g_NativeVotes) 1546 | { 1547 | NativeVotes_GetItem(menu, param2, map, PLATFORM_MAX_PATH); 1548 | } 1549 | else 1550 | { 1551 | GetMenuItem(menu, param2, map, PLATFORM_MAX_PATH); 1552 | } 1553 | 1554 | if (StrEqual(map, VOTE_EXTEND, false)) 1555 | { 1556 | Format(buffer, sizeof(buffer), "%T", "Extend Map", param1); 1557 | } 1558 | else if (StrEqual(map, VOTE_DONTCHANGE, false)) 1559 | { 1560 | Format(buffer, sizeof(buffer), "%T", "Dont Change", param1); 1561 | } 1562 | // Mapchooser Extended 1563 | else if (StrEqual(map, LINE_ONE, false)) 1564 | { 1565 | Format(buffer, sizeof(buffer),"%T", "Line One", param1); 1566 | } 1567 | else if (StrEqual(map, LINE_TWO, false)) 1568 | { 1569 | Format(buffer, sizeof(buffer),"%T", "Line Two", param1); 1570 | } 1571 | // Note that the first part is to discard the spacer line 1572 | else if (!StrEqual(map, LINE_SPACER, false)) 1573 | { 1574 | if (mark == 1 && !InternalIsMapOfficial(map)) 1575 | { 1576 | Format(buffer, sizeof(buffer), "%T", "Custom Marked", param1, map); 1577 | } 1578 | else if (mark == 2 && !InternalIsMapOfficial(map)) 1579 | { 1580 | Format(buffer, sizeof(buffer), "%T", "Custom", param1, map); 1581 | } 1582 | } 1583 | 1584 | if (buffer[0] != '\0') 1585 | { 1586 | if (g_NativeVotes) 1587 | { 1588 | NativeVotes_RedrawVoteItem(buffer); 1589 | return _:Plugin_Continue; 1590 | } 1591 | else 1592 | { 1593 | return RedrawMenuItem(buffer); 1594 | } 1595 | } 1596 | // End Mapchooser Extended 1597 | } 1598 | 1599 | case MenuAction_VoteCancel: 1600 | { 1601 | // If we receive 0 votes, pick at random. 1602 | if (param1 == VoteCancel_NoVotes && GetConVarBool(g_Cvar_NoVoteMode)) 1603 | { 1604 | new count; 1605 | if (g_NativeVotes) 1606 | { 1607 | count = NativeVotes_GetItemCount(menu); 1608 | } 1609 | else 1610 | { 1611 | count = GetMenuItemCount(menu); 1612 | } 1613 | 1614 | decl item; 1615 | decl String:map[PLATFORM_MAX_PATH]; 1616 | 1617 | do 1618 | { 1619 | new startInt = 0; 1620 | if (!g_NativeVotes && g_BlockedSlots) 1621 | { 1622 | if (g_AddNoVote) 1623 | { 1624 | startInt = 2; 1625 | } 1626 | else 1627 | { 1628 | startInt = 3; 1629 | } 1630 | } 1631 | item = GetRandomInt(startInt, count - 1); 1632 | if (g_NativeVotes) 1633 | { 1634 | NativeVotes_GetItem(menu, item, map, PLATFORM_MAX_PATH); 1635 | } 1636 | else 1637 | { 1638 | GetMenuItem(menu, item, map, PLATFORM_MAX_PATH); 1639 | } 1640 | } 1641 | while (strcmp(map, VOTE_EXTEND, false) == 0); 1642 | 1643 | SetNextMap(map); 1644 | g_MapVoteCompleted = true; 1645 | 1646 | if (g_NativeVotes) 1647 | { 1648 | NativeVotes_DisplayPass(menu, map); 1649 | } 1650 | } 1651 | else if (g_NativeVotes) 1652 | { 1653 | new NativeVotesFailType:reason = NativeVotesFail_Generic; 1654 | if (param1 == VoteCancel_NoVotes) 1655 | { 1656 | reason = NativeVotesFail_NotEnoughVotes; 1657 | } 1658 | 1659 | NativeVotes_DisplayFail(menu, reason); 1660 | } 1661 | else 1662 | { 1663 | // We were actually cancelled. I guess we do nothing. 1664 | } 1665 | 1666 | g_HasVoteStarted = false; 1667 | } 1668 | } 1669 | 1670 | return 0; 1671 | } 1672 | 1673 | public Action:Timer_ChangeMap(Handle:hTimer, Handle:dp) 1674 | { 1675 | g_ChangeMapInProgress = false; 1676 | 1677 | new String:map[PLATFORM_MAX_PATH]; 1678 | 1679 | if (dp == INVALID_HANDLE) 1680 | { 1681 | if (!GetNextMap(map, PLATFORM_MAX_PATH)) 1682 | { 1683 | //No passed map and no set nextmap. fail! 1684 | return Plugin_Stop; 1685 | } 1686 | } 1687 | else 1688 | { 1689 | ResetPack(dp); 1690 | ReadPackString(dp, map, PLATFORM_MAX_PATH); 1691 | } 1692 | 1693 | ForceChangeLevel(map, "Map Vote"); 1694 | 1695 | return Plugin_Stop; 1696 | } 1697 | 1698 | bool:RemoveStringFromArray(Handle:array, String:str[]) 1699 | { 1700 | new index = FindStringInArray(array, str); 1701 | if (index != -1) 1702 | { 1703 | RemoveFromArray(array, index); 1704 | return true; 1705 | } 1706 | 1707 | return false; 1708 | } 1709 | 1710 | CreateNextVote() 1711 | { 1712 | assert(g_NextMapList) 1713 | ClearArray(g_NextMapList); 1714 | 1715 | decl String:map[PLATFORM_MAX_PATH]; 1716 | new Handle:tempMaps = CloneArray(g_MapList); 1717 | 1718 | GetCurrentMap(map, PLATFORM_MAX_PATH); 1719 | RemoveStringFromArray(tempMaps, map); 1720 | 1721 | if (GetConVarInt(g_Cvar_ExcludeMaps) && GetArraySize(tempMaps) > GetConVarInt(g_Cvar_ExcludeMaps)) 1722 | { 1723 | for (new i = 0; i < GetArraySize(g_OldMapList); i++) 1724 | { 1725 | GetArrayString(g_OldMapList, i, map, PLATFORM_MAX_PATH); 1726 | RemoveStringFromArray(tempMaps, map); 1727 | } 1728 | } 1729 | 1730 | new voteSize = GetVoteSize(); 1731 | new limit = (voteSize < GetArraySize(tempMaps) ? voteSize : GetArraySize(tempMaps)); 1732 | 1733 | for (new i = 0; i < limit; i++) 1734 | { 1735 | new b = GetRandomInt(0, GetArraySize(tempMaps) - 1); 1736 | GetArrayString(tempMaps, b, map, PLATFORM_MAX_PATH); 1737 | PushArrayString(g_NextMapList, map); 1738 | RemoveFromArray(tempMaps, b); 1739 | } 1740 | 1741 | CloseHandle(tempMaps); 1742 | } 1743 | 1744 | bool:CanVoteStart() 1745 | { 1746 | if (g_WaitingForVote || g_HasVoteStarted) 1747 | { 1748 | return false; 1749 | } 1750 | 1751 | return true; 1752 | } 1753 | 1754 | NominateResult:InternalNominateMap(String:map[], bool:force, owner) 1755 | { 1756 | if (!IsMapValid(map)) 1757 | { 1758 | return Nominate_InvalidMap; 1759 | } 1760 | 1761 | /* Map already in the vote */ 1762 | if (FindStringInArray(g_NominateList, map) != -1) 1763 | { 1764 | return Nominate_AlreadyInVote; 1765 | } 1766 | 1767 | new index; 1768 | 1769 | /* Look to replace an existing nomination by this client - Nominations made with owner = 0 aren't replaced */ 1770 | if (owner && ((index = FindValueInArray(g_NominateOwners, owner)) != -1)) 1771 | { 1772 | new String:oldmap[PLATFORM_MAX_PATH]; 1773 | GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH); 1774 | Call_StartForward(g_NominationsResetForward); 1775 | Call_PushString(oldmap); 1776 | Call_PushCell(owner); 1777 | Call_Finish(); 1778 | 1779 | SetArrayString(g_NominateList, index, map); 1780 | return Nominate_Replaced; 1781 | } 1782 | 1783 | /* Too many nominated maps. */ 1784 | if (g_NominateCount >= GetVoteSize() && !force) 1785 | { 1786 | return Nominate_VoteFull; 1787 | } 1788 | 1789 | PushArrayString(g_NominateList, map); 1790 | PushArrayCell(g_NominateOwners, owner); 1791 | g_NominateCount++; 1792 | 1793 | while (GetArraySize(g_NominateList) > GetVoteSize()) 1794 | { 1795 | new String:oldmap[PLATFORM_MAX_PATH]; 1796 | GetArrayString(g_NominateList, 0, oldmap, PLATFORM_MAX_PATH); 1797 | Call_StartForward(g_NominationsResetForward); 1798 | Call_PushString(oldmap); 1799 | Call_PushCell(GetArrayCell(g_NominateOwners, 0)); 1800 | Call_Finish(); 1801 | 1802 | RemoveFromArray(g_NominateList, 0); 1803 | RemoveFromArray(g_NominateOwners, 0); 1804 | } 1805 | 1806 | return Nominate_Added; 1807 | } 1808 | 1809 | /* Add natives to allow nominate and initiate vote to be call */ 1810 | 1811 | /* native bool:NominateMap(const String:map[], bool:force, &NominateError:error); */ 1812 | public Native_NominateMap(Handle:plugin, numParams) 1813 | { 1814 | new len; 1815 | GetNativeStringLength(1, len); 1816 | 1817 | if (len <= 0) 1818 | { 1819 | return false; 1820 | } 1821 | 1822 | new String:map[len+1]; 1823 | GetNativeString(1, map, len+1); 1824 | 1825 | return _:InternalNominateMap(map, GetNativeCell(2), GetNativeCell(3)); 1826 | } 1827 | 1828 | bool:InternalRemoveNominationByMap(String:map[]) 1829 | { 1830 | for (new i = 0; i < GetArraySize(g_NominateList); i++) 1831 | { 1832 | new String:oldmap[PLATFORM_MAX_PATH]; 1833 | GetArrayString(g_NominateList, i, oldmap, PLATFORM_MAX_PATH); 1834 | 1835 | if(strcmp(map, oldmap, false) == 0) 1836 | { 1837 | Call_StartForward(g_NominationsResetForward); 1838 | Call_PushString(oldmap); 1839 | Call_PushCell(GetArrayCell(g_NominateOwners, i)); 1840 | Call_Finish(); 1841 | 1842 | RemoveFromArray(g_NominateList, i); 1843 | RemoveFromArray(g_NominateOwners, i); 1844 | g_NominateCount--; 1845 | 1846 | return true; 1847 | } 1848 | } 1849 | 1850 | return false; 1851 | } 1852 | 1853 | /* native bool:RemoveNominationByMap(const String:map[]); */ 1854 | public Native_RemoveNominationByMap(Handle:plugin, numParams) 1855 | { 1856 | new len; 1857 | GetNativeStringLength(1, len); 1858 | 1859 | if (len <= 0) 1860 | { 1861 | return false; 1862 | } 1863 | 1864 | new String:map[len+1]; 1865 | GetNativeString(1, map, len+1); 1866 | 1867 | return _:InternalRemoveNominationByMap(map); 1868 | } 1869 | 1870 | bool:InternalRemoveNominationByOwner(owner) 1871 | { 1872 | new index; 1873 | 1874 | if (owner && ((index = FindValueInArray(g_NominateOwners, owner)) != -1)) 1875 | { 1876 | new String:oldmap[PLATFORM_MAX_PATH]; 1877 | GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH); 1878 | 1879 | Call_StartForward(g_NominationsResetForward); 1880 | Call_PushString(oldmap); 1881 | Call_PushCell(owner); 1882 | Call_Finish(); 1883 | 1884 | RemoveFromArray(g_NominateList, index); 1885 | RemoveFromArray(g_NominateOwners, index); 1886 | g_NominateCount--; 1887 | 1888 | return true; 1889 | } 1890 | 1891 | return false; 1892 | } 1893 | 1894 | /* native bool:RemoveNominationByOwner(owner); */ 1895 | public Native_RemoveNominationByOwner(Handle:plugin, numParams) 1896 | { 1897 | return _:InternalRemoveNominationByOwner(GetNativeCell(1)); 1898 | } 1899 | 1900 | /* native InitiateMapChooserVote(); */ 1901 | public Native_InitiateVote(Handle:plugin, numParams) 1902 | { 1903 | new MapChange:when = MapChange:GetNativeCell(1); 1904 | new Handle:inputarray = Handle:GetNativeCell(2); 1905 | 1906 | LogAction(-1, -1, "Starting map vote because outside request"); 1907 | 1908 | SetupWarningTimer(WarningType_Vote, when, inputarray); 1909 | //InitiateVote(when, inputarray); 1910 | } 1911 | 1912 | public Native_CanVoteStart(Handle:plugin, numParams) 1913 | { 1914 | return CanVoteStart(); 1915 | } 1916 | 1917 | public Native_CheckVoteDone(Handle:plugin, numParams) 1918 | { 1919 | return g_MapVoteCompleted; 1920 | } 1921 | 1922 | public Native_EndOfMapVoteEnabled(Handle:plugin, numParams) 1923 | { 1924 | return GetConVarBool(g_Cvar_EndOfMapVote); 1925 | } 1926 | 1927 | public Native_GetExcludeMapList(Handle:plugin, numParams) 1928 | { 1929 | new Handle:array = Handle:GetNativeCell(1); 1930 | 1931 | if (array == INVALID_HANDLE) 1932 | { 1933 | return; 1934 | } 1935 | new size = GetArraySize(g_OldMapList); 1936 | decl String:map[PLATFORM_MAX_PATH]; 1937 | 1938 | for (new i=0; i -1); 2117 | } 2118 | 2119 | public Native_IsWarningTimer(Handle:plugin, numParams) 2120 | { 2121 | return g_WarningInProgress; 2122 | } 2123 | 2124 | public Native_CanNominate(Handle:plugin, numParams) 2125 | { 2126 | if (g_HasVoteStarted) 2127 | { 2128 | return _:CanNominate_No_VoteInProgress; 2129 | } 2130 | 2131 | if (g_MapVoteCompleted) 2132 | { 2133 | return _:CanNominate_No_VoteComplete; 2134 | } 2135 | 2136 | if (g_NominateCount >= GetVoteSize()) 2137 | { 2138 | return _:CanNominate_No_VoteFull; 2139 | } 2140 | 2141 | return _:CanNominate_Yes; 2142 | } 2143 | 2144 | 2145 | stock AddMapItem(const String:map[]) 2146 | { 2147 | if (g_NativeVotes) 2148 | { 2149 | NativeVotes_AddItem(g_VoteMenu, map, map); 2150 | } 2151 | else 2152 | { 2153 | AddMenuItem(g_VoteMenu, map, map); 2154 | } 2155 | } 2156 | 2157 | stock GetMapItem(Handle:menu, position, String:map[], mapLen) 2158 | { 2159 | if (g_NativeVotes) 2160 | { 2161 | NativeVotes_GetItem(menu, position, map, mapLen); 2162 | } 2163 | else 2164 | { 2165 | GetMenuItem(menu, position, map, mapLen); 2166 | } 2167 | } 2168 | 2169 | stock AddExtendToMenu(Handle:menu, MapChange:when) 2170 | { 2171 | /* Do we add any special items? */ 2172 | // Moved for Mapchooser Extended 2173 | 2174 | if ((when == MapChange_Instant || when == MapChange_RoundEnd) && GetConVarBool(g_Cvar_DontChange)) 2175 | { 2176 | if (g_NativeVotes) 2177 | { 2178 | // Built-in votes don't have "Don't Change", send Extend instead 2179 | NativeVotes_AddItem(menu, VOTE_DONTCHANGE, "Don't Change"); 2180 | } 2181 | else 2182 | { 2183 | AddMenuItem(menu, VOTE_DONTCHANGE, "Don't Change"); 2184 | } 2185 | } 2186 | else if (GetConVarBool(g_Cvar_Extend) && g_Extends < GetConVarInt(g_Cvar_Extend)) 2187 | { 2188 | if (g_NativeVotes) 2189 | { 2190 | NativeVotes_AddItem(menu, VOTE_EXTEND, "Extend Map"); 2191 | } 2192 | else 2193 | { 2194 | AddMenuItem(menu, VOTE_EXTEND, "Extend Map"); 2195 | } 2196 | } 2197 | } 2198 | 2199 | // Using this stock REQUIRES you to add the following to AskPluginLoad2: 2200 | // MarkNativeAsOptional("GetEngineVersion"); 2201 | stock EngineVersion:GetEngineVersionCompat() 2202 | { 2203 | new EngineVersion:version; 2204 | if (GetFeatureStatus(FeatureType_Native, "GetEngineVersion") != FeatureStatus_Available) 2205 | { 2206 | new sdkVersion = GuessSDKVersion(); 2207 | switch (sdkVersion) 2208 | { 2209 | case SOURCE_SDK_ORIGINAL: 2210 | { 2211 | version = Engine_Original; 2212 | } 2213 | 2214 | case SOURCE_SDK_DARKMESSIAH: 2215 | { 2216 | version = Engine_DarkMessiah; 2217 | } 2218 | 2219 | case SOURCE_SDK_EPISODE1: 2220 | { 2221 | version = Engine_SourceSDK2006; 2222 | } 2223 | 2224 | case SOURCE_SDK_EPISODE2: 2225 | { 2226 | version = Engine_SourceSDK2007; 2227 | } 2228 | 2229 | case SOURCE_SDK_BLOODYGOODTIME: 2230 | { 2231 | version = Engine_BloodyGoodTime; 2232 | } 2233 | 2234 | case SOURCE_SDK_EYE: 2235 | { 2236 | version = Engine_EYE; 2237 | } 2238 | 2239 | case SOURCE_SDK_CSS: 2240 | { 2241 | version = Engine_CSS; 2242 | } 2243 | 2244 | case SOURCE_SDK_EPISODE2VALVE: 2245 | { 2246 | decl String:gameFolder[PLATFORM_MAX_PATH]; 2247 | GetGameFolderName(gameFolder, PLATFORM_MAX_PATH); 2248 | if (StrEqual(gameFolder, "dod", false)) 2249 | { 2250 | version = Engine_DODS; 2251 | } 2252 | else if (StrEqual(gameFolder, "hl2mp", false)) 2253 | { 2254 | version = Engine_HL2DM; 2255 | } 2256 | else 2257 | { 2258 | version = Engine_TF2; 2259 | } 2260 | } 2261 | 2262 | case SOURCE_SDK_LEFT4DEAD: 2263 | { 2264 | version = Engine_Left4Dead; 2265 | } 2266 | 2267 | case SOURCE_SDK_LEFT4DEAD2: 2268 | { 2269 | decl String:gameFolder[PLATFORM_MAX_PATH]; 2270 | GetGameFolderName(gameFolder, PLATFORM_MAX_PATH); 2271 | if (StrEqual(gameFolder, "nd", false)) 2272 | { 2273 | version = Engine_NuclearDawn; 2274 | } 2275 | else 2276 | { 2277 | version = Engine_Left4Dead2; 2278 | } 2279 | } 2280 | 2281 | case SOURCE_SDK_ALIENSWARM: 2282 | { 2283 | version = Engine_AlienSwarm; 2284 | } 2285 | 2286 | case SOURCE_SDK_CSGO: 2287 | { 2288 | version = Engine_CSGO; 2289 | } 2290 | 2291 | default: 2292 | { 2293 | version = Engine_Unknown; 2294 | } 2295 | } 2296 | } 2297 | else 2298 | { 2299 | version = GetEngineVersion(); 2300 | } 2301 | 2302 | return version; 2303 | } 2304 | 2305 | GetVoteSize() 2306 | { 2307 | new voteSize = GetConVarInt(g_Cvar_IncludeMaps); 2308 | 2309 | // New in 1.9.5 to let us bump up the included maps count 2310 | if (g_NativeVotes) 2311 | { 2312 | new max = NativeVotes_GetMaxItems(); 2313 | 2314 | if (max < voteSize) 2315 | { 2316 | voteSize = max; 2317 | } 2318 | } 2319 | 2320 | return voteSize; 2321 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/mapchooser_extended_sounds.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * MapChooser Extended Sounds 5 | * Sound support for Mapchooser Extended 6 | * Inspired by QuakeSounds 2.7 7 | * 8 | * MapChooser Extended Sounds (C)2011-2014 Powerlord (Ross Bemrose) 9 | * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. 10 | * ============================================================================= 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, version 3.0, as published by the 14 | * Free Software Foundation. 15 | * 16 | * This program 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 the GNU General Public License for more 19 | * details. 20 | * 21 | * You should have received a copy of the GNU General Public License along with 22 | * this program. If not, see . 23 | * 24 | * As a special exception, AlliedModders LLC gives you permission to link the 25 | * code of this program (as well as its derivative works) to "Half-Life 2," the 26 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 27 | * by the Valve Corporation. You must obey the GNU General Public License in 28 | * all respects for all other code used. Additionally, AlliedModders LLC grants 29 | * this exception to all derivative works. AlliedModders LLC defines further 30 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 31 | * or . 32 | * 33 | * Version: $Id$ 34 | */ 35 | 36 | #pragma semicolon 1 37 | #include 38 | #include 39 | #include "include/mapchooser_extended" 40 | #include 41 | #include 42 | 43 | #define VERSION "1.10.3" 44 | 45 | #define CONFIG_FILE "configs/mapchooser_extended/sounds.cfg" 46 | #define CONFIG_DIRECTORY "configs/mapchooser_extended/sounds" 47 | 48 | #define SET_NAME_MAX_LENGTH 64 49 | 50 | // 0-60, even though we don't ever call 0 51 | // Counter-intuitive note: This array has 61 elements, not 60 52 | #define COUNTER_MAX_SIZE 60 53 | // The number of digits in the previous number 54 | #define COUNTER_MAX_SIZE_DIGITS 2 55 | 56 | #define NUM_TYPES 5 57 | 58 | // CVar Handles 59 | new Handle:g_Cvar_EnableSounds = INVALID_HANDLE; 60 | new Handle:g_Cvar_EnableCounterSounds = INVALID_HANDLE; 61 | new Handle:g_Cvar_SoundSet = INVALID_HANDLE; 62 | new Handle:g_Cvar_DownloadAllSounds = INVALID_HANDLE; 63 | 64 | // Data Handles 65 | new Handle:g_TypeNames = INVALID_HANDLE; // Maps SoundEvent enumeration values to KeyValue section names 66 | new Handle:g_SetNames = INVALID_HANDLE; 67 | new Handle:g_SoundFiles = INVALID_HANDLE; 68 | new Handle:g_CurrentSoundSet = INVALID_HANDLE; // Lazy "pointer" to the current sound set. Updated on cvar change or map change. 69 | 70 | //Global variables 71 | new bool:g_DownloadAllSounds; 72 | 73 | enum SoundEvent 74 | { 75 | SoundEvent_Counter = 0, 76 | SoundEvent_VoteStart = 1, 77 | SoundEvent_VoteEnd = 2, 78 | SoundEvent_VoteWarning = 3, 79 | SoundEvent_RunoffWarning = 4, 80 | } 81 | 82 | enum SoundType 83 | { 84 | SoundType_None, 85 | SoundType_Sound, 86 | SoundType_Builtin, 87 | SoundType_Event 88 | } 89 | 90 | enum SoundStore 91 | { 92 | String:SoundStore_Value[PLATFORM_MAX_PATH], 93 | SoundType:SoundStore_Type 94 | } 95 | 96 | public Plugin:myinfo = 97 | { 98 | name = "Mapchooser Extended Sounds", 99 | author = "Powerlord", 100 | description = "Sound support for Mapchooser Extended", 101 | version = VERSION, 102 | url = "https://forums.alliedmods.net/showthread.php?t=156974" 103 | } 104 | 105 | // Map enum values to their named values 106 | // This is used for searching later. 107 | PopulateTypeNamesArray() 108 | { 109 | if (g_TypeNames == INVALID_HANDLE) 110 | { 111 | g_TypeNames = CreateArray(ByteCountToCells(SET_NAME_MAX_LENGTH), NUM_TYPES); 112 | SetArrayString(g_TypeNames, _:SoundEvent_Counter, "counter"); 113 | SetArrayString(g_TypeNames, _:SoundEvent_VoteStart, "vote start"); 114 | SetArrayString(g_TypeNames, _:SoundEvent_VoteEnd, "vote end"); 115 | SetArrayString(g_TypeNames, _:SoundEvent_VoteWarning, "vote warning"); 116 | SetArrayString(g_TypeNames, _:SoundEvent_RunoffWarning, "runoff warning"); 117 | } 118 | } 119 | 120 | public OnPluginStart() 121 | { 122 | g_Cvar_EnableSounds = CreateConVar("mce_sounds_enablesounds", "1", "Enable this plugin. Sounds will still be downloaded (if applicable) even if the plugin is disabled this way.", FCVAR_NONE, true, 0.0, true, 1.0); 123 | g_Cvar_EnableCounterSounds = CreateConVar("mce_sounds_enablewarningcountersounds", "1", "Enable sounds to be played during warning counter. If this is disabled, map vote warning, start, and stop sounds still play.", FCVAR_NONE, true, 0.0, true, 1.0); 124 | g_Cvar_SoundSet = CreateConVar("mce_sounds_soundset", "tf", "Sound set to use, optimized for TF by default. Sound sets are defined in addons/sourcemod/configs/mapchooser_extended_sounds.cfg. Takes effect immediately if sm_mapvote_downloadallsounds is 1, otherwise at map change.", FCVAR_NONE); 125 | g_Cvar_DownloadAllSounds = CreateConVar("mce_sounds_downloadallsounds", "0", "Force players to download all sound sets, so sets can be dynamically changed during the map. Defaults to off. Takes effect at map change.", FCVAR_NONE, true, 0.0, true, 1.0); 126 | CreateConVar("mce_sounds_version", VERSION, "Mapchooser Extended Sounds Version", FCVAR_DONTRECORD|FCVAR_SPONLY|FCVAR_REPLICATED); 127 | 128 | AutoExecConfig(true, "mapchooser_extended_sounds"); 129 | 130 | RegAdminCmd("mce_sounds_reload", Command_Reload, ADMFLAG_CONVARS, "Reload Mapchooser Sound configuration file."); 131 | RegAdminCmd("sm_mapvote_reload_sounds", Command_Reload, ADMFLAG_CONVARS, "Deprecated: use mce_sounds_reload"); 132 | 133 | RegAdminCmd("mce_sounds_list_soundsets", Command_List_Soundsets, ADMFLAG_CONVARS, "List available Mapchooser Extended sound sets."); 134 | RegAdminCmd("sm_mapvote_list_soundsets", Command_List_Soundsets, ADMFLAG_CONVARS, "Deprecated: use mce_sounds_list_soundsets"); 135 | 136 | PopulateTypeNamesArray(); 137 | // LoadSounds needs to be executed even if the plugin is "disabled" via the sm_mapvote_enablesounds cvar. 138 | 139 | g_SetNames = CreateArray(ByteCountToCells(PLATFORM_MAX_PATH)); 140 | g_SoundFiles = CreateTrie(); 141 | LoadSounds(); 142 | HookConVarChange(g_Cvar_SoundSet, SoundSetChanged); 143 | } 144 | 145 | // Not sure this is required, but there were some weird crashes when this plugin was unloaded. This is an attempt to fix that. 146 | /* 147 | public OnPluginEnd() 148 | { 149 | CloseSoundArrayHandles(); 150 | } 151 | */ 152 | 153 | /* 154 | * Moved to OnConfigsExecuted due to cvar requirements 155 | public OnMapStart() 156 | { 157 | BuildDownloadsTableAll(); 158 | } 159 | */ 160 | 161 | public OnConfigsExecuted() 162 | { 163 | g_DownloadAllSounds = GetConVarBool(g_Cvar_DownloadAllSounds); 164 | 165 | SetSoundSetFromCVar(); 166 | 167 | if (g_DownloadAllSounds) 168 | { 169 | BuildDownloadsTableAll(); 170 | } 171 | else 172 | { 173 | BuildDownloadsTable(g_CurrentSoundSet); 174 | } 175 | } 176 | 177 | SetSoundSetFromCVar() 178 | { 179 | decl String:soundSet[SET_NAME_MAX_LENGTH]; 180 | 181 | // Store which sound set is in use 182 | GetConVarString(g_Cvar_SoundSet, soundSet, sizeof(soundSet)); 183 | 184 | // Unknown sound set from config file, reset to default 185 | if (FindStringInArray(g_SetNames, soundSet) == -1 && !StrEqual(soundSet, "tf", true)) 186 | { 187 | ResetConVar(g_Cvar_SoundSet); 188 | GetConVarString(g_Cvar_SoundSet, soundSet, sizeof(soundSet)); 189 | } 190 | 191 | SetCurrentSoundSet(soundSet); 192 | } 193 | 194 | public SoundSetChanged(Handle:cvar, String:oldValue[], String:newValue[]) 195 | { 196 | if (FindStringInArray(g_SetNames, newValue) == -1) 197 | { 198 | LogError("New sound set not found: %s", newValue); 199 | SetConVarString(cvar, oldValue); 200 | } 201 | else if (g_DownloadAllSounds) 202 | { 203 | SetCurrentSoundSet(newValue); 204 | } 205 | } 206 | 207 | public OnMapVoteStarted() 208 | { 209 | PlaySound(SoundEvent_VoteStart); 210 | } 211 | 212 | public OnMapVoteEnd(const String:map[]) 213 | { 214 | PlaySound(SoundEvent_VoteEnd); 215 | } 216 | 217 | public OnMapVoteWarningStart() 218 | { 219 | PlaySound(SoundEvent_VoteWarning); 220 | } 221 | 222 | public OnMapVoteRunnoffWarningStart() 223 | { 224 | PlaySound(SoundEvent_RunoffWarning); 225 | } 226 | 227 | public OnMapVoteWarningTick(time) 228 | { 229 | if (GetConVarBool(g_Cvar_EnableSounds) && GetConVarBool(g_Cvar_EnableCounterSounds)) { 230 | decl String:currentType[SET_NAME_MAX_LENGTH]; 231 | decl Handle:counterTrie; 232 | 233 | if (g_CurrentSoundSet != INVALID_HANDLE) 234 | { 235 | if (GetArrayString(g_TypeNames, _:SoundEvent_Counter, currentType, sizeof(currentType)) > 0 && GetTrieValue(g_CurrentSoundSet, currentType, counterTrie)) 236 | { 237 | new String:key[5]; 238 | IntToString(time, key, sizeof(key)); 239 | 240 | new soundData[SoundStore]; 241 | if (!GetTrieArray(counterTrie, key, soundData[0], sizeof(soundData))) 242 | { 243 | return; 244 | } 245 | 246 | if (soundData[SoundStore_Type] == SoundType_Event) 247 | { 248 | new Handle:broadcastEvent = CreateEvent("teamplay_broadcast_audio"); 249 | if (broadcastEvent == INVALID_HANDLE) 250 | { 251 | #if defined DEBUG 252 | LogError("Could not create teamplay_broadcast_event. This may be because there are no players connected."); 253 | #endif 254 | return; 255 | } 256 | SetEventInt(broadcastEvent, "team", -1); 257 | SetEventString(broadcastEvent, "sound", soundData[SoundStore_Value]); 258 | FireEvent(broadcastEvent); 259 | } 260 | else 261 | { 262 | EmitSoundToAllAny(soundData[SoundStore_Value]); 263 | } 264 | } 265 | } 266 | } 267 | } 268 | 269 | public Action:Command_Reload(client, args) 270 | { 271 | LoadSounds(); 272 | SetSoundSetFromCVar(); 273 | ReplyToCommand(client, "[MCES] Reloaded sound configuration."); 274 | return Plugin_Handled; 275 | } 276 | 277 | public Action:Command_List_Soundsets(client, args) 278 | { 279 | new setCount = GetArraySize(g_SetNames); 280 | ReplyToCommand(client, "[SM] The following %d sound sets are installed:", setCount); 281 | for (new i = 0; i < setCount; i++) 282 | { 283 | decl String:setName[SET_NAME_MAX_LENGTH]; 284 | GetArrayString(g_SetNames, i, setName, sizeof(setName)); 285 | ReplyToCommand(client, "[SM] %s", setName); 286 | } 287 | } 288 | 289 | PlaySound(SoundEvent:event) 290 | { 291 | if (GetConVarBool(g_Cvar_EnableSounds)) 292 | { 293 | if (g_CurrentSoundSet != INVALID_HANDLE) 294 | { 295 | decl String:currentType[SET_NAME_MAX_LENGTH]; 296 | 297 | if (GetArrayString(g_TypeNames, _:event, currentType, sizeof(currentType)) > 0) 298 | { 299 | new soundData[SoundStore]; 300 | GetTrieArray(g_CurrentSoundSet, currentType, soundData[0], sizeof(soundData)); 301 | if (soundData[SoundStore_Type] == SoundType_Event) 302 | { 303 | new Handle:broadcastEvent = CreateEvent("teamplay_broadcast_audio"); 304 | if (broadcastEvent == INVALID_HANDLE) 305 | { 306 | #if defined DEBUG 307 | LogError("Could not create teamplay_broadcast_event. This may be because there are no players connected."); 308 | #endif 309 | return; 310 | } 311 | SetEventInt(broadcastEvent, "team", -1); 312 | SetEventString(broadcastEvent, "sound", soundData[SoundStore_Value]); 313 | FireEvent(broadcastEvent); 314 | } 315 | else 316 | { 317 | EmitSoundToAllAny(soundData[SoundStore_Value]); 318 | } 319 | } 320 | } 321 | } 322 | 323 | } 324 | 325 | SetCurrentSoundSet(String:soundSet[]) 326 | { 327 | // Save a reference to the Trie for the current sound set, for use in the forwards below. 328 | // Also do error checking to make sure the set exists. 329 | if (!GetTrieValue(g_SoundFiles, soundSet, g_CurrentSoundSet)) 330 | { 331 | SetFailState("Could not load sound set"); 332 | } 333 | 334 | } 335 | 336 | // Load the list of sounds sounds from the configuration file 337 | // This should be done on plugin load. 338 | // This looks really complicated, but it really isn't. 339 | LoadSounds() 340 | { 341 | CloseSoundArrayHandles(); 342 | 343 | decl String:directoryPath[PLATFORM_MAX_PATH]; 344 | decl String:modName[SET_NAME_MAX_LENGTH]; 345 | 346 | GetGameFolderName(modName, sizeof(modName)); 347 | 348 | BuildPath(Path_SM, directoryPath, sizeof(directoryPath), CONFIG_DIRECTORY); 349 | 350 | new Handle:directory = OpenDirectory(directoryPath); 351 | if (directory != INVALID_HANDLE) 352 | { 353 | decl String:dirEntry[PLATFORM_MAX_PATH]; 354 | while (ReadDirEntry(directory, dirEntry, sizeof(dirEntry))) 355 | { 356 | new Handle:soundsKV = CreateKeyValues("MapchooserSoundsList"); 357 | decl String:filePath[PLATFORM_MAX_PATH]; 358 | 359 | Format(filePath, sizeof(filePath), "%s/%s", directoryPath, dirEntry); 360 | 361 | if (!DirExists(filePath)) 362 | { 363 | FileToKeyValues(soundsKV, filePath); 364 | 365 | if (KvGotoFirstSubKey(soundsKV)) 366 | { 367 | // Iterate through the sets 368 | do 369 | { 370 | new Handle:setTrie = CreateTrie(); 371 | decl String:currentSet[SET_NAME_MAX_LENGTH]; 372 | new bool:builtinSet = false; 373 | 374 | KvGetSectionName(soundsKV, currentSet, sizeof(currentSet)); 375 | 376 | if (FindStringInArray(g_SetNames, currentSet) == -1) 377 | { 378 | // Add to the list of sound sets 379 | PushArrayString(g_SetNames, currentSet); 380 | } 381 | else 382 | { 383 | SetFailState("Duplicate sound set: %s", currentSet); 384 | } 385 | 386 | if (StrEqual(currentSet, modName, false)) 387 | { 388 | builtinSet = true; 389 | } 390 | 391 | if (KvGotoFirstSubKey(soundsKV)) { 392 | // Iterate through each sound in the set 393 | do 394 | { 395 | decl String:currentType[SET_NAME_MAX_LENGTH]; 396 | KvGetSectionName(soundsKV, currentType, sizeof(currentType)); 397 | // Type to enum mapping 398 | new typeKey = FindStringInArray(g_TypeNames, currentType); 399 | 400 | switch(typeKey) 401 | { 402 | case SoundEvent_Counter: 403 | { 404 | // Counter is special, as it has multiple values 405 | new Handle:counterTrie = CreateTrie(); 406 | 407 | if (KvGotoFirstSubKey(soundsKV)) 408 | { 409 | do 410 | { 411 | // Get the current key 412 | decl String:time[COUNTER_MAX_SIZE_DIGITS + 1]; 413 | 414 | KvGetSectionName(soundsKV, time, sizeof(time)); 415 | 416 | new soundData[SoundStore]; 417 | 418 | // new key = StringToInt(time); 419 | 420 | soundData[SoundStore_Type] = RetrieveSound(soundsKV, builtinSet, soundData[SoundStore_Value], PLATFORM_MAX_PATH); 421 | if (soundData[SoundStore_Type] == SoundType_None) 422 | { 423 | continue; 424 | } 425 | 426 | // This seems wrong, but this is documented on the forums here: https://forums.alliedmods.net/showthread.php?t=151942 427 | SetTrieArray(counterTrie, time, soundData[0], sizeof(soundData)); 428 | 429 | //SetArrayString(counterArray, key, soundFile); 430 | } while (KvGotoNextKey(soundsKV)); 431 | KvGoBack(soundsKV); 432 | } 433 | 434 | SetTrieValue(setTrie, currentType, _:counterTrie); 435 | 436 | } 437 | 438 | // Set the sounds directly for other types 439 | default: 440 | { 441 | new soundData[SoundStore]; 442 | 443 | soundData[SoundStore_Type] = RetrieveSound(soundsKV, builtinSet, soundData[SoundStore_Value], PLATFORM_MAX_PATH); 444 | 445 | if (soundData[SoundStore_Type] == SoundType_None) 446 | { 447 | continue; 448 | } 449 | 450 | SetTrieArray(setTrie, currentType, soundData[0], sizeof(soundData)); 451 | } 452 | } 453 | } while (KvGotoNextKey(soundsKV)); 454 | KvGoBack(soundsKV); 455 | } 456 | SetTrieValue(g_SoundFiles, currentSet, setTrie); 457 | } while (KvGotoNextKey(soundsKV)); 458 | } 459 | } 460 | CloseHandle(soundsKV); 461 | } 462 | CloseHandle(directory); 463 | } 464 | 465 | if (GetArraySize(g_SetNames) == 0) 466 | { 467 | SetFailState("Could not locate any sound sets."); 468 | } 469 | } 470 | 471 | // Internal LoadSounds function to get sound and type 472 | SoundType:RetrieveSound(Handle:soundsKV, bool:isBuiltin, String:soundFile[], soundFileSize) 473 | { 474 | if (isBuiltin) 475 | { 476 | // event is considered before builtin, as it has related game data and should always be used in preference to builtin 477 | KvGetString(soundsKV, "event", soundFile,soundFileSize); 478 | 479 | if (!StrEqual(soundFile, "")) 480 | { 481 | return SoundType_Event; 482 | } 483 | 484 | KvGetString(soundsKV, "builtin", soundFile, soundFileSize); 485 | if (!StrEqual(soundFile, "")) 486 | { 487 | return SoundType_Builtin; 488 | } 489 | } 490 | 491 | KvGetString(soundsKV, "sound", soundFile, soundFileSize); 492 | 493 | if (!StrEqual(soundFile, "")) 494 | { 495 | return SoundType_Sound; 496 | } 497 | 498 | // Whoops, didn't find this sound 499 | return SoundType_None; 500 | } 501 | 502 | // Preload all sounds in a set 503 | BuildDownloadsTable(Handle:currentSoundSet) 504 | { 505 | if (currentSoundSet != INVALID_HANDLE) 506 | { 507 | for (new i = 0; i < GetArraySize(g_TypeNames); i++) 508 | { 509 | decl String:currentType[SET_NAME_MAX_LENGTH]; 510 | GetArrayString(g_TypeNames, i, currentType, sizeof(currentType)); 511 | 512 | switch(i) 513 | { 514 | case SoundEvent_Counter: 515 | { 516 | decl Handle:counterTrie; 517 | if (GetTrieValue(currentSoundSet, currentType, counterTrie)) 518 | { 519 | // Skip value 0 520 | for (new j = 1; j <= COUNTER_MAX_SIZE; ++j) 521 | { 522 | new String:key[5]; 523 | IntToString(j, key, sizeof(key)); 524 | 525 | new soundData[SoundStore]; 526 | GetTrieArray(counterTrie, key, soundData[0], sizeof(soundData)); 527 | if (soundData[SoundStore_Type] != SoundType_Event) 528 | { 529 | CacheSound(soundData); 530 | } 531 | } 532 | } 533 | } 534 | 535 | default: 536 | { 537 | new soundData[SoundStore]; 538 | GetTrieArray(currentSoundSet, currentType, soundData[0], sizeof(soundData)); 539 | 540 | if (soundData[SoundStore_Type] != SoundType_Event) 541 | { 542 | CacheSound(soundData); 543 | } 544 | } 545 | } 546 | } 547 | } 548 | } 549 | 550 | // Load each set and build its download table 551 | stock BuildDownloadsTableAll() 552 | { 553 | for (new i = 0; i < GetArraySize(g_SetNames); i++) 554 | { 555 | decl String:currentSet[SET_NAME_MAX_LENGTH]; 556 | decl Handle:currentSoundSet; 557 | GetArrayString(g_SetNames, i, currentSet, sizeof(currentSet)); 558 | 559 | if (GetTrieValue(g_SoundFiles, currentSet, currentSoundSet)) 560 | { 561 | BuildDownloadsTable(currentSoundSet); 562 | } 563 | } 564 | } 565 | 566 | // Found myself repeating this code, so I pulled it into a separate function 567 | CacheSound(soundData[SoundStore]) 568 | { 569 | if (soundData[SoundStore_Type] == SoundType_Builtin) 570 | { 571 | PrecacheSoundAny(soundData[SoundStore_Value]); 572 | } 573 | else if (soundData[SoundStore_Type] == SoundType_Sound) 574 | { 575 | if (PrecacheSoundAny(soundData[SoundStore_Value])) 576 | { 577 | decl String:downloadLocation[PLATFORM_MAX_PATH]; 578 | Format(downloadLocation, sizeof(downloadLocation), "sound/%s", soundData[SoundStore_Value]); 579 | AddFileToDownloadsTable(downloadLocation); 580 | } else { 581 | LogMessage("Failed to load sound: %s", soundData[SoundStore_Value]); 582 | } 583 | } 584 | } 585 | 586 | // Close all the handles that are children and grandchildren of the g_SoundFiles trie. 587 | stock CloseSoundArrayHandles() 588 | { 589 | // Close all open handles in the sound set 590 | for (new i = 0; i < GetArraySize(g_SetNames); i++) 591 | { 592 | decl String:currentSet[SET_NAME_MAX_LENGTH]; 593 | decl Handle:trieHandle; 594 | decl Handle:arrayHandle; 595 | 596 | GetArrayString(g_SetNames, i, currentSet, sizeof(currentSet)); 597 | GetTrieValue(g_SoundFiles, currentSet, trieHandle); 598 | // "counter" is an adt_trie, close that too 599 | GetTrieValue(trieHandle, "counter", arrayHandle); 600 | CloseHandle(arrayHandle); 601 | CloseHandle(trieHandle); 602 | } 603 | ClearTrie(g_SoundFiles); 604 | ClearArray(g_SetNames); 605 | 606 | g_CurrentSoundSet = INVALID_HANDLE; 607 | } 608 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/nominations_extended.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * Nominations Extended 5 | * Allows players to nominate maps for Mapchooser 6 | * 7 | * Nominations Extended (C)2012-2013 Powerlord (Ross Bemrose) 8 | * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. 9 | * ============================================================================= 10 | * 11 | * This program is free software; you can redistribute it and/or modify it under 12 | * the terms of the GNU General Public License, version 3.0, as published by the 13 | * Free Software Foundation. 14 | * 15 | * This program 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 the GNU General Public License for more 18 | * details. 19 | * 20 | * You should have received a copy of the GNU General Public License along with 21 | * this program. If not, see . 22 | * 23 | * As a special exception, AlliedModders LLC gives you permission to link the 24 | * code of this program (as well as its derivative works) to "Half-Life 2," the 25 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 26 | * by the Valve Corporation. You must obey the GNU General Public License in 27 | * all respects for all other code used. Additionally, AlliedModders LLC grants 28 | * this exception to all derivative works. AlliedModders LLC defines further 29 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 30 | * or . 31 | * 32 | * Version: $Id$ 33 | */ 34 | 35 | #include 36 | #include 37 | #include "include/mapchooser_extended" 38 | #include 39 | #pragma semicolon 1 40 | 41 | #define MCE_VERSION "1.10.0" 42 | 43 | public Plugin:myinfo = 44 | { 45 | name = "Map Nominations Extended", 46 | author = "Powerlord and AlliedModders LLC", 47 | description = "Provides Map Nominations", 48 | version = MCE_VERSION, 49 | url = "https://forums.alliedmods.net/showthread.php?t=156974" 50 | }; 51 | 52 | new Handle:g_Cvar_ExcludeOld = INVALID_HANDLE; 53 | new Handle:g_Cvar_ExcludeCurrent = INVALID_HANDLE; 54 | 55 | new Handle:g_MapList = INVALID_HANDLE; 56 | new Handle:g_MapMenu = INVALID_HANDLE; 57 | new g_mapFileSerial = -1; 58 | 59 | #define MAPSTATUS_ENABLED (1<<0) 60 | #define MAPSTATUS_DISABLED (1<<1) 61 | #define MAPSTATUS_EXCLUDE_CURRENT (1<<2) 62 | #define MAPSTATUS_EXCLUDE_PREVIOUS (1<<3) 63 | #define MAPSTATUS_EXCLUDE_NOMINATED (1<<4) 64 | 65 | new Handle:g_mapTrie; 66 | 67 | // Nominations Extended Convars 68 | new Handle:g_Cvar_MarkCustomMaps = INVALID_HANDLE; 69 | 70 | public OnPluginStart() 71 | { 72 | LoadTranslations("common.phrases"); 73 | LoadTranslations("nominations.phrases"); 74 | LoadTranslations("basetriggers.phrases"); // for Next Map phrase 75 | LoadTranslations("mapchooser_extended.phrases"); 76 | 77 | new arraySize = ByteCountToCells(PLATFORM_MAX_PATH); 78 | g_MapList = CreateArray(arraySize); 79 | 80 | g_Cvar_ExcludeOld = CreateConVar("sm_nominate_excludeold", "1", "Specifies if the current map should be excluded from the Nominations list", 0, true, 0.00, true, 1.0); 81 | g_Cvar_ExcludeCurrent = CreateConVar("sm_nominate_excludecurrent", "1", "Specifies if the MapChooser excluded maps should also be excluded from Nominations", 0, true, 0.00, true, 1.0); 82 | 83 | RegConsoleCmd("say", Command_Say); 84 | RegConsoleCmd("say_team", Command_Say); 85 | 86 | RegConsoleCmd("sm_nominate", Command_Nominate); 87 | 88 | RegAdminCmd("sm_nominate_addmap", Command_Addmap, ADMFLAG_CHANGEMAP, "sm_nominate_addmap - Forces a map to be on the next mapvote."); 89 | 90 | // Nominations Extended cvars 91 | CreateConVar("ne_version", MCE_VERSION, "Nominations Extended Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD); 92 | 93 | 94 | g_mapTrie = CreateTrie(); 95 | } 96 | 97 | public OnAllPluginsLoaded() 98 | { 99 | // This is an MCE cvar... this plugin requires MCE to be loaded. Granted, this plugin SHOULD have an MCE dependency. 100 | g_Cvar_MarkCustomMaps = FindConVar("mce_markcustommaps"); 101 | } 102 | 103 | public OnConfigsExecuted() 104 | { 105 | if (ReadMapList(g_MapList, 106 | g_mapFileSerial, 107 | "nominations", 108 | MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_MAPSFOLDER) 109 | == INVALID_HANDLE) 110 | { 111 | if (g_mapFileSerial == -1) 112 | { 113 | SetFailState("Unable to create a valid map list."); 114 | } 115 | } 116 | 117 | BuildMapMenu(); 118 | } 119 | 120 | public OnNominationRemoved(const String:map[], owner) 121 | { 122 | new status; 123 | 124 | /* Is the map in our list? */ 125 | if (!GetTrieValue(g_mapTrie, map, status)) 126 | { 127 | return; 128 | } 129 | 130 | /* Was the map disabled due to being nominated */ 131 | if ((status & MAPSTATUS_EXCLUDE_NOMINATED) != MAPSTATUS_EXCLUDE_NOMINATED) 132 | { 133 | return; 134 | } 135 | 136 | SetTrieValue(g_mapTrie, map, MAPSTATUS_ENABLED); 137 | } 138 | 139 | public Action:Command_Addmap(client, args) 140 | { 141 | if (args < 1) 142 | { 143 | CReplyToCommand(client, "[NE] Usage: sm_nominate_addmap "); 144 | return Plugin_Handled; 145 | } 146 | 147 | decl String:mapname[PLATFORM_MAX_PATH]; 148 | GetCmdArg(1, mapname, sizeof(mapname)); 149 | 150 | 151 | new status; 152 | if (!GetTrieValue(g_mapTrie, mapname, status)) 153 | { 154 | CReplyToCommand(client, "%t", "Map was not found", mapname); 155 | return Plugin_Handled; 156 | } 157 | 158 | new NominateResult:result = NominateMap(mapname, true, 0); 159 | 160 | if (result > Nominate_Replaced) 161 | { 162 | /* We assume already in vote is the casue because the maplist does a Map Validity check and we forced, so it can't be full */ 163 | CReplyToCommand(client, "%t", "Map Already In Vote", mapname); 164 | 165 | return Plugin_Handled; 166 | } 167 | 168 | 169 | SetTrieValue(g_mapTrie, mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED); 170 | 171 | 172 | CReplyToCommand(client, "%t", "Map Inserted", mapname); 173 | LogAction(client, -1, "\"%L\" inserted map \"%s\".", client, mapname); 174 | 175 | return Plugin_Handled; 176 | } 177 | 178 | public Action:Command_Say(client, args) 179 | { 180 | if (!client) 181 | { 182 | return Plugin_Continue; 183 | } 184 | 185 | decl String:text[192]; 186 | if (!GetCmdArgString(text, sizeof(text))) 187 | { 188 | return Plugin_Continue; 189 | } 190 | 191 | new startidx = 0; 192 | if(text[strlen(text)-1] == '"') 193 | { 194 | text[strlen(text)-1] = '\0'; 195 | startidx = 1; 196 | } 197 | 198 | new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT); 199 | 200 | if (strcmp(text[startidx], "nominate", false) == 0) 201 | { 202 | if (IsNominateAllowed(client)) 203 | { 204 | AttemptNominate(client); 205 | } 206 | } 207 | 208 | SetCmdReplySource(old); 209 | 210 | return Plugin_Continue; 211 | } 212 | 213 | public Action:Command_Nominate(client, args) 214 | { 215 | if (!client || !IsNominateAllowed(client)) 216 | { 217 | return Plugin_Handled; 218 | } 219 | 220 | if (args == 0) 221 | { 222 | AttemptNominate(client); 223 | return Plugin_Handled; 224 | } 225 | 226 | decl String:mapname[PLATFORM_MAX_PATH]; 227 | GetCmdArg(1, mapname, sizeof(mapname)); 228 | 229 | new status; 230 | if (!GetTrieValue(g_mapTrie, mapname, status)) 231 | { 232 | CReplyToCommand(client, "%t", "Map was not found", mapname); 233 | return Plugin_Handled; 234 | } 235 | 236 | if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED) 237 | { 238 | if ((status & MAPSTATUS_EXCLUDE_CURRENT) == MAPSTATUS_EXCLUDE_CURRENT) 239 | { 240 | CReplyToCommand(client, "[NE] %t", "Can't Nominate Current Map"); 241 | } 242 | 243 | if ((status & MAPSTATUS_EXCLUDE_PREVIOUS) == MAPSTATUS_EXCLUDE_PREVIOUS) 244 | { 245 | CReplyToCommand(client, "[NE] %t", "Map in Exclude List"); 246 | } 247 | 248 | if ((status & MAPSTATUS_EXCLUDE_NOMINATED) == MAPSTATUS_EXCLUDE_NOMINATED) 249 | { 250 | CReplyToCommand(client, "[NE] %t", "Map Already Nominated"); 251 | } 252 | 253 | return Plugin_Handled; 254 | } 255 | 256 | new NominateResult:result = NominateMap(mapname, false, client); 257 | 258 | if (result > Nominate_Replaced) 259 | { 260 | if (result == Nominate_AlreadyInVote) 261 | { 262 | CReplyToCommand(client, "%t", "Map Already In Vote", mapname); 263 | } 264 | else 265 | { 266 | CReplyToCommand(client, "[NE] %t", "Map Already Nominated"); 267 | } 268 | 269 | return Plugin_Handled; 270 | } 271 | 272 | /* Map was nominated! - Disable the menu item and update the trie */ 273 | 274 | SetTrieValue(g_mapTrie, mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED); 275 | 276 | decl String:name[MAX_NAME_LENGTH]; 277 | GetClientName(client, name, sizeof(name)); 278 | PrintToChatAll("[NE] %t", "Map Nominated", name, mapname); 279 | LogMessage("%s nominated %s", name, mapname); 280 | 281 | return Plugin_Continue; 282 | } 283 | 284 | AttemptNominate(client) 285 | { 286 | SetMenuTitle(g_MapMenu, "%T", "Nominate Title", client); 287 | DisplayMenu(g_MapMenu, client, MENU_TIME_FOREVER); 288 | 289 | return; 290 | } 291 | 292 | BuildMapMenu() 293 | { 294 | if (g_MapMenu != INVALID_HANDLE) 295 | { 296 | CloseHandle(g_MapMenu); 297 | g_MapMenu = INVALID_HANDLE; 298 | } 299 | 300 | ClearTrie(g_mapTrie); 301 | 302 | g_MapMenu = CreateMenu(Handler_MapSelectMenu, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem); 303 | 304 | decl String:map[PLATFORM_MAX_PATH]; 305 | 306 | new Handle:excludeMaps = INVALID_HANDLE; 307 | decl String:currentMap[32]; 308 | 309 | if (GetConVarBool(g_Cvar_ExcludeOld)) 310 | { 311 | excludeMaps = CreateArray(ByteCountToCells(PLATFORM_MAX_PATH)); 312 | GetExcludeMapList(excludeMaps); 313 | } 314 | 315 | if (GetConVarBool(g_Cvar_ExcludeCurrent)) 316 | { 317 | GetCurrentMap(currentMap, sizeof(currentMap)); 318 | } 319 | 320 | 321 | for (new i = 0; i < GetArraySize(g_MapList); i++) 322 | { 323 | new status = MAPSTATUS_ENABLED; 324 | 325 | GetArrayString(g_MapList, i, map, sizeof(map)); 326 | 327 | if (GetConVarBool(g_Cvar_ExcludeCurrent)) 328 | { 329 | if (StrEqual(map, currentMap)) 330 | { 331 | status = MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_CURRENT; 332 | } 333 | } 334 | 335 | /* Dont bother with this check if the current map check passed */ 336 | if (GetConVarBool(g_Cvar_ExcludeOld) && status == MAPSTATUS_ENABLED) 337 | { 338 | if (FindStringInArray(excludeMaps, map) != -1) 339 | { 340 | status = MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_PREVIOUS; 341 | } 342 | } 343 | 344 | AddMenuItem(g_MapMenu, map, map); 345 | SetTrieValue(g_mapTrie, map, status); 346 | } 347 | 348 | SetMenuExitButton(g_MapMenu, true); 349 | 350 | if (excludeMaps != INVALID_HANDLE) 351 | { 352 | CloseHandle(excludeMaps); 353 | } 354 | } 355 | 356 | public Handler_MapSelectMenu(Handle:menu, MenuAction:action, param1, param2) 357 | { 358 | switch (action) 359 | { 360 | case MenuAction_Select: 361 | { 362 | decl String:map[PLATFORM_MAX_PATH], String:name[MAX_NAME_LENGTH]; 363 | GetMenuItem(menu, param2, map, sizeof(map)); 364 | 365 | GetClientName(param1, name, MAX_NAME_LENGTH); 366 | 367 | new NominateResult:result = NominateMap(map, false, param1); 368 | 369 | /* Don't need to check for InvalidMap because the menu did that already */ 370 | if (result == Nominate_AlreadyInVote) 371 | { 372 | PrintToChat(param1, "[NE] %t", "Map Already Nominated"); 373 | return 0; 374 | } 375 | else if (result == Nominate_VoteFull) 376 | { 377 | PrintToChat(param1, "[NE] %t", "Max Nominations"); 378 | return 0; 379 | } 380 | 381 | SetTrieValue(g_mapTrie, map, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED); 382 | 383 | if (result == Nominate_Replaced) 384 | { 385 | PrintToChatAll("[NE] %t", "Map Nomination Changed", name, map); 386 | return 0; 387 | } 388 | 389 | PrintToChatAll("[NE] %t", "Map Nominated", name, map); 390 | LogMessage("%s nominated %s", name, map); 391 | } 392 | 393 | case MenuAction_DrawItem: 394 | { 395 | decl String:map[PLATFORM_MAX_PATH]; 396 | GetMenuItem(menu, param2, map, sizeof(map)); 397 | 398 | new status; 399 | 400 | if (!GetTrieValue(g_mapTrie, map, status)) 401 | { 402 | LogError("Menu selection of item not in trie. Major logic problem somewhere."); 403 | return ITEMDRAW_DEFAULT; 404 | } 405 | 406 | if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED) 407 | { 408 | return ITEMDRAW_DISABLED; 409 | } 410 | 411 | return ITEMDRAW_DEFAULT; 412 | 413 | } 414 | 415 | case MenuAction_DisplayItem: 416 | { 417 | decl String:map[PLATFORM_MAX_PATH]; 418 | GetMenuItem(menu, param2, map, sizeof(map)); 419 | 420 | new mark = GetConVarInt(g_Cvar_MarkCustomMaps); 421 | new bool:official; 422 | 423 | new status; 424 | 425 | if (!GetTrieValue(g_mapTrie, map, status)) 426 | { 427 | LogError("Menu selection of item not in trie. Major logic problem somewhere."); 428 | return 0; 429 | } 430 | 431 | decl String:buffer[100]; 432 | decl String:display[150]; 433 | 434 | if (mark) 435 | { 436 | official = IsMapOfficial(map); 437 | } 438 | 439 | if (mark && !official) 440 | { 441 | switch (mark) 442 | { 443 | case 1: 444 | { 445 | Format(buffer, sizeof(buffer), "%T", "Custom Marked", param1, map); 446 | } 447 | 448 | case 2: 449 | { 450 | Format(buffer, sizeof(buffer), "%T", "Custom", param1, map); 451 | } 452 | } 453 | } 454 | else 455 | { 456 | strcopy(buffer, sizeof(buffer), map); 457 | } 458 | 459 | if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED) 460 | { 461 | if ((status & MAPSTATUS_EXCLUDE_CURRENT) == MAPSTATUS_EXCLUDE_CURRENT) 462 | { 463 | Format(display, sizeof(display), "%s (%T)", buffer, "Current Map", param1); 464 | return RedrawMenuItem(display); 465 | } 466 | 467 | if ((status & MAPSTATUS_EXCLUDE_PREVIOUS) == MAPSTATUS_EXCLUDE_PREVIOUS) 468 | { 469 | Format(display, sizeof(display), "%s (%T)", buffer, "Recently Played", param1); 470 | return RedrawMenuItem(display); 471 | } 472 | 473 | if ((status & MAPSTATUS_EXCLUDE_NOMINATED) == MAPSTATUS_EXCLUDE_NOMINATED) 474 | { 475 | Format(display, sizeof(display), "%s (%T)", buffer, "Nominated", param1); 476 | return RedrawMenuItem(display); 477 | } 478 | } 479 | 480 | if (mark && !official) 481 | return RedrawMenuItem(buffer); 482 | 483 | return 0; 484 | } 485 | } 486 | 487 | return 0; 488 | } 489 | 490 | stock bool:IsNominateAllowed(client) 491 | { 492 | new CanNominateResult:result = CanNominate(); 493 | 494 | switch(result) 495 | { 496 | case CanNominate_No_VoteInProgress: 497 | { 498 | CReplyToCommand(client, "[ME] %t", "Nextmap Voting Started"); 499 | return false; 500 | } 501 | 502 | case CanNominate_No_VoteComplete: 503 | { 504 | new String:map[PLATFORM_MAX_PATH]; 505 | GetNextMap(map, sizeof(map)); 506 | CReplyToCommand(client, "[NE] %t", "Next Map", map); 507 | return false; 508 | } 509 | 510 | case CanNominate_No_VoteFull: 511 | { 512 | CReplyToCommand(client, "[ME] %t", "Max Nominations"); 513 | return false; 514 | } 515 | } 516 | 517 | return true; 518 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/rockthevote_extended.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * Rock The Vote Extended 5 | * Creates a map vote when the required number of players have requested one. 6 | * 7 | * Rock The Vote Extended (C)2012-2013 Powerlord (Ross Bemrose) 8 | * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. 9 | * ============================================================================= 10 | * 11 | * This program is free software; you can redistribute it and/or modify it under 12 | * the terms of the GNU General Public License, version 3.0, as published by the 13 | * Free Software Foundation. 14 | * 15 | * This program 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 the GNU General Public License for more 18 | * details. 19 | * 20 | * You should have received a copy of the GNU General Public License along with 21 | * this program. If not, see . 22 | * 23 | * As a special exception, AlliedModders LLC gives you permission to link the 24 | * code of this program (as well as its derivative works) to "Half-Life 2," the 25 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 26 | * by the Valve Corporation. You must obey the GNU General Public License in 27 | * all respects for all other code used. Additionally, AlliedModders LLC grants 28 | * this exception to all derivative works. AlliedModders LLC defines further 29 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 30 | * or . 31 | * 32 | * Version: $Id$ 33 | */ 34 | 35 | #include 36 | #include 37 | #include "include/mapchooser_extended" 38 | #include 39 | #include 40 | 41 | #pragma semicolon 1 42 | 43 | #define MCE_VERSION "1.10.0" 44 | 45 | public Plugin:myinfo = 46 | { 47 | name = "Rock The Vote Extended", 48 | author = "Powerlord and AlliedModders LLC", 49 | description = "Provides RTV Map Voting", 50 | version = MCE_VERSION, 51 | url = "https://forums.alliedmods.net/showthread.php?t=156974" 52 | }; 53 | 54 | new Handle:g_Cvar_Needed = INVALID_HANDLE; 55 | new Handle:g_Cvar_MinPlayers = INVALID_HANDLE; 56 | new Handle:g_Cvar_InitialDelay = INVALID_HANDLE; 57 | new Handle:g_Cvar_Interval = INVALID_HANDLE; 58 | new Handle:g_Cvar_ChangeTime = INVALID_HANDLE; 59 | new Handle:g_Cvar_RTVPostVoteAction = INVALID_HANDLE; 60 | 61 | new bool:g_CanRTV = false; // True if RTV loaded maps and is active. 62 | new bool:g_RTVAllowed = false; // True if RTV is available to players. Used to delay rtv votes. 63 | new g_Voters = 0; // Total voters connected. Doesn't include fake clients. 64 | new g_Votes = 0; // Total number of "say rtv" votes 65 | new g_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed) 66 | new bool:g_Voted[MAXPLAYERS+1] = {false, ...}; 67 | 68 | new bool:g_InChange = false; 69 | 70 | public OnPluginStart() 71 | { 72 | LoadTranslations("common.phrases"); 73 | LoadTranslations("rockthevote.phrases"); 74 | LoadTranslations("basevotes.phrases"); 75 | 76 | g_Cvar_Needed = CreateConVar("sm_rtv_needed", "0.60", "Percentage of players needed to rockthevote (Def 60%)", 0, true, 0.05, true, 1.0); 77 | g_Cvar_MinPlayers = CreateConVar("sm_rtv_minplayers", "0", "Number of players required before RTV will be enabled.", 0, true, 0.0, true, float(MAXPLAYERS)); 78 | g_Cvar_InitialDelay = CreateConVar("sm_rtv_initialdelay", "30.0", "Time (in seconds) before first RTV can be held", 0, true, 0.00); 79 | g_Cvar_Interval = CreateConVar("sm_rtv_interval", "240.0", "Time (in seconds) after a failed RTV before another can be held", 0, true, 0.00); 80 | g_Cvar_ChangeTime = CreateConVar("sm_rtv_changetime", "0", "When to change the map after a succesful RTV: 0 - Instant, 1 - RoundEnd, 2 - MapEnd", _, true, 0.0, true, 2.0); 81 | g_Cvar_RTVPostVoteAction = CreateConVar("sm_rtv_postvoteaction", "0", "What to do with RTV's after a mapvote has completed. 0 - Allow, success = instant change, 1 - Deny", _, true, 0.0, true, 1.0); 82 | 83 | RegConsoleCmd("say", Command_Say); 84 | RegConsoleCmd("say_team", Command_Say); 85 | 86 | RegConsoleCmd("sm_rtv", Command_RTV); 87 | 88 | RegAdminCmd("sm_forcertv", Command_ForceRTV, ADMFLAG_CHANGEMAP, "Force an RTV vote"); 89 | RegAdminCmd("mce_forcertv", Command_ForceRTV, ADMFLAG_CHANGEMAP, "Force an RTV vote"); 90 | 91 | // Rock The Vote Extended cvars 92 | CreateConVar("rtve_version", MCE_VERSION, "Rock The Vote Extended Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD); 93 | 94 | AutoExecConfig(true, "rtv"); 95 | } 96 | 97 | public OnMapStart() 98 | { 99 | g_Voters = 0; 100 | g_Votes = 0; 101 | g_VotesNeeded = 0; 102 | g_InChange = false; 103 | 104 | /* Handle late load */ 105 | for (new i=1; i<=MaxClients; i++) 106 | { 107 | if (IsClientConnected(i)) 108 | { 109 | OnClientConnected(i); 110 | } 111 | } 112 | } 113 | 114 | public OnMapEnd() 115 | { 116 | g_CanRTV = false; 117 | g_RTVAllowed = false; 118 | } 119 | 120 | public OnConfigsExecuted() 121 | { 122 | g_CanRTV = true; 123 | g_RTVAllowed = false; 124 | CreateTimer(GetConVarFloat(g_Cvar_InitialDelay), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE); 125 | } 126 | 127 | public OnClientConnected(client) 128 | { 129 | if(IsFakeClient(client)) 130 | return; 131 | 132 | g_Voted[client] = false; 133 | 134 | g_Voters++; 135 | g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed)); 136 | 137 | return; 138 | } 139 | 140 | public OnClientDisconnect(client) 141 | { 142 | if(IsFakeClient(client)) 143 | return; 144 | 145 | if(g_Voted[client]) 146 | { 147 | g_Votes--; 148 | } 149 | 150 | g_Voters--; 151 | 152 | g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed)); 153 | 154 | if (!g_CanRTV) 155 | { 156 | return; 157 | } 158 | 159 | if (g_Votes && 160 | g_Voters && 161 | g_Votes >= g_VotesNeeded && 162 | g_RTVAllowed ) 163 | { 164 | if (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished()) 165 | { 166 | return; 167 | } 168 | 169 | StartRTV(); 170 | } 171 | } 172 | 173 | public Action:Command_RTV(client, args) 174 | { 175 | if (!g_CanRTV || !client) 176 | { 177 | return Plugin_Handled; 178 | } 179 | 180 | AttemptRTV(client); 181 | 182 | return Plugin_Handled; 183 | } 184 | 185 | public Action:Command_Say(client, args) 186 | { 187 | if (!g_CanRTV || !client) 188 | { 189 | return Plugin_Continue; 190 | } 191 | 192 | decl String:text[192]; 193 | if (!GetCmdArgString(text, sizeof(text))) 194 | { 195 | return Plugin_Continue; 196 | } 197 | 198 | new startidx = 0; 199 | if(text[strlen(text)-1] == '"') 200 | { 201 | text[strlen(text)-1] = '\0'; 202 | startidx = 1; 203 | } 204 | 205 | new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT); 206 | 207 | if (strcmp(text[startidx], "rtv", false) == 0 || strcmp(text[startidx], "rockthevote", false) == 0) 208 | { 209 | AttemptRTV(client); 210 | } 211 | 212 | SetCmdReplySource(old); 213 | 214 | return Plugin_Continue; 215 | } 216 | 217 | AttemptRTV(client) 218 | { 219 | if (!g_RTVAllowed || (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished())) 220 | { 221 | CReplyToCommand(client, "[SM] %t", "RTV Not Allowed"); 222 | return; 223 | } 224 | 225 | if (!CanMapChooserStartVote()) 226 | { 227 | CReplyToCommand(client, "[SM] %t", "RTV Started"); 228 | return; 229 | } 230 | 231 | if (GetClientCount(true) < GetConVarInt(g_Cvar_MinPlayers)) 232 | { 233 | CReplyToCommand(client, "[SM] %t", "Minimal Players Not Met"); 234 | return; 235 | } 236 | 237 | if (g_Voted[client]) 238 | { 239 | CReplyToCommand(client, "[SM] %t", "Already Voted", g_Votes, g_VotesNeeded); 240 | return; 241 | } 242 | 243 | new String:name[MAX_NAME_LENGTH]; 244 | GetClientName(client, name, sizeof(name)); 245 | 246 | g_Votes++; 247 | g_Voted[client] = true; 248 | 249 | CPrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded); 250 | 251 | if (g_Votes >= g_VotesNeeded) 252 | { 253 | StartRTV(); 254 | } 255 | } 256 | 257 | public Action:Timer_DelayRTV(Handle:timer) 258 | { 259 | g_RTVAllowed = true; 260 | } 261 | 262 | StartRTV() 263 | { 264 | if (g_InChange) 265 | { 266 | return; 267 | } 268 | 269 | if (EndOfMapVoteEnabled() && HasEndOfMapVoteFinished()) 270 | { 271 | /* Change right now then */ 272 | new String:map[PLATFORM_MAX_PATH]; 273 | if (GetNextMap(map, sizeof(map))) 274 | { 275 | CPrintToChatAll("[SM] %t", "Changing Maps", map); 276 | CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE); 277 | g_InChange = true; 278 | 279 | ResetRTV(); 280 | 281 | g_RTVAllowed = false; 282 | } 283 | return; 284 | } 285 | 286 | if (CanMapChooserStartVote()) 287 | { 288 | new MapChange:when = MapChange:GetConVarInt(g_Cvar_ChangeTime); 289 | InitiateMapChooserVote(when); 290 | 291 | ResetRTV(); 292 | 293 | g_RTVAllowed = false; 294 | CreateTimer(GetConVarFloat(g_Cvar_Interval), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE); 295 | } 296 | } 297 | 298 | ResetRTV() 299 | { 300 | g_Votes = 0; 301 | 302 | for (new i=1; i<=MAXPLAYERS; i++) 303 | { 304 | g_Voted[i] = false; 305 | } 306 | } 307 | 308 | public Action:Timer_ChangeMap(Handle:hTimer) 309 | { 310 | g_InChange = false; 311 | 312 | LogMessage("RTV changing map manually"); 313 | 314 | new String:map[PLATFORM_MAX_PATH]; 315 | if (GetNextMap(map, sizeof(map))) 316 | { 317 | ForceChangeLevel(map, "RTV after mapvote"); 318 | } 319 | 320 | return Plugin_Stop; 321 | } 322 | 323 | // Rock The Vote Extended functions 324 | 325 | public Action:Command_ForceRTV(client, args) 326 | { 327 | if (!g_CanRTV || !client) 328 | { 329 | return Plugin_Handled; 330 | } 331 | 332 | ShowActivity2(client, "[RTVE] ", "%t", "Initiated Vote Map"); 333 | 334 | StartRTV(); 335 | 336 | return Plugin_Handled; 337 | } 338 | 339 | 340 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/chi/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/chi/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "chi" "下一幅地图投票了!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "chi" "下一幅地图投选已开始." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "chi" " 地图投票已结束. 下一幅地图将为 {1}. ( 得票{2}%% , {3}票)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "chi" "当前地图已被延长." 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "chi" "延长当前地图" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "chi" "请勿更换" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "chi" "当前地图已被延长! 投票显示! (得票 {1}%% 共 {2} 票)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "chi" "更换下一幅地图为 \"{1}\"." 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/cze/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/cze/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "cze" "Hlasujte o příští mapě!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "cze" "Hlasování o příští mapě začalo." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "cze" "Hlasování o mapě skončilo. Příští mapou bude {1}. (Obdržela {2}%% z {3} hlasů)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "cze" "Současná mapa byla prodloužena. (Obdržela {1}%% z {2} hlasů)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "cze" "Prodloužit současnou mapu" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "cze" "Neměnit" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "cze" "Současná mapa pokračuje! Hlasování rozhodlo! (Obdržela {1}%% z {2} hlasů)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "cze" "Změnil příští mapu na \"{1}\"." 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/da/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/da/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "da" "Stem om næste bane!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "da" "Afstemning for næste bane er begyndt." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "da" "Bane afstemning er fuldført. Den næste bane vil være {1}. (Modtog {2}%% af {3} stemmer) " 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "da" "Den nuværende bane er blevet forlænget. (Modtog {1}%% af {2} stemmer) " 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "da" "Forlæng bane" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "da" "Skift ikke!" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "da" "Den aktuelle bane fortsætter! Afstemningen har talt! (Modtog {1}%% af {2} stemmer)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "da" "Skiftede næste bane til \"{1}'." 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/de/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "de" "Stimme für die nächste Karte!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "de" "Abstimmung für die nächste Karte wurde gestartet." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "de" "Karten-Abstimmung wurde abgeschlossen. Nächste Karte wird {1} sein. ({2}%% von {3} Stimmen erhalten) " 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "de" "Die aktuelle Karte wurde verlängert. ({1}%% von {2} Stimmen erhalten) " 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "de" "Verlängere aktuelle Karte" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "de" "Nicht wechseln" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "de" "Aktuelle Karte geht weiter! Die Abstimmung hat entschieden! ({1}%% von {2} Stimmen erhalten) " 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "de" "Nächste Karte wurde auf \"{1}\" geändert. " 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "de" "Stichwahl für die nächste Karte!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "de" "Anzahl der Stimmen" 51 | } 52 | 53 | "Custom" 54 | { 55 | "de" "{1} (nicht vorhanden)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "de" "Keine Karte hat mehr als {1}%% der Stimmen.\nEine neue Abstimmung ist erforderlich!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "de" "Stichwahl startet in: {1} Sekunden" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "de" "Achtung! Die Abstimmung für die nächste Karte startet in: {1} Sekunden" 71 | } 72 | 73 | "Line One" 74 | { 75 | "de" "Überlegen Sie, welche Karte Sie spielen möchten ..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "de" "... und nicht unüberlegt wählen!" 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "de" "Abstimmung ist bereits im Gange. Versuch Sie es erneut in {1} Sekunden" 86 | } 87 | 88 | "Tie Vote" 89 | { 90 | "de" "Die Top-{1} Karten haben gleich viele Stimmen!.\nEine neue Abstimmung ist erforderlich!" 91 | } 92 | 93 | "Custom Marked" 94 | { 95 | "de" "*{1}" 96 | } 97 | 98 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/es/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "es" "Vota para el siguiente mapa!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "es" "La votacion para el siguiente mapa ha comenzado." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "es" "Votacion de Mapa finalizado. El siguiente mapa sera {1}. (Recibidos {2}%% de {3} votos)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "es" "El mapa actual ha sido extendido. (Recibidos {1}%% de {2} votos)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "es" "Extender mapa actual" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "es" "No cambiar" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "es" "El mapa actual continua! La votacion ha hablado! (Recibidos {1}%% de {2} votos)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "es" "El siguiente mapa ha cambiado a \"{1}\"." 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "es" "Hacer votacion para el siguiente mapa!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "es" "Numero de Votaciones" 51 | } 52 | 53 | "Custom" 54 | { 55 | "es" "{1} (Custom)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "es" "No hay ningun mapa que haya recibido el {1}%% de votaciones.\nEntonces, que mapa ganara? Es necesario otra votacion!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "es" "La votacion empezara en: {1}s" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "es" "Atencion! La votacion para el siguiente mapa se iniciara en: {1}s" 71 | } 72 | 73 | "Line One" 74 | { 75 | "es" "Considera que mapa quieres jugar..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "es" "...y no pulse los botones sin pensar ;-)" 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "es" "Votacion ya iniciada. Intentando de nuevo en {1}s." 86 | } 87 | 88 | "Tie Vote" 89 | { 90 | "es" "El top {1} de mapas tienen el mismo numero de votaciones.\nSe necesita una nueva votacion!" 91 | } 92 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/fr/mapchooser_extended.phrases.old.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "fr" "Voter pour la prochaine map!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "fr" "Voter pour la prochaine map est lancer." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "fr" "Le VoteMap est terminer. La prochaine map sera {1}. (Reçu {2}%% sur {3} votes)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "fr" "La map actuelle a été prolonger. (Reçu {1}%% sur {2} votes)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "fr" "Prolonger la map" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "fr" "Ne pas changer" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "fr" "La map continue! Le vote a tranché! (Reçu {1}%% sur {2} votes)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "fr" "La map suivante sera \"{1}\"." 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "fr" "Votez a nouveau pour la prochaine Map!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "fr" "Nombres de votes" 51 | } 52 | 53 | "Custom" 54 | { 55 | "fr" "{1} (Custom)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "fr" "Aucune map n'a reçu plus de {1}%% du vote.\nAlors, quels maps va gagner? Un nouveau vote va être lancé!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "fr" "Un nouveau vote commence dans: {1}s" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "fr" "Attention! Le vote pour la prochaine map commence dans: {1}s" 71 | } 72 | 73 | "Line One" 74 | { 75 | "fr" "Voter pour la map que vous voulez jouer..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "fr" "...et ne pas cliquez sur une touche comme un con ;-)" 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "fr" "Vote déjà en cours. Reassayer dans {1}s." 86 | } 87 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/fr/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "fr" "Votez pour la prochaine map!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "fr" "Le vote pour la prochaine map est lancé." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "fr" "Le VoteMap est terminé. La prochaine map sera {1}. (Reçu {2}%% sur {3} votes)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "fr" "La map actuelle a été prolongée. (Reçu {1}%% sur {2} votes)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "fr" "Prolonger la map" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "fr" "Ne pas changer" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "fr" "La map continue! Le vote a tranché! (Reçu {1}%% sur {2} votes)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "fr" "La map suivante sera \"{1}\"." 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "fr" "Votez à nouveau pour la prochaine Map!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "fr" "Nombres de votes" 51 | } 52 | 53 | "Custom" 54 | { 55 | "fr" "{1} (Custom)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "fr" "Aucune map n'a reçu plus de {1}%% du vote.\nAlors, quelle map va gagner? Un nouveau vote va être lancé!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "fr" "Un nouveau vote commence dans: {1}s" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "fr" "Attention! Le vote pour la prochaine map commence dans: {1}s" 71 | } 72 | 73 | "Line One" 74 | { 75 | "fr" "Votez pour la map que vous voulez jouer..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "fr" "...et n'appuyez pas sur une touche comme un con ;-)" 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "fr" "Vote déjà en cours. Reassayez dans {1}s." 86 | } 87 | 88 | "Tie Vote" 89 | { 90 | "fr" "{1} maps ont eu un même nombre de voix.\nUn nouveau vote est nécessaire!" 91 | } 92 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/hu/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/hu/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "hu" "Mi legyen a következő pálya?" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "hu" "Palyavalaszto szavazas elindult!" 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "hu" "A szavazás lezárult. A következő pálya a {1} lesz" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "hu" "Az aktualis palya meghosszabitva." 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "hu" "Palya meghosszabitasa" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "hu" "Ne valtsunk!" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "hu" "Jelenlegi palya folytatodik." 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "hu" "\"{1}\" lesz a kovetkezo palya" 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/it/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "it" "Vota per la prossima mappa!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "it" "Le votazione per scegliere la prossima mappa sono iniziate." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "it" "Le votazioni sono terminate. La prossima mappa sarà {1}. (Con {2}%% su {3} votes)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "it" "La mappa attuale è stata estesa. (Con {1}%% su {2} votes)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "it" "Estendi la mappa corrente" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "it" "Non cambiare" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "it" "La mappa continua! Il voto ha parlato! (Con {1}%% su {2} votes)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "it" "La mappa successiva sarà \"{1}\"." 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "it" "Vota nuovamente per scegliere la prossima mappa!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "it" "Numero di voti" 51 | } 52 | 53 | "Custom" 54 | { 55 | "it" "{1} (Custom)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "it" "Nessuna mappa ha ricevuto più del {1}%% di voti.\nAllora, quale mappa vincerà? Si inizia un' altra votazione!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "it" "Una nuova votazione inizierà tra: {1}s" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "it" "Attenzione! Le votazione per la prossima mappa cominceranno tra: {1}s" 71 | } 72 | 73 | "Line One" 74 | { 75 | "it" "Vota la mappa chevorresti giocare..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "it" "...e non cliccare i tasti sconsideratamente :D" 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "it" "Il voto è in corso. Riprova tra {1}s." 86 | } 87 | 88 | "Tie Vote" 89 | { 90 | "it" "Le mappe hanno raggiunto il pareggio dei voti.\nBisogna nuovamente votare!" 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/jp/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/jp/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "jp" "次のマップを投票してください!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "jp" "次のマップ投票をスタートしました。" 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "jp" "マップ投票が完了しました。次はマップは{1}です。({3}中{2}%%)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "jp" "現在のマップを延長します。({3}中{2}%%)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "jp" "現在のマップを延長" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "jp" "変更しない" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "jp" "現在のマップを延長します。({3}中{2}%%)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "jp" "次のマップを\"{1}\"に変更しました。" 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ko/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "ko" "다음 맵을 결정하기 위한 투표!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "ko" "다음 맵을 결정하기 위한 투표가 시작되었습니다." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "ko" "맵 투표가 끝났습니다. 다음 맵은 {1} 이 될 것입니다. (전체 인원 {2}명 중 {1}%%의 표를 받았습니다.)" 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "ko" "현재 맵을 더하기로 결정했습니다. (전체 인원 {2}명 중 {1}%%의 표를 받았습니다.)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "ko" "지금 맵을 더 하자" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "ko" "바꾸지 말자" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "ko" "현재 맵을 계속 합니다!(전체 인원 {2} 명의 {1}%% 의 표를 받았습니다)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "ko" "다음 맵을 \"{1}\" 로 바꾸었습니다." 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "ko" "다음 맵을 결정하기 위한 재투표!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "ko" "투표수" 51 | } 52 | 53 | "Custom" 54 | { 55 | "ko" "{1} (커스텀 맵)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "ko" "{1}%% 이상 투표를 받은 맵이 없습니다.\n다음 맵을 결정하기 위해 재투표를 합니다!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "ko" "재투표까지: {1}초" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "ko" "알립니다! 다음 맵을 결정하는 투표까지: {1}초" 71 | } 72 | 73 | "Line One" 74 | { 75 | "ko" "원하는 맵을 선택하세요..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "ko" "...그리고 아무거나 막 찍지 말고요 -_-" 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "ko" "투표가 진행 중에 있습니다. {1}초 후 다시 시도합니다." 86 | } 87 | 88 | "Tie Vote" 89 | { 90 | "ko" "{1}개 맵이 같은 투표수를 얻었습니다.\n재투표를 합니다!" 91 | } 92 | 93 | "Custom Marked" 94 | { 95 | "ko" "*{1}" 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/lv/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/lv/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "lv" "Balso par nākamo karti!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "lv" "Balsošana par nākamo karti ir sākusies." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "lv" "Balsošana par karti ir beigusies. Nākamā karte būs {1}. (Saņēma {2}%% no {3} balsīm) " 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "lv" "Patreizējās kartes laiks ir pagarināts. (Saņēma {1}%% no {2} balsīm) " 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "lv" "Pagarināt laiku patreizējā kartē" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "lv" "Nemainīt" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "lv" "Patreizējā karte turpinās! Aptauja ir beigusies! (Saņēma {1}%% no {2} balsīm)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "lv" "Nomainīja nākamo karti uz \"{1}\"." 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "en" "Vote for the next map!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "en" "Voting for next map has started." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "#format" "{1:s},{2:i},{3:i}" 16 | "en" "Map voting has finished. The next map will be {1}. (Received {2}%% of {3} votes)" 17 | } 18 | 19 | "Current Map Extended" 20 | { 21 | "#format" "{1:i},{2:i}" 22 | "en" "The current map has been extended. (Received {1}%% of {2} votes)" 23 | } 24 | 25 | "Extend Map" 26 | { 27 | "en" "Extend Current Map" 28 | } 29 | 30 | "Dont Change" 31 | { 32 | "en" "Don't Change" 33 | } 34 | 35 | "Current Map Stays" 36 | { 37 | "#format" "{1:i},{2:i}" 38 | "en" "Current map continues! The Vote has spoken! (Received {1}%% of {2} votes)" 39 | } 40 | 41 | "Changed Next Map" 42 | { 43 | "#format" "{1:s}" 44 | "en" "Changed nextmap to \"{1}\"." 45 | } 46 | 47 | "Runoff Vote Nextmap" 48 | { 49 | "en" "Runoff Vote for the next map!" 50 | } 51 | 52 | "Number Of Votes" 53 | { 54 | "en" "Number of votes" 55 | } 56 | 57 | "Custom" 58 | { 59 | "#format" "{1:s}" 60 | "en" "{1} (Custom)" 61 | } 62 | 63 | "Revote Is Needed" 64 | { 65 | "#format" "{1:i}" 66 | "en" "No map has received more than {1}%% of the vote.\nSo, which map will win? A revote is needed!" 67 | } 68 | 69 | "Revote Warning" 70 | { 71 | "#format" "{1:i}" 72 | "en" "Runoff vote will start in: {1}s" 73 | } 74 | 75 | "Vote Warning" 76 | { 77 | "#format" "{1:i}" 78 | "en" "Warning! Voting for the next map will begin in: {1}s" 79 | } 80 | 81 | "Line One" 82 | { 83 | "en" "Consider which map you want to play..." 84 | } 85 | 86 | "Line Two" 87 | { 88 | "en" "...and don't hit buttons thoughtlessly ;-)" 89 | } 90 | 91 | "Cannot Start Vote" 92 | { 93 | "#format" "{1:i}" 94 | "en" "Vote already in progress. Retrying in {1}s." 95 | } 96 | 97 | "Tie Vote" 98 | { 99 | "#format" "{1:i}" 100 | "en" "The top {1} maps had the same number of votes.\nA revote is needed!" 101 | } 102 | 103 | "Custom Marked" 104 | { 105 | "#format" "{1:s}" 106 | "en" "*{1}" 107 | } 108 | 109 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/nl/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/nl/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "nl" "Stem voor de volgende map!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "nl" "Stemmen voor de volgende map is gestart." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "nl" "Map stemmen gestopt. De volgende map wordt {1}." 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "nl" "De huidige map is verlengd." 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "nl" "Verleng huidige map" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "nl" "Niet veranderen" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "nl" "Huidige map gaat verder! De Stem heeft gesproken! (Ontvangen {1}%% van de {2} stemmen)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "nl" "Volgende map verandert naar \"{1}\"." 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/no/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/no/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "no" "Stem for det neste kartet!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "no" "Avstemning for det neste kartet har startet." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "no" "Kart-avstemningen er avsluttet. Det neste kartet vil være {1}. (Mottok {2}%% av {3} stemmer)." 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "no" "Gjeldende kart videreføres! (Mottok {1}%% av {2} stemmer)." 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "no" "Forleng gjeldende kart." 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "no" "Ikke bytt!" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "no" "Gjeldende kart videreføres! Avstemningen har talt! (Mottok {1}%% av {2} stemmer)." 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "no" "Byttet neste kart til \"{1}\"" 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/pl/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "pl" "Głosuj na następną mapę!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "pl" "Rozpoczęto głosowanie na następną mapę." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "pl" "Głosowanie na mapę zostało zakończone. Następną mapą będzie {1}. (Otrzymała {2} procent z {3} głosów) " 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "pl" "Aktualna mapa została przedłużona. (Otrzymała {1} procent z {2} głosów)" 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "pl" "Przedłuż bieżącą mapę" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "pl" "Nie Zmieniaj" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "pl" "Aktualna mapa będzie kontynuowana! (Otrzymano {1} procent z {2} głosów)" 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "pl" "Zmieniono następną mapę na: \"{1}\"." 41 | } 42 | 43 | "Runoff Vote Nextmap" 44 | { 45 | "pl" "Wybierz ponownie!" 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "pl" "Otrzymane głosy" 51 | } 52 | 53 | "Custom" 54 | { 55 | "pl" "{1} (Niestandardowa)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "pl" "Żadna mapa nie otrzymała przynajmniej {1}%% głosów.\nWięc która mapa jest zwycięzcą? Trzeba zagłosować ponownie!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "pl" "Ponowne głosowanie rozpocznie się za: {1}s\nTym razem się już zdecydujcie ;-)" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "pl" "UWAGA!!! Głosowanie na następną mapę rozpocznie się za: {1}s" 71 | } 72 | 73 | "Line One" 74 | { 75 | "pl" "Zastanów się na której mapie chcesz grać..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "pl" "...wpisując !revote możesz zmienić swój głos." 81 | } 82 | 83 | "Cannot Start Vote" 84 | { 85 | "pl" "Głosowanie w toku. Ponawiam za {1}s." 86 | } 87 | 88 | "Tie Vote" 89 | { 90 | "pl" "{1} najlepsze mapy otrzymały tę samą ilość głosów.\nPotrzeba ponownego głosowania!" 91 | } 92 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/pt/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/addons/sourcemod/translations/pt/mapchooser_extended.phrases.txt -------------------------------------------------------------------------------- /addons/sourcemod/translations/ru/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "ru" "Голосование за следующую карту." 6 | } 7 | 8 | "Runoff Vote Nextmap" 9 | { 10 | "ru" "Повторное голосование за карту." 11 | } 12 | 13 | "Nextmap Voting Started" 14 | { 15 | "ru" "Голосование за следующую карту запущено." 16 | } 17 | 18 | "Nextmap Voting Finished" 19 | { 20 | "ru" "Голосование за карту завершено. Следующей картой будет: {1}. (Получено {2}%% из {3} голосов(а))" 21 | } 22 | 23 | "Current Map Extended" 24 | { 25 | "ru" "Текущая карта была продлена. (Получено {1}%% из {2} голосов(а))" 26 | } 27 | 28 | "Extend Map" 29 | { 30 | "ru" "Продлить текущую карту." 31 | } 32 | 33 | "Dont Change" 34 | { 35 | "ru" "Не менять карту." 36 | } 37 | 38 | "Current Map Stays" 39 | { 40 | "ru" "Текущая карта не сменится! (Получено {1}%% из {2} голосов(а))" 41 | } 42 | 43 | "Changed Next Map" 44 | { 45 | "ru" "Следующая карта изменена на \"{1}\"." 46 | } 47 | 48 | "Number Of Votes" 49 | { 50 | "ru" "Количество голосов" 51 | } 52 | 53 | "Custom" 54 | { 55 | "ru" "{1} (Случайная)" 56 | } 57 | 58 | "Revote Is Needed" 59 | { 60 | "ru" "Ни одна карта не получила более, чем {1}%% голосов(а).\nИтак, какая карта будет следующей? Приготовьтесь к повторному голосованию!" 61 | } 62 | 63 | "Revote Warning" 64 | { 65 | "ru" "Повторное голосование начнётся через: {1}s" 66 | } 67 | 68 | "Vote Warning" 69 | { 70 | "ru" "Внимание! Голосование за следующую карту начнётся через: {1}s" 71 | } 72 | 73 | "Line One" 74 | { 75 | "ru" "Выбери, какая карта будет следующей..." 76 | } 77 | 78 | "Line Two" 79 | { 80 | "ru" "...и не клацай кнопки,не подумав ;-)" 81 | } 82 | "Cannot Start Vote" 83 | { 84 | "#format" "{1:i}" 85 | "ru" "Голосование уже в процессе. Попробуйте через {1} с." 86 | } 87 | 88 | } "Tie Vote" 89 | { 90 | "#format" "{1:i}" 91 | "ru" "{1} карты набрали одинаковое количество голосов.\nНеобходимо повторное голосование !" 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/sv/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/sv/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "sv" "Rösta för nästa bana!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "sv" "Röstning om nästa bana har börjat." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "sv" "Röstningen om banan har avslutats. Nästa bana kommer att bli {1}. (Fick {2}%% av {3} röster) " 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "sv" "Den nuvarande banan har förlängts. (Fick {1}%% av {2} röster) " 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "sv" "Förläng nuvarande bana" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "sv" "Byt inte" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "sv" "Nuvarande banan fortsätter! Röstningen har talat! (Fick {1}%% av {2} röster) " 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "sv" "Bytta nästa bana till \"{1}\". " 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/tr/incomplete.txt: -------------------------------------------------------------------------------- 1 | Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning", 2 | "Line One", "Line Two", "Cannot Start Vote", and "Tie Vote" -------------------------------------------------------------------------------- /addons/sourcemod/translations/tr/mapchooser_extended.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Vote Nextmap" 4 | { 5 | "tr" "Sonraki harita için oy ver!" 6 | } 7 | 8 | "Nextmap Voting Started" 9 | { 10 | "tr" "Sonraki harita için oylama başladı." 11 | } 12 | 13 | "Nextmap Voting Finished" 14 | { 15 | "tr" "Harita oylaması sona erdi. Sıradaki harita {1} olacak. ({3} oyun %%{2}'i alındı) " 16 | } 17 | 18 | "Current Map Extended" 19 | { 20 | "tr" "Geçerli harita uzatıldı. ({2} oyun %%{1}'i alındı) " 21 | } 22 | 23 | "Extend Map" 24 | { 25 | "tr" "Geçerli Haritayı Uzat" 26 | } 27 | 28 | "Dont Change" 29 | { 30 | "tr" "Değiştirme" 31 | } 32 | 33 | "Current Map Stays" 34 | { 35 | "tr" "Geçerli harita devam ediyor! Oylama konuştu! ({2} oyun %%{1}'i alındı) " 36 | } 37 | 38 | "Changed Next Map" 39 | { 40 | "tr" "Sıradaki harita \"{1}\" olarak değiştirildi." 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /sound_sets/hl1/addons/sourcemod/configs/mapchooser_extended/sounds/hl1.cfg: -------------------------------------------------------------------------------- 1 | "MapchooserSoundsList" 2 | { 3 | "hl1" 4 | { 5 | "counter" 6 | { 7 | "1" 8 | { 9 | "sound" "mapchooser/hl1/one.mp3" 10 | } 11 | "2" 12 | { 13 | "sound" "mapchooser/hl1/two.mp3" 14 | } 15 | "3" 16 | { 17 | "sound" "mapchooser/hl1/three.mp3" 18 | } 19 | "4" 20 | { 21 | "sound" "mapchooser/hl1/four.mp3" 22 | } 23 | "5" 24 | { 25 | "sound" "mapchooser/hl1/five.mp3" 26 | } 27 | "6" 28 | { 29 | "sound" "mapchooser/hl1/six.mp3" 30 | } 31 | "7" 32 | { 33 | "sound" "mapchooser/hl1/seven.mp3" 34 | } 35 | "8" 36 | { 37 | "sound" "mapchooser/hl1/eight.mp3" 38 | } 39 | "9" 40 | { 41 | "sound" "mapchooser/hl1/nine.mp3" 42 | } 43 | "11" 44 | { 45 | "sound" "mapchooser/hl1/ten_seconds.mp3" 46 | } 47 | "20" 48 | { 49 | "sound" "mapchooser/hl1/twenty_seconds.mp3" 50 | } 51 | "30" 52 | { 53 | "sound" "mapchooser/hl1/thirty_seconds.mp3" 54 | } 55 | "60" 56 | { 57 | "sound" "mapchooser/hl1/sixty_seconds.mp3" 58 | } 59 | } 60 | "vote start" 61 | { 62 | "sound" "mapchooser/hl1/startyourvoting.mp3" 63 | } 64 | "vote end" 65 | { 66 | "sound" "mapchooser/hl1/endofvote.mp3" 67 | } 68 | "vote warning" 69 | { 70 | "sound" "mapchooser/hl1/bell_warning.mp3" 71 | } 72 | "runoff warning" 73 | { 74 | "sound" "mapchooser/hl1/gman_choose2.mp3" 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/bell_warning.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/bell_warning.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/bell_warning.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/bell_warning.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/eight.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/eight.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/eight.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/eight.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/endofvote.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/endofvote.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/five.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/five.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/five.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/five.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/four.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/four.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/four.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/four.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/gman_choose2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/gman_choose2.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/gman_choose2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/gman_choose2.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/nine.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/nine.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/nine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/nine.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/one.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/one.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/one.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/one.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/seven.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/seven.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/seven.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/seven.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/six.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/six.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/six.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/six.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/sixty_seconds.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/sixty_seconds.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/sixty_seconds.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/sixty_seconds.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/startyourvoting.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/startyourvoting.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/ten_seconds.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/ten_seconds.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/ten_seconds.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/ten_seconds.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/thirty_seconds.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/thirty_seconds.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/thirty_seconds.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/thirty_seconds.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/three.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/three.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/three.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/three.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/twenty_seconds.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/twenty_seconds.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/twenty_seconds.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/twenty_seconds.wav -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/two.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/two.mp3 -------------------------------------------------------------------------------- /sound_sets/hl1/sound/mapchooser/hl1/two.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/hl1/sound/mapchooser/hl1/two.wav -------------------------------------------------------------------------------- /sound_sets/tf/addons/sourcemod/configs/mapchooser_extended/sounds/tf.cfg: -------------------------------------------------------------------------------- 1 | "MapchooserSoundsList" 2 | { 3 | "tf" 4 | { 5 | "counter" 6 | { 7 | "1" 8 | { 9 | "sound" "mapchooser/tf2/announcer_begins_1sec.mp3" 10 | "builtin" "vo/announcer_begins_1sec.mp3" 11 | "event" "Announcer.RoundBegins1Seconds" 12 | } 13 | "2" 14 | { 15 | "sound" "mapchooser/tf2/announcer_begins_2sec.mp3" 16 | "builtin" "vo/announcer_begins_2sec.mp3" 17 | "event" "Announcer.RoundBegins2Seconds" 18 | } 19 | "3" 20 | { 21 | "sound" "mapchooser/tf2/announcer_begins_3sec.mp3" 22 | "builtin" "vo/announcer_begins_3sec.mp3" 23 | "event" "Announcer.RoundBegins3Seconds" 24 | } 25 | "4" 26 | { 27 | "sound" "mapchooser/tf2/announcer_begins_4sec.mp3" 28 | "builtin" "vo/announcer_begins_4sec.mp3" 29 | "event" "Announcer.RoundBegins4Seconds" 30 | } 31 | "5" 32 | { 33 | "sound" "mapchooser/tf2/announcer_begins_5sec.mp3" 34 | "builtin" "vo/announcer_begins_5sec.mp3" 35 | "event" "Announcer.RoundBegins5Seconds" 36 | } 37 | "10" 38 | { 39 | "sound" "mapchooser/tf2/announcer_dec_missionbegins10s01.mp3" 40 | "builtin" "vo/announcer_dec_missionbegins10s01.mp3" 41 | } 42 | "30" 43 | { 44 | "sound" "mapchooser/tf2/announcer_dec_missionbegins30s01.mp3" 45 | "builtin" "vo/announcer_dec_missionbegins30s01.mp3" 46 | } 47 | } 48 | "vote start" 49 | { 50 | "sound" "mapchooser/tf2/vote_started.mp3" 51 | "event" "Vote.Created" 52 | "builtin" "ui/vote_started.wav" 53 | } 54 | "vote end" 55 | { 56 | "sound" "mapchooser/tf2/vote_success.mp3" 57 | "event" "Vote.Passed" 58 | "builtin" "ui/vote_success.wav" 59 | } 60 | "vote warning" 61 | { 62 | "sound" "mapchooser/tf2/announcer_dec_missionbegins60s03.mp3" 63 | "builtin" "vo/announcer_dec_missionbegins60s03.mp3" 64 | } 65 | "runoff warning" 66 | { 67 | "sound" "mapchooser/tf2/vote_failure.mp3" 68 | "event" "Vote.Failed" 69 | "builtin" "ui/vote_failure.wav" 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_begins_1sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_begins_1sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_begins_2sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_begins_2sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_begins_3sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_begins_3sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_begins_4sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_begins_4sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_begins_5sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_begins_5sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_dec_missionbegins10s01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_dec_missionbegins10s01.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_dec_missionbegins30s01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_dec_missionbegins30s01.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/announcer_dec_missionbegins60s03.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/announcer_dec_missionbegins60s03.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/vote_failure.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/vote_failure.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/vote_started.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/vote_started.mp3 -------------------------------------------------------------------------------- /sound_sets/tf/sound/mapchooser/tf2/vote_success.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf/sound/mapchooser/tf2/vote_success.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/addons/sourcemod/configs/mapchooser_extended/sounds/tf.cfg: -------------------------------------------------------------------------------- 1 | "MapchooserSoundsList" 2 | { 3 | "tf" 4 | { 5 | "counter" 6 | { 7 | "1" 8 | { 9 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_begins_01sec.mp3" 10 | "builtin" "vo/halloween_merasmus/sf14_merasmus_begins_01sec.mp3" 11 | "event" "Merasmus.RoundBegins1Seconds" 12 | } 13 | "2" 14 | { 15 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_begins_02sec.mp3" 16 | "builtin" "vo/halloween_merasmus/sf14_merasmus_begins_02sec.mp3" 17 | "event" "Merasmus.RoundBegins2Seconds" 18 | } 19 | "3" 20 | { 21 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_begins_03sec.mp3" 22 | "builtin" "vo/halloween_merasmus/sf14_merasmus_begins_03sec.mp3" 23 | "event" "Merasmus.RoundBegins3Seconds" 24 | } 25 | "4" 26 | { 27 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_begins_04sec.mp3" 28 | "builtin" "vo/halloween_merasmus/sf14_merasmus_begins_04sec.mp3" 29 | "event" "Merasmus.RoundBegins4Seconds" 30 | } 31 | "5" 32 | { 33 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_begins_05sec.mp3" 34 | "builtin" "vo/halloween_merasmus/sf14_merasmus_begins_05sec.mp3" 35 | "event" "Merasmus.RoundBegins5Seconds" 36 | } 37 | } 38 | "vote start" 39 | { 40 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_minigame_fp_reveal07.mp3" 41 | "builtin" "vo/halloween_merasmus/sf14_merasmus_minigame_fp_reveal07.mp3" 42 | } 43 | "vote end" 44 | { 45 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_minigame_overtime_03.mp3" 46 | "builtin" "vo/halloween_merasmus/sf14_merasmus_minigame_overtime_03.mp3" 47 | } 48 | "vote warning" 49 | { 50 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_round_start_short_01.mp3" 51 | "builtin" "vo/halloween_merasmus/sf14_merasmus_round_start_short_01.mp3" 52 | } 53 | "runoff warning" 54 | { 55 | "sound" "mapchooser/tf2_merasmus/sf14_merasmus_necromasher_miss_10.mp3" 56 | "builtin" "vo/halloween_merasmus/sf14_merasmus_necromasher_miss_10.mp3" 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_01sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_01sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_02sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_02sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_03sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_03sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_04sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_04sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_05sec.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_begins_05sec.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_minigame_fp_reveal07.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_minigame_fp_reveal07.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_minigame_overtime_03.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_minigame_overtime_03.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_necromasher_miss_10.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_necromasher_miss_10.mp3 -------------------------------------------------------------------------------- /sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_round_start_short_01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powerlord/sourcemod-mapchooser-extended/1c65609697b21cd4d71e9bf1947158e72d4f7800/sound_sets/tf_merasmus/sound/mapchooser/tf2_merasmus/sf14_merasmus_round_start_short_01.mp3 --------------------------------------------------------------------------------