diff --git a/.gitignore b/.gitignore index 9e21902..510efbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,11 @@ +amxmodx/data +amxmodx/logs amxmodx/plugins +amxmodx/scripting/amxmod_compat +amxmodx/scripting/backup +amxmodx/scripting/compiled +amxmodx/scripting/testsuite amxmodx/scripting/*.amxx amxmodx/scripting/compiled/*.amxx amxmodx/configs/sql.cfg -amxmodx/configs/kz/kreedz.cfg \ No newline at end of file +amxmodx/configs/kz/kreedz.cfg diff --git a/amxmodx/ACKNOWLEDGEMENTS.txt b/amxmodx/ACKNOWLEDGEMENTS.txt new file mode 100644 index 0000000..d318e93 --- /dev/null +++ b/amxmodx/ACKNOWLEDGEMENTS.txt @@ -0,0 +1,165 @@ +---------------------------------- +Pawn Abstract Machine and Compiler +---------------------------------- +Copyright (c) ITB CompuPhase, 1997-2005 + +This software is provided "as-is", without any express or implied warranty. +In no event will the authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in + a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +-------------------------------------------------------------- +zlib, as used in the AMX Mod X Pawn compiler and plugin loader +-------------------------------------------------------------- +Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +--------------------------------- +PCRE, as used in the Regex module +--------------------------------- +Copyright (c) 1997-2014 University of Cambridge + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +You may obtain a copy of the license at + http://www.pcre.org/licence.txt + +----------------------------------------- +libmaxminddb, as used in the GeoIP module +----------------------------------------- +Copyright 2013-2014 MaxMind, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +-------------------------------------------------------------- +Portable C++ Hashing Library, as used in AMX Mod X Core module +-------------------------------------------------------------- +Copyright (c) 2014 Stephan Brumme + +All source code published on http://create.stephan-brumme.com +and its sub-pages is licensed similar to the zlib license: + +This software is provided 'as-is', without any express or implied warranty. +In no event will the author be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + + * The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. + * If you use this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + * Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + +----------------------------------------------------------------- +Portable C UTF-8 Rewind Library, as used in AMX Mod X Core module +----------------------------------------------------------------- +Copyright (C) 2014-2016 Quinten Lansu + +Licensed under The MIT License. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------------------------------------------------------------- +Parson, as used in the JSON module +-------------------------------------------------------------- +Copyright (c) 2012 - 2017 Krzysztof Gabis + +Licensed under The MIT License. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/amxmodx/GPLv2.txt b/amxmodx/GPLv2.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/amxmodx/GPLv2.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/amxmodx/GPLv3.txt b/amxmodx/GPLv3.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/amxmodx/GPLv3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/amxmodx/LICENSE.txt b/amxmodx/LICENSE.txt new file mode 100644 index 0000000..197125f --- /dev/null +++ b/amxmodx/LICENSE.txt @@ -0,0 +1,34 @@ +AMX MOD X LICENSE INFORMATION +VERSION: AUGUST-04-2014 + +AMX Mod X is licensed under the GNU General Public License, version 3, or (at +your option) any later version. + +As a special exception, the AMX Mod X Development Team gives permission to link +the code of this program with the Half-Life Game Engine ("HL Engine") and +Modified Game Libraries ("MODs") developed via the Half-Life 1 SDK as full +replacements for Valve games. You must obey the GNU General Public License in +all respects for all other code used other than the HL Engine and MODs. This +extension, at your option, may also be granted to works based on AMX Mod X. + +As an additional special exception to the GNU General Public License 3.0, +AlliedModders LLC permits dual-licensing of DERIVATIVE WORKS ONLY (that is, +Pawn/AMX Mod X Plugins and AMX Mod X Modules, or any software built from the AMX +Mod X header files) under the GNU General Public License version 2 "or any +higher version." As such, you may choose for your derivative work(s) to be +compatible with the GNU General Public License version 2 as long as it is also +compatible with the GNU General Public License version 3, via the "or any higher +version" clause. This is intended for compatibility with other software. + +As a final exception to the above, any derivative works created prior to this +date (August 4, 2014) may be exclusively licensed under the GNU General Public +License version 2 (without an "or any higher version" clause) if and only if the +work was already GNU General Public License 2.0 exclusive. This clause is +provided for backwards compatibility only. + +A copy of the GNU General Public License 2.0 is available in GPLv2.txt. +A copy of the GNU General Public License 3.0 is available in GPLv3.txt. + +Some components of AMX Mod X use a license other than the GNU General Public +License. You must also adhere to these additional licenses in all respects. See +ACKNOWLEDGEMENTS.txt for further details. diff --git a/amxmodx/configs/allmaps.txt b/amxmodx/configs/allmaps.txt new file mode 100644 index 0000000..3205bdc --- /dev/null +++ b/amxmodx/configs/allmaps.txt @@ -0,0 +1,322 @@ +ins_blueline +mad_tomb2 +ladder_0logic +dyd_hb_betty_k +bkz_junglebhop +kzlt_arabhop +kz_indusrun +kzex_earthruins +jail_logo +kzeed_bhop_madness +kz_heat +kzsca_watertemple +kek_google +kzro_island +bkz_bhopaztec +imkz_tsfh +kzru_Mam6ahop +bhop_dustzone +kzro_bhopbl0ck +bhkz_bronzebhop +dyd_toonblock +bkz_goldbhop +kz-endo_bikinihop +ksz_zuma +bk_icerock +fu_bawhop +mto_bhops +d2_mario_bhop +dyd_bhop +bkz_dqvolski_most +cypress_p0burkan +kzua_zp_hamunaptra_x +bkzgt_aasault +smk_factory +bk_bhop +doze_ljrun +kz_6fd_volcano +kz_ins_ancientgardens +clintmo_bhoptoon +mls_greenstyle_bh +kz_kzse_dustbhop_h +etl_spacebhop +kzpf_deathless_x +kz_kzro_roscbhop +bhop_aeonflux +bkz_goldbhop_v2 +risk_sector +py_mix +kz_tkz_desertbl00ks +risk_bhop_bunny +slD_bside_nightblock +kg_duckhops_flawless +kz_deathvalley +kz_xj_communitybhop +BBbhop +kz_j2s_icevalley +cah_lost +kz_nix +bhop_blocks +kz_cg_xtremedesert +kz_kzro_winter +kzru_spacehop +pprn_violetta_x +cg_wildwesthop +gbc_towers2 +kzsca_burrow +cg_cbblebhop +kzro_jaashsbhop +kz_man_bhopsnow +gayl0rd_bhop +cypress_volcancliff +etl_forsakenblock +kz_man_neighbourhood +coma_X +kzro_mountainbhop +kaspek_caverna_v1 +daza_colorswitch +ham_bricks +kz_kzsca_bhopindustry +kz_j2s_cupblock +fu_replayhop +kz_j2s_westbl0ck +kz_longjumps2 +pixelhop +bhop_fabrit +kzua_de_portal +firs_room_x +hb_lambdaaa +bhop_its_2caves +j2s_autumn +bhop_platinum +kzla_cdbanana +kzua_mk_illumina_h +hfr_302 +ftw_deathzone +kzls_kodash +bkz_noob +kzsca_bagdad +bhop_tropic_h +j2s_sandland +1324_svalley +bkz_forestrace +kzsca_watertemple2 +rkz_easy_bhop_cross_runner +kzls_smile +hb_patchouli +kz_nobkz_factoryrun +kzls_bhop_china +smk_kzsca_factory +dyd_insulate +chk_cruel +kzy_juhxbhop +kzsca_snakebhop +kzro_tits +kz_kzdk_templebhop_h +fu_plainhop +kzse_bhopblock +bkz_bhopvalley +stf_creepytemple +qsk_azure +kz_synergy +fu_devhops +kzra_crystal_palace +nobkz_minimal +mad_bhopit +cg_coldbhop +hama_bricksv2 +kz_waterplant +gbc_randombhop +kz_cellblock +j2s_4tunnels +bhop_perfect2012 +kz_exodus_hard +kz_world +fb_ultimateclimb +kz_kzlt_dementia +radon_desertpassage +kzru_technology_x +kz_ascension_b8 +bhop_mz_chaosmedia90 +kz_wild +kzlt_dark_vault +daza_cobkz_inducility +hb_Creep +ytt_wow_mix +cd_bhop +kzra_stonebhop2 +speed_ytt_castle +bkz_whatisthis +cg_coldbhop_v2 +kzra_stonebhop +kz_kzdk_delianshop +kzdk_explorer_x +kzua_mk_illumina +av_degyptianez +kz_shrubhop_ez +kzarg_bhopcircuit +clintmo_bhopwarehouse +holy_lame +hb_inj3ct0r +bhop_gamebox +jro_goldbhop +dyd_brick +3T_xiaocaibi +kz_cg_venice +rr_inside^outside +1324_hellhouse +kz_rd_oldmine +clintmo_bhopbarrels +bhop_brainiac +cypress_bhoprun +kz-endo_toonbhopz +kzray_rocky-bhop +kz_kzsca_escape +mls_icefall_bhop +ce_house_3ways +fof_dale +kz_facility +4U_factory_wjs +ivns_arcadium +kzra_greencave +kzcn_2012 +bkz_toonworld +kz_pacman +bhop_cave +Bhop_Blackjump +notkz_amazing +kzz_bhop +bw_pcjump +kz_bkz_egyptbhop +hb_PurpLeRainN +kz_cg_lavacliff +kzua_zp_godroom_h +bkm_problock +bhop_slackibira +sn_dustown +k_sun +holy_strafemaster +cg_d2block_h +smk_evergreen +fof_chillbhop +bhop_astro +ckz_corsair +kzblt_dx_blueshadow2 +kz_dbh_pipehop +kzbr_hii_cartoonbhop +nz_playstation +kz_canyon +kz_shrubhop_h +kz_kzse_toonworld +bhop_cave2 +kz_kzlt_femtobhop +kzex_darksiders +mh_bhopljs_h +j2s_4floors +daza_dimensionjumper +bkz_volcanobhop +mad_tomb +bhop_terrainhop +kzarg_lostrome +hb_DotAntipro +kz_kzfr_rabbithighway +cg_arizonabhop +bhop_darkstars +ugly_stairstoon +kz_ins_bhoptown +kztw_abyss_2014 +cosy_cavebhop +fs_streetjump +gg_jackson2 +sn_ezycity +bhop_avantura +rd_jump_house +kz_undergroundvillage +kz_giantbean_b15 +kz-endo_carrington +daza_cityblock +kz_megabhop_hard +kz_synergy_x2 +chip_bhopnoob_x +kzra_worlds +kz_kz-endo_portal +hfr_descent_h +bn_tombbhop +fu_bhop +kz-endo_topspeed +kzra_stoneishbhop +kz_cxg_jekyll +bkz_wallblock +cLt_firstbhop +klz_sherbrooke +kz-endo_blue +dyd_onlime +prochallenge_bhop +kzua_zp_cellaregypt +kzro_brickybhop +hm_crazystairs +kz_kzdk_covebhop +kz_satomi +kzblt_dx_mercy +bla_reactorhop +bhop_lego +kz_adventure +qsk_still +risk_snowcastle +kz_anubis +rush_adventure +bhop_kaninpuff +hit_canyonbhop +fu_frosty +kz_kzarg_catacombsbhop +cg_lighthops +rush_countless +ytt_light_stars +ml_monsterbhop +kzra_bhopmemories +kz_starwars_deeja +notkz_bhopcolour +kzsk_cubeblock +bhop_lyy_egypt +kzm_cityhops +kzro_excitedbhop +kz_owensvalley +kz_kzlv_wanderer +cnd_bairesbhop +kzra_somecaves +kz_bkz_tropicbhop +fof_utopia +bhop_colorhop +cosy_marioworld +mck_vudu +bhop_csr +cobkz_toonworld +kzsca_heaven +kz_synergy_x +fof_32 +kzeed_prohop +kzarg_cellhop +fu_sane +bhop_jbg_grass +bhop_reys +ins_hlteaser +mls_floppytown_bh +kz_kzsca_still +kz-endo_congo +rvp_tundra-bhop +kz_radium +kzro_gohome +bkz_lostbase +kzr_greybhop +kzua_goldbhop_x +bhop_temple +kz_excavation +mls_stairsbhop +nobkz_mst_honduras_h +kzsk_rocksland +dr0_lost_sector +pro_kzcn_blow2 +holy_somethingalamode +kzarg_ih_sandhop +kz_hopez +bhop_c21 diff --git a/amxmodx/configs/amxx.cfg b/amxmodx/configs/amxx.cfg new file mode 100755 index 0000000..6ff891c --- /dev/null +++ b/amxmodx/configs/amxx.cfg @@ -0,0 +1,255 @@ +// AMX Mod X Configuration File +echo Executing AMX Mod X Configuration File + +// Default access for all non admin players (see users.ini for access details) +// +// Default value: "z" +amx_default_access "z" + +// Name of setinfo which should store a password on a client (you should change this) +// Note: Always prefix the field with an underscore (aka: "_") +// (Example: setinfo _pw "password") +// +// Default value: "_pw" +amx_password_field "_pw" + +// Mode of logging to a server +// 0 - disable logging, players won't be checked (and access won't be set) +// 1 - normal mode which obey flags set in accounts +// 2 - kick all players not on list +// +// Default value: 1 +amx_mode 1 + +// Show admins activity +// 0 - disabled +// 1 - show without admin name +// 2 - show with name +// 3 - show name only to admins, hide name from normal users +// 4 - show name only to admins, show nothing to normal users +// 5 - hide name only to admins, show nothing to normal users +// +// Default value: 2 +amx_show_activity 2 + +// Frequency in seconds and text of scrolling message +// +// Default value: "Welcome to %hostname% -- This server is using AMX Mod X" 600 +amx_scrollmsg "Welcome to %hostname% -- This server is using AMX Mod X" 600 + +// Center typed colored messages (last parameter is a color in RRRGGGBBB format) +// +// Default values: "Welcome to %hostname%" "000255100" +// "This server is using AMX ModX\nVisit http://www.amxmodx.org" "000100255" +amx_imessage "Welcome to %hostname%" "000255100" +amx_imessage "This server is using AMX Mod X\nVisit http://www.amxmodx.org" "000100255" + +// Frequency in seconds of colored messages +// +// Default value: 180 +amx_freq_imessage 180 + +// Ban times for the main ban menu (amx_banmenu) +// Use 0 for permanent ban +// Default values: 0 5 10 15 30 45 60 +amx_plmenu_bantimes 0 5 10 15 30 45 60 + +// Max temporary ban time (admins with ADMIN_BAN_TEMP access can't ban more than this time) +// time in minutes, 60 is 1 hour, 120 is 2 hours, 1440 is 1 day, and 10080 is 1 week +// Default value: 4320 aka 3 days +amx_tempban_maxtime 4320 + +// Slap damage amounts for the main slap menu (amx_slapmenu) +// Slay is automaticall inserted as the last option +// Default values: 0 1 5 +amx_plmenu_slapdmg 0 1 5 + +// Set in seconds how fast players can chat (chat-flood protection) +// +// Default value: 0.75 +amx_flood_time 0.75 + +// Amount of slots to reserve. +// +// Default value: 0 +amx_reservation 0 + +// If you set this to 1, you can hide slots on your server. +// If server "full" of public slots and slots hidden, you must manually connect with connect console command +// +// Default value: 0 +amx_hideslots 0 + +// Displaying of time remaining +// a - display white text on bottom +// b - use voice +// c - don't add "remaining" (only in voice) +// d - don't add "hours/minutes/seconds" (only in voice) +// e - show/speak if current time is less than this set in parameter +// +// Default value: "ab 1200" "ab 600" "ab 300" "ab 180" "ab 60" "bcde 11" +amx_time_display "ab 1200" "ab 600" "ab 300" "ab 180" "ab 60" "bcde 11" + +// Announce "say thetime" and "say timeleft" with voice, set to 0 to disable. +// +// Default value: 1 +amx_time_voice 1 + +// Display who votes for what option, set to 0 to disable, 1 to enable. +// +// Default value: 1 +amx_vote_answers 1 + +// Some ratios for voting success + +// Default value: 0.40 +amx_votekick_ratio 0.40 + +// Default value: 0.40 +amx_voteban_ratio 0.40 + +// Default value: 0.40 +amx_votemap_ratio 0.40 + +// Default value: 0.02 +amx_vote_ratio 0.02 + +// Max. time to which map can be extended +// +// Default value: 90 +amx_extendmap_max 90 + +// Step for each extending +// +// Default value: 15 +amx_extendmap_step 15 + +// Server language in ISO 639-1 format +// Please see data/lang/languages.txt file for a list of supported languages +// +// Default value: en +amx_language "en" + +// If you set this to 0, clients cannot chose their language, instead they use +// whatever language the server is configured to use. +// +// Default value: 1 +amx_client_languages 1 + +// If you set this to 0, clients will not see a message about amx_langmenu when they join the server +// +// Default value: 1 +amx_language_display_msg 1 + +// If you set this to 0, clients will not see a message about amx_help when they join the server +// +// Default value: 1 +amx_help_display_msg 1 + +// Time to wait (in seconds) before displaying a message about amx_help to a client once joined the server +// +// Default value: 15 +amx_help_display_msg_time 15 + +// Amount of commands per amx_help page +// +// Default value: 10 +amx_help_amount_per_page 10 + +// Plugin Debug mode +// 0 - No debugging (garbage line numbers) +// 1 - Plugins with "debug" option in plugins.ini are put into debug mode +// 2 - All plugins are put in debug mode +// Note - debug mode will affect JIT performance +// +// Default value: 1 +amx_debug 0 + +// Plugin MultiLingual Debug +// To debug a language put its 2 letter code between quotes ("en", "de", etc) +// "" means disabled +// +// Default value: "" +amx_mldebug "" + +// +// Beginning of Counter-Strike package specific configurations. +// + +// Rank mode +// 0 - by nick +// 1 - by authid +// 2 - by ip +// +// Default value: 1 +csstats_rank 1 + +// Max size of the stats file +// +// Default value: 3500 +csstats_maxsize 3500 + +// Whether or not to rank bots with csstats - set to 1 to rank bots, 0 otherwise. +// +// Default value: 0 +csstats_rankbots 0 + +// Duration of HUD-statistics +// +// Default value: 12.0 +amx_statsx_duration 12.0 + +// HUD-statistics display limit relative round freeze end +// Negative time will clear the HUD-statstics before the round freeze time has ended +// +// Default value: -2.0 +amx_statsx_freeze -2.0 + +// Sets whether Restrict Weapons plugin should use a configuration file per map or or not. +// If enabled, the file format is: weaprest_mapname.ini (e.g. weaprest_de_dust.ini). +// - +// Default value: 0 +amx_restrmapsettings 0 + +sv_airaccelerate 100 + +sv_downloadurl "https://cs.f0.gg/cstrike" +sv_allowdownload 1 +sv_allowupload 1 + +mp_round_infinite 1 +mp_infinite_ammo 1 +mp_auto_join_team 1 +mp_autokick 0 +humans_join_team CT +mp_scoreboard_showhealth -1 +mp_scoreboard_showmoney -1 +mp_scoreboard_showdefkit 0 + +sys_timing 1 // disables|enables plugin. Recommended: keep a base sys_tic in mapchangecfgfile. +sys_sleep 100 // Tic hibernation rate. The tic when there are 0 players. +sys_quota 2000 // Tic rate quota. The tic added per connected player. + +// specinfo +si_enabled 1 +si_list_enabled 1 +si_keys_enabled 1 +si_list_default 1 +si_keys_default 1 +si_immunity 1 + +// rtv +amx_emptymap "ml_monsterbhop" +amx_extendmap_max 90 +amx_extendmap_step 15 +amx_idletime 5 +amx_show_activity 2 +amx_staytime 300 +amx_vote_answers 1 +dmap_strict 0 +emptymap_allowed 0 +enforce_timelimit 0 +mp_timelimit 30 +nominations_allowed 1 +weapon_delay 1 +dmap_rtvwait 0 diff --git a/amxmodx/configs/clcmds.ini b/amxmodx/configs/clcmds.ini new file mode 100755 index 0000000..4de0283 --- /dev/null +++ b/amxmodx/configs/clcmds.ini @@ -0,0 +1,17 @@ +; Menu configuration file +; File location: $moddir/addons/amxmodx/configs/clcmds.ini +; To use with Players Menu plugin + +; NOTE: By default in all settings the access level is set to "u". +; However you can change that, to limit the access to some settings. + +; Client Commands Menu: ; < description > < command > < flags > < access level > +; "a" - execute from server console +; "b" - execute from admin console +; "c" - execute on selected player +; "d" - back to menu when executed + +"Kick player" "amx_kick #%userid%" "b" "u" +"Slay player" "amx_slay #%userid%" "bd" "u" +"Slap with 1 dmg." "amx_slap #%userid% 1" "bd" "u" +"Ban for 5 minutes" "amx_ban #%userid% 5" "b" "u" diff --git a/amxmodx/configs/cmdaccess.ini b/amxmodx/configs/cmdaccess.ini new file mode 100644 index 0000000..b1a76e0 --- /dev/null +++ b/amxmodx/configs/cmdaccess.ini @@ -0,0 +1,126 @@ +; This file will store the commands used by plugins, and their access level +; To change the access of a command, edit the flags beside it and then +; change the server's map. +; +; Example: If I wanted to change the amx_slap access to require +; RCON access (flag "l") I would change this: +; "amx_slap" "e" ; admincmd.amxx +; To this: +; "amx_slap" "l" ; admincmd.amxx +; +; To disable a specific command from being used with the command manager +; and to only use the plugin-specified access set the flag to "!" +; +; NOTE: The plugin name at the end is just for reference to what plugin +; uses what commands. It is ignored. + +"amx_reloadadmins" "h" ; admin_sql.amxx +"amx_addadmin" "l" ; admin_sql.amxx +"amx_kick" "c" ; admincmd.amxx +"amx_ban" "d" ; admincmd.amxx +"amx_banip" "d" ; admincmd.amxx +"amx_addban" "d" ; admincmd.amxx +"amx_unban" "d" ; admincmd.amxx +"amx_slay" "e" ; admincmd.amxx +"amx_slap" "e" ; admincmd.amxx +"amx_leave" "c" ; admincmd.amxx +"amx_pause" "g" ; admincmd.amxx +"amx_who" "y" ; admincmd.amxx +"amx_cvar" "g" ; admincmd.amxx +"amx_plugins" "y" ; admincmd.amxx +"amx_modules" "y" ; admincmd.amxx +"amx_map" "f" ; admincmd.amxx +"amx_cfg" "h" ; admincmd.amxx +"amx_nick" "e" ; admincmd.amxx +"amx_last" "d" ; admincmd.amxx +"amx_rcon" "l" ; admincmd.amxx +"amx_showrcon" "l" ; admincmd.amxx +"amx_help" "" ; adminhelp.amxx +"amx_setlang" "h" ; multilingual.amxx +"amx_langmenu" "" ; multilingual.amxx +"amxmodmenu" "u" ; menufront.amxx +"amx_menu" "" ; menufront.amxx +"amx_cmdmenu" "u" ; cmdmenu.amxx +"amx_cfgmenu" "u" ; cmdmenu.amxx +"amx_speechmenu" "u" ; cmdmenu.amxx +"amx_cvarmenu" "g" ; cmdmenu.amxx +"amx_kickmenu" "c" ; plmenu.amxx +"amx_banmenu" "d" ; plmenu.amxx +"amx_slapmenu" "e" ; plmenu.amxx +"amx_teammenu" "m" ; plmenu.amxx +"amx_clcmdmenu" "m" ; plmenu.amxx +"amx_teleportmenu" "h" ; telemenu.amxx +"amx_mapmenu" "f" ; mapsmenu.amxx +"amx_votemapmenu" "j" ; mapsmenu.amxx +"amx_plugincvarmenu" "g" ; pluginmenu.amxx +"amx_plugincmdmenu" "u" ; pluginmenu.amxx +"amx_say" "i" ; adminchat.amxx +"amx_chat" "i" ; adminchat.amxx +"amx_psay" "i" ; adminchat.amxx +"amx_tsay" "i" ; adminchat.amxx +"amx_csay" "i" ; adminchat.amxx +"amx_votemap" "j" ; adminvote.amxx +"amx_votekick" "j" ; adminvote.amxx +"amx_voteban" "j" ; adminvote.amxx +"amx_vote" "j" ; adminvote.amxx +"amx_cancelvote" "j" ; adminvote.amxx +"amx_pausecfg" "h" ; pausecfg.amxx +"amx_pausecfgmenu" "h" ; pausecfg.amxx +"amx_off" "h" ; pausecfg.amxx +"amx_on" "h" ; pausecfg.amxx +"kz_mpbhop" "h" ; mpbhop.amxx +"kz_mpbhop_entitytouch" "h" ; mpbhop.amxx +"kz_safe_inform" "h" ; mpbhop.amxx +"kz_mpbhopmenu" "h" ; mpbhop.amxx +"kz_showblocks" "h" ; mpbhop.amxx +"+hook" "c" ; prokreedz.amxx +"-hook" "c" ; prokreedz.amxx +"kz_hook" "c" ; prokreedz.amxx +"mapm_debug" "f" ; mapmanager.amxx +"mapm_startvote" "f" ; mapmanager.amxx +"mapm_stopvote" "f" ; mapmanager.amxx +"gal_startvote" "f" ; galileo.amxx +"gal_cancelvote" "f" ; galileo.amxx +"gal_changelevel" "f" ; galileo.amxx +"gal_createmapfile" "l" ; galileo.amxx +"gal_maintenance_mode" "l" ; galileo.amxx +"gal_look_for_crashes" "l" ; galileo.amxx +"gal_votemap" "f" ; galileo.amxx +"cm_reload" "l" ; crx_chatmanager.amxx +"kzmapdl" "f" ; kz_map_downloader.amxx +"amx_adminpassword" "l" ; admins_manager.amxx +"amx_adminaccount" "l" ; admins_manager.amxx +"amx_fakeping" "c" ; pingfaker.amxx +"kzr_update" "l" ; kzrecords.amxx +"amx_xvar_float" "g" ; admincmd.amxx +"amx_xvar_int" "g" ; admincmd.amxx +"amx_extendmap" "f" ; admincmd.amxx +"amx_searchcmd" "" ; adminhelp.amxx +"say" "i" ; adminchat.amxx +"amx_votenextmap" "j" ; mapchooser4.amxx +"amx_listmaps2" "" ; mapchooser4.amxx +"amx_nextmap_vote" "f" ; rtv.amxx +"votemap" "" ; deagsmapmanager.amxx +"dmap_help" "" ; deagsmapmanager.amxx +"dmap_status" "m" ; deagsmapmanager.amxx +"dmap_votemode" "r" ; deagsmapmanager.amxx +"dmap_cyclemode" "r" ; deagsmapmanager.amxx +"dmap_banlastmaps" "r" ; deagsmapmanager.amxx +"dmap_quietmode" "r" ; deagsmapmanager.amxx +"dmap_freeze" "r" ; deagsmapmanager.amxx +"dmap_messages" "r" ; deagsmapmanager.amxx +"dmap_rtvtoggle" "r" ; deagsmapmanager.amxx +"dmap_rockthevote" "m" ; deagsmapmanager.amxx +"amx_rockthevote" "m" ; deagsmapmanager.amxx +"amx_rtv" "m" ; deagsmapmanager.amxx +"dmap_rtvpercent" "r" ; deagsmapmanager.amxx +"dmap_rtvplayers" "r" ; deagsmapmanager.amxx +"dmap_rtvwait" "r" ; deagsmapmanager.amxx +"dmap_default" "r" ; deagsmapmanager.amxx +"dmap_mapsurl" "r" ; deagsmapmanager.amxx +"dmap_mapsnum" "r" ; deagsmapmanager.amxx +"dmap_nominations" "r" ; deagsmapmanager.amxx +"dmap_maxcustom" "r" ; deagsmapmanager.amxx +"dmap_cancelvote" "m" ; deagsmapmanager.amxx +"dmap_nominate" "m" ; deagsmapmanager.amxx +"listmaps" "" ; deagsmapmanager.amxx diff --git a/amxmodx/configs/cmds.ini b/amxmodx/configs/cmds.ini new file mode 100755 index 0000000..554d4f9 --- /dev/null +++ b/amxmodx/configs/cmds.ini @@ -0,0 +1,16 @@ +; Menu configuration file +; File location: $moddir/addons/amxmodx/configs/cmds.ini +; To use with Commands Menu plugin + +; NOTE: By default in all settings the access level is set to "u". +; However you can change that, to limit the access to some settings. + +; Commands Menu: ; < description > < command > < flags > < access level > +; "a" - execute from server console +; "b" - execute from admin console +; "c" - execute on all clients +; "d" - back to menu when executed + +"Pause" "amx_pause" "ad" "u" +" " "-" "" "u" +"Restart Round" "sv_restartround 1" "a" "u" diff --git a/amxmodx/configs/configs.ini b/amxmodx/configs/configs.ini new file mode 100755 index 0000000..27bbdd1 --- /dev/null +++ b/amxmodx/configs/configs.ini @@ -0,0 +1,22 @@ +; Menu configuration file +; File location: $moddir/addons/amxmodx/configs/configs.ini +; To use with Commands Menu plugin + +; NOTE: By default in all settings the access level is set to "u". +; However you can change that, to limit the access to some settings. + +; Commands Menu: +; < description > < command > < flags > < access level > +; "a" - execute from server console +; "b" - execute from admin console +; "c" - execute on all clients +; "d" - back to menu when executed + +;"PUBLIC Settings" "servercfgfile server.cfg;exec server.cfg" "a" "u" +;"Clanbase" "exec clanbase.cfg;servercfgfile \'\'" "a" "u" +;"Clanbase Charges Only" "exec clanbase_co.cfg;servercfgfile \'\'" "a" "u" +;"Official CAL Match" "exec cal.cfg;servercfgfile \'\'" "a" "u" +;"ProvingGrounds Server Config" "exec leagues/pg.cfg;servercfgfile \'\'" "a" "u" +;"OGL CS Server Config" "exec ogl.cfg;servercfgfile \'\'" "a" "u" +;"OGL CS FF Server Config" "exec ogl_ff.cfg;servercfgfile \'\'" "a" "u" +;"OGL CS Advanced Server Config" "exec ogl_adv.cfg;servercfgfile \'\'" "a" "u" diff --git a/amxmodx/configs/core.ini b/amxmodx/configs/core.ini new file mode 100755 index 0000000..f0d3a4a --- /dev/null +++ b/amxmodx/configs/core.ini @@ -0,0 +1,50 @@ +; Configuration file for AMX Mod X +amxx_logs addons/amxmodx/logs +amxx_configsdir addons/amxmodx/configs +amxx_datadir addons/amxmodx/data +amxx_modules addons/amxmodx/configs/modules.ini +amxx_plugins addons/amxmodx/configs/plugins.ini +amxx_pluginsdir addons/amxmodx/plugins +amxx_modulesdir addons/amxmodx/modules +amxx_vault addons/amxmodx/data/vault.ini +; It is important that "csstats" comes before "csstats_score" +csstats addons/amxmodx/data/csstats.dat +csstats_score addons/amxmodx/data/csstats.amxx + +; Logging mode +; 0 - no logging +; 1 - one logfile / day +; 2 - one logfile / map +; 3 - HL Logs +amxx_logging 1 + +; MySQL default timeout +mysql_timeout 60 + +; Binary logging level +; add these up to get what you want +; these only work with bin logging binaries +; 1 - default +; 2 - log internal string sets/gets +; 4 - log internal formats +; 8 - log all native params +; 16 - log internal function calls (only in debug mode) +; 32 - log line number accesses (only in debug mode) +bin_logging 49 + +; Maximum binary log size, in megs +max_binlog_size 20 + +; Plugin optimization flags - add these up to get what you want +; lowering these may stop crashes on very old CPUs +; set 65536 to disable optimizer, NOT 0! +;------------- +; 1 - float arithmetic +; 2 - float comparisons +; 4 - float rounding +optimizer 7 + +; Admin command flag manager +; 0 - enabled +; 1 - disabled +disableflagman 0 diff --git a/amxmodx/configs/custommenuitems.cfg b/amxmodx/configs/custommenuitems.cfg new file mode 100755 index 0000000..cb6f2aa --- /dev/null +++ b/amxmodx/configs/custommenuitems.cfg @@ -0,0 +1,19 @@ +// Here you can add menu items from any plugin to Menus Front-End plugin, aka "amxmodmenu". +// You can also add menu items to the normal non-admin client menu "amx_menu". +// +// Adding to "amxmodmenu": +// Usage: "amx_addmenuitem " +// +// Adding to "amx_menu": +// Usage: "amx_addclientmenuitem " +// +// : This is the text displayed in the menu itself for this item. +// : This is the client command used to access the menu. +// : Specify what access flags admins must have to use this menu item. (Check users.ini for access flags.) +// : This must be the _exact_ (though case insensitive) name of the plugin which holds the menu command. (Use "amxx plugins" in server console, plugin names are listed in Name column.) +// +// Example: (be sure to use quotes around parameters with spaces!) +// +// amx_addmenuitem "Weapon Arena" "weaponarena_menu" "hu" "Weapon Arena" +// amx_addclientmenuitem "Warcraft 3" "war3menu" "" "Warcraft 3 XP" + diff --git a/amxmodx/configs/cvars.ini b/amxmodx/configs/cvars.ini new file mode 100755 index 0000000..fb61b38 --- /dev/null +++ b/amxmodx/configs/cvars.ini @@ -0,0 +1,22 @@ +; Menu configuration file +; File location: $moddir/addons/amxmodx/configs/cvars.ini +; To use with Commands Menu plugin + +; Cvars Menu: +; < cvar > < values > ... < access level > + +"mp_timelimit" "0" "30" "45" "u" +"sv_password" "" "mypw" "clanwar" "u" +"pausable" "0" "1" "u" +"sv_voiceenable" "0" "1" "u" +"mp_chattime" "0" "1" "3" "u" +"mp_logmessages" "0" "1" "u" +"mp_friendlyfire" "0" "1" "u" +"mp_limitteams" "0" "1" "2" "u" +"mp_autoteambalance" "0" "1" "2" "u" +"allow_spectators" "0" "1" "u" +"mp_freezetime" "0" "6" "u" +"mp_buytime" "1" "0.5" "u" +"mp_startmoney" "800" "1800" "3600" "u" +"mp_c4timer" "35" "45" "15" "u" +"mp_forcechasecam" "0" "1" "2" "u" diff --git a/amxmodx/configs/hamdata.ini b/amxmodx/configs/hamdata.ini new file mode 100644 index 0000000..05a4469 --- /dev/null +++ b/amxmodx/configs/hamdata.ini @@ -0,0 +1,4719 @@ +; Ham Sandwich module config file. +; +; IMPORTANT: It is highly suggested that you do not modify this file unless +; you know _exactly_ what you are doing! +; +; NOTE: Just because a mod contains a function does not means it will work +; as expected. If, for example, HamKilled() does not work as you think +; it should in Counter-Strike DO NOT FILE A BUG REPORT. This just +; exposes the function for you, whether or not it works, or how it +; works is up to plugin authors to figure out. +; +; NOTE: If a mod is missing keys for a certain native, that particular native +; will not be loaded! Example: Say CS is missing the "takedamage" index +; but has the use and pev indexes. The HamUse and HamePdataCbase natives +; will be registered, but the HamTakeDamage native will not register. +; In addition, any attempts to hook a function who's key is missing will +; result in the plugin failing. +; +; NOTE: The base key is only needed for the linux configs. +; +; NOTE: Any keys that begin with a modname (eg: cstrike_restart) will, +; obviously, only work on that mod and all mirrors of it (eg: czero). +; +; NOTE: If you change this file while the module is already loaded, you will +; need to restart the server for the changes to take effect. Changes to +; this file before the module is loaded will take effect when the module +; loads. +; +; NOTE: All of these offsets and settings are for the latest (at the time of +; release) legitimate version of the mod. However, there is a _chance_ +; that they will work on older (and even newer) versions. +; eg: If they work on non-Steam CS 1.6 this is coincidental, if they do +; not work on non-Steam CS 1.6 this will not be officially fixed. +; +; Mirrors: These take the name of one mod, and copy all of its data to another +; name. An example of a use for this would be cstrike and czero: they +; use the same binary so all of its vtable offsets are guaranteed to +; be identical. Mirrors should always come first in the file! +; +; Version: $Id: hamdata.ini 3687 2008-03-04 18:51:35Z sawce $ + + +@mirror cstrike czero +@mirror ns nsp +@mirror valve dmc + +; TODO: check these - all are estimates +@section cstrike linux + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 3 + objectcaps 6 + activate 7 + setobjectcollisionbox 8 + classify 9 + deathnotice 10 + traceattack 11 + takedamage 12 + takehealth 13 + killed 14 + bloodcolor 15 + tracebleed 16 + istriggered 17 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + giveammo 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvisible 56 + fvecvisible 57 + changeyaw 59 + hashumangibs 60 + hasaliengibs 61 + fademonster 62 + gibmonster 63 + getdeathactivity 64 + becomedead 65 + irelationship 67 + painsound 68 + reportaistate 70 + monsterinitdead 71 + look 72 + bestvisibleenemy 73 + finviewcone 74 + fvecinviewcone 75 + + player_jump 76 + player_duck 77 + player_prethink 78 + player_postthink 79 + player_getgunposition 80 + player_shouldfadeondeath 66 + player_impulsecommands 83 + player_updateclientdata 82 + + item_addtoplayer 59 + item_addduplicate 60 + item_getiteminfo 61 + item_candeploy 62 + item_deploy 64 + item_canholster 66 + item_holster 67 + item_updateiteminfo 68 + item_preframe 69 + item_postframe 70 + item_drop 71 + item_kill 72 + item_attachtoplayer 73 + item_primaryammoindex 74 + item_secondaryammoindex 75 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 79 + + weapon_extractammo 80 + weapon_extractclipammo 81 + weapon_addweapon 82 + weapon_playemptysound 83 + weapon_resetemptysound 84 + weapon_isusable 86 + weapon_primaryattack 87 + weapon_secondaryattack 88 + weapon_reload 89 + weapon_weaponidle 90 + weapon_retireweapon 91 + weapon_shouldweaponidle 92 + weapon_usedecrement 93 + + cstrike_restart 2 + cstrike_roundrespawn 84 + cstrike_item_candrop 63 + cstrike_item_isweapon 65 + cstrike_item_getmaxspeed 78 + cstrike_weapon_sendweaponanim 85 + cstrike_player_resetmaxspeed 69 + cstrike_player_isbot 81 + cstrike_player_getautoaimvector 85 + cstrike_player_blind 86 + cstrike_player_ontouchingweapon 87 + +@end +@section cstrike windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 3 + objectcaps 6 + activate 7 + setobjectcollisionbox 8 + classify 9 + deathnotice 10 + traceattack 11 + takedamage 12 + takehealth 13 + killed 14 + bloodcolor 15 + tracebleed 16 + istriggered 17 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + giveammo 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvecvisible 56 + fvisible 57 + changeyaw 59 + hashumangibs 60 + hasaliengibs 61 + fademonster 62 + gibmonster 63 + getdeathactivity 64 + becomedead 65 + irelationship 67 + painsound 68 + reportaistate 70 + monsterinitdead 71 + look 72 + bestvisibleenemy 73 + finviewcone 75 + fvecinviewcone 74 + + player_jump 76 + player_duck 77 + player_prethink 78 + player_postthink 79 + player_getgunposition 80 + player_shouldfadeondeath 66 + player_impulsecommands 83 + player_updateclientdata 82 + + item_addtoplayer 59 + item_addduplicate 60 + item_getiteminfo 61 + item_candeploy 62 + item_deploy 64 + item_canholster 66 + item_holster 67 + item_updateiteminfo 68 + item_preframe 69 + item_postframe 70 + item_drop 71 + item_kill 72 + item_attachtoplayer 73 + item_primaryammoindex 74 + item_secondaryammoindex 75 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 79 + + weapon_extractammo 80 + weapon_extractclipammo 81 + weapon_addweapon 82 + weapon_playemptysound 83 + weapon_resetemptysound 84 + weapon_isusable 86 + weapon_primaryattack 87 + weapon_secondaryattack 88 + weapon_reload 89 + weapon_weaponidle 90 + weapon_retireweapon 91 + weapon_shouldweaponidle 92 + weapon_usedecrement 93 + + cstrike_restart 2 + cstrike_roundrespawn 84 + cstrike_item_candrop 63 + cstrike_item_isweapon 65 + cstrike_item_getmaxspeed 78 + cstrike_weapon_sendweaponanim 85 + cstrike_player_resetmaxspeed 69 + cstrike_player_isbot 81 + cstrike_player_getautoaimvector 85 + cstrike_player_blind 86 + cstrike_player_ontouchingweapon 87 +@end + +@section cstrike mac + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 3 + objectcaps 6 + activate 7 + setobjectcollisionbox 8 + classify 9 + deathnotice 10 + traceattack 11 + takedamage 12 + takehealth 13 + killed 14 + bloodcolor 15 + tracebleed 16 + istriggered 17 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + giveammo 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvecvisible 56 + fvisible 57 + changeyaw 59 + hashumangibs 60 + hasaliengibs 61 + fademonster 62 + gibmonster 63 + getdeathactivity 64 + becomedead 65 + irelationship 67 + painsound 68 + reportaistate 70 + monsterinitdead 71 + look 72 + bestvisibleenemy 73 + finviewcone 74 + fvecinviewcone 75 + + player_jump 76 + player_duck 77 + player_prethink 78 + player_postthink 79 + player_getgunposition 80 + player_shouldfadeondeath 66 + player_impulsecommands 83 + player_updateclientdata 82 + + item_addtoplayer 59 + item_addduplicate 60 + item_getiteminfo 61 + item_candeploy 62 + item_deploy 64 + item_canholster 66 + item_holster 67 + item_updateiteminfo 68 + item_preframe 69 + item_postframe 70 + item_drop 71 + item_kill 72 + item_attachtoplayer 73 + item_primaryammoindex 74 + item_secondaryammoindex 75 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 79 + + weapon_extractammo 80 + weapon_extractclipammo 81 + weapon_addweapon 82 + weapon_playemptysound 83 + weapon_resetemptysound 84 + weapon_isusable 86 + weapon_primaryattack 87 + weapon_secondaryattack 88 + weapon_reload 89 + weapon_weaponidle 90 + weapon_retireweapon 91 + weapon_shouldweaponidle 92 + weapon_usedecrement 93 + + cstrike_restart 2 + cstrike_roundrespawn 84 + cstrike_item_candrop 63 + cstrike_item_isweapon 65 + cstrike_item_getmaxspeed 78 + cstrike_weapon_sendweaponanim 85 + cstrike_player_resetmaxspeed 69 + cstrike_player_isbot 81 + cstrike_player_getautoaimvector 85 + cstrike_player_blind 86 + cstrike_player_ontouchingweapon 87 +@end + +@section dod linux + pev 4 + base 0x0 + + spawn 3 + precache 4 + keyvalue 5 + objectcaps 8 + activate 9 + setobjectcollisionbox 12 + classify 13 + deathnotice 14 + traceattack 17 + takedamage 18 + takehealth 19 + killed 20 + bloodcolor 21 + tracebleed 22 + mymonsterpointer 23 + mysquadmonsterpointer 24 + gettogglestate 25 + addpoints 26 + addpointstoteam 27 + addplayeritem 28 + removeplayeritem 29 + giveammo 30 + getdelay 31 + ismoving 32 + overridereset 33 + damagedecal 34 + settogglestate 35 + startsneaking 36 + stopsneaking 37 + oncontrols 38 + issneaking 39 + isalive 40 + isbspmodel 41 + reflectgauss 42 + hastarget 43 + isinworld 44 + isplayer 45 + isnetclient 46 + teamid 47 + getnexttarget 48 + think 49 + touch 50 + use 51 + blocked 52 + respawn 53 + updateowner 54 + fbecomeprone 55 + center 56 + eyeposition 57 + earposition 58 + bodytarget 59 + illumination 60 + fvisible 61 + fvecvisible 62 + + look 64 + changeyaw 67 + irelationship 69 + monsterinitdead 71 + bestvisibleenemy 74 + finviewcone 75 + fvecinviewcone 76 + + runai 65 + monsterthink 68 + monsterinit 70 + checklocalmove 77 + move 78 + moveexecute 79 + shouldadvanceroute 80 + getstoppedactivity 81 + stop 82 + checkrangeattack1 83 + checkrangeattack2 84 + checkmeleeattack1 85 + checkmeleeattack2 86 + schedulechange 92 + canplaysequence 93 + canplaysentence2 94 + playsentence 95 + playscriptedsentence 96 + sentencestop 97 + getidealstate 98 + setactivity 99 + reportaistate 100 + checkenemy 101 + ftriangulate 102 + setyawspeed 103 + buildnearestroute 104 + findcover 105 + coverradius 107 + fcancheckattacks 108 + checkammo 109 + ignoreconditions 110 + fvalidatehinttype 111 + fcanactiveidle 112 + isoundmask 113 + hearingsensitivity 116 + barnaclevictimbitten 117 + barnaclevictimreleased 118 + preschedulethink 120 + getdeathactivity 121 + gibmonster 122 + hashumangibs 123 + hasaliengibs 124 + fademonster 125 + deathsound 127 + alertsound 128 + idlesound 129 + painsound 130 + stopfollowing 131 + + player_jump 134 + player_duck 135 + player_prethink 132 + player_postthink 133 + player_getgunposition 126 + player_shouldfadeondeath 66 + player_impulsecommands 137 + player_updateclientdata 136 + + item_addtoplayer 64 + item_addduplicate 65 + item_getiteminfo 66 + item_candeploy 67 + item_deploy 68 + item_canholster 73 + item_holster 74 + item_updateiteminfo 75 + item_preframe 76 + item_postframe 77 + item_drop 78 + item_kill 79 + item_attachtoplayer 80 + item_primaryammoindex 81 + item_secondaryammoindex 82 + item_updateclientdata 83 + item_getweaponptr 84 + item_itemslot 85 + + weapon_extractammo 86 + weapon_extractclipammo 87 + weapon_addweapon 88 + weapon_playemptysound 89 + weapon_resetemptysound 90 + weapon_isusable 92 + weapon_primaryattack 102 + weapon_secondaryattack 103 + weapon_reload 104 + weapon_weaponidle 105 + weapon_retireweapon 106 + weapon_shouldweaponidle 107 + weapon_usedecrement 108 + + dod_roundrespawn 0 + dod_roundrespawnent 1 + dod_roundstore 2 + dod_areasetindex 10 + dod_areasendstatus 11 + dod_getstate 15 + dod_getstateent 16 + dod_setscriptreset 119 + + dod_item_candrop 70 + dod_item_spawndeploy 69 + dod_item_setdmgtime 71 + dod_item_dropgren 72 + + dod_weapon_sendweaponanim 91 + dod_weapon_isuseable 92 + dod_weapon_aim 93 + dod_weapon_flaim 94 + dod_weapon_removestamina 95 + dod_weapon_changefov 96 + dod_weapon_zoomout 97 + dod_weapon_zoomin 98 + dod_weapon_getfov 99 + dod_weapon_playeriswatersniping 100 + dod_weapon_updatezoomspeed 101 + dod_weapon_special 105 +@end +@section dod windows + pev 4 + base 0x0 + + spawn 3 + precache 4 + keyvalue 5 + objectcaps 8 + activate 9 + setobjectcollisionbox 12 + classify 13 + deathnotice 14 + traceattack 17 + takedamage 18 + takehealth 19 + killed 20 + bloodcolor 21 + tracebleed 22 + mymonsterpointer 23 + mysquadmonsterpointer 24 + gettogglestate 25 + addpoints 26 + addpointstoteam 27 + addplayeritem 28 + removeplayeritem 29 + giveammo 30 + getdelay 31 + ismoving 32 + overridereset 33 + damagedecal 34 + settogglestate 35 + startsneaking 36 + stopsneaking 37 + oncontrols 38 + issneaking 39 + isalive 40 + isbspmodel 41 + reflectgauss 42 + hastarget 43 + isinworld 44 + isplayer 45 + isnetclient 46 + teamid 47 + getnexttarget 48 + think 49 + touch 50 + use 51 + blocked 52 + respawn 53 + updateowner 54 + fbecomeprone 55 + center 56 + eyeposition 57 + earposition 58 + bodytarget 59 + illumination 60 + fvisible 62 + fvecvisible 61 + + look 64 + changeyaw 67 + irelationship 69 + monsterinitdead 71 + bestvisibleenemy 74 + finviewcone 76 + fvecinviewcone 75 + + runai 65 + monsterthink 68 + monsterinit 70 + checklocalmove 77 + move 78 + moveexecute 79 + shouldadvanceroute 80 + getstoppedactivity 81 + stop 82 + checkrangeattack1 83 + checkrangeattack2 84 + checkmeleeattack1 85 + checkmeleeattack2 86 + schedulechange 92 + canplaysequence 93 + canplaysentence2 94 + playsentence 95 + playscriptedsentence 96 + sentencestop 97 + getidealstate 98 + setactivity 99 + reportaistate 100 + checkenemy 101 + ftriangulate 102 + setyawspeed 103 + buildnearestroute 104 + findcover 105 + coverradius 107 + fcancheckattacks 108 + checkammo 109 + ignoreconditions 110 + fvalidatehinttype 111 + fcanactiveidle 112 + isoundmask 113 + hearingsensitivity 116 + barnaclevictimbitten 117 + barnaclevictimreleased 118 + preschedulethink 120 + getdeathactivity 121 + gibmonster 122 + hashumangibs 123 + hasaliengibs 124 + fademonster 125 + deathsound 127 + alertsound 128 + idlesound 129 + painsound 130 + stopfollowing 131 + + player_jump 134 + player_duck 135 + player_prethink 132 + player_postthink 133 + player_getgunposition 126 + player_shouldfadeondeath 66 + player_impulsecommands 137 + player_updateclientdata 136 + + item_addtoplayer 64 + item_addduplicate 65 + item_getiteminfo 66 + item_candeploy 67 + item_deploy 68 + item_canholster 73 + item_holster 74 + item_updateiteminfo 75 + item_preframe 76 + item_postframe 77 + item_drop 78 + item_kill 79 + item_attachtoplayer 80 + item_primaryammoindex 81 + item_secondaryammoindex 82 + item_updateclientdata 83 + item_getweaponptr 84 + item_itemslot 85 + + weapon_extractammo 86 + weapon_extractclipammo 87 + weapon_addweapon 88 + weapon_playemptysound 89 + weapon_resetemptysound 90 + weapon_isusable 92 + weapon_primaryattack 102 + weapon_secondaryattack 103 + weapon_reload 104 + weapon_weaponidle 105 + weapon_retireweapon 106 + weapon_shouldweaponidle 107 + weapon_usedecrement 108 + + dod_roundrespawn 0 + dod_roundrespawnent 1 + dod_roundstore 2 + dod_areasetindex 10 + dod_areasendstatus 11 + dod_getstate 16 + dod_getstateent 15 + dod_setscriptreset 119 + + dod_item_candrop 70 + dod_item_spawndeploy 69 + dod_item_setdmgtime 71 + dod_item_dropgren 72 + + dod_weapon_sendweaponanim 91 + dod_weapon_isuseable 92 + dod_weapon_aim 93 + dod_weapon_flaim 94 + dod_weapon_removestamina 95 + dod_weapon_changefov 96 + dod_weapon_zoomout 97 + dod_weapon_zoomin 98 + dod_weapon_getfov 99 + dod_weapon_playeriswatersniping 100 + dod_weapon_updatezoomspeed 101 + dod_weapon_special 105 +@end + +@section dod mac + pev 4 + base 0x0 + + spawn 3 + precache 4 + keyvalue 5 + objectcaps 8 + activate 9 + setobjectcollisionbox 12 + classify 13 + deathnotice 14 + traceattack 17 + takedamage 18 + takehealth 19 + killed 20 + bloodcolor 21 + tracebleed 22 + mymonsterpointer 23 + mysquadmonsterpointer 24 + gettogglestate 25 + addpoints 26 + addpointstoteam 27 + addplayeritem 28 + removeplayeritem 29 + giveammo 30 + getdelay 31 + ismoving 32 + overridereset 33 + damagedecal 34 + settogglestate 35 + startsneaking 36 + stopsneaking 37 + oncontrols 38 + issneaking 39 + isalive 40 + isbspmodel 41 + reflectgauss 42 + hastarget 43 + isinworld 44 + isplayer 45 + isnetclient 46 + teamid 47 + getnexttarget 48 + think 49 + touch 50 + use 51 + blocked 52 + respawn 53 + updateowner 54 + fbecomeprone 55 + center 56 + eyeposition 57 + earposition 58 + bodytarget 59 + illumination 60 + fvisible 61 + fvecvisible 62 + + look 64 + changeyaw 67 + irelationship 69 + monsterinitdead 71 + bestvisibleenemy 74 + finviewcone 75 + fvecinviewcone 76 + + runai 65 + monsterthink 68 + monsterinit 70 + checklocalmove 77 + move 78 + moveexecute 79 + shouldadvanceroute 80 + getstoppedactivity 81 + stop 82 + checkrangeattack1 83 + checkrangeattack2 84 + checkmeleeattack1 85 + checkmeleeattack2 86 + schedulechange 92 + canplaysequence 93 + canplaysentence2 94 + playsentence 95 + playscriptedsentence 96 + sentencestop 97 + getidealstate 98 + setactivity 99 + reportaistate 100 + checkenemy 101 + ftriangulate 102 + setyawspeed 103 + buildnearestroute 104 + findcover 105 + coverradius 107 + fcancheckattacks 108 + checkammo 109 + ignoreconditions 110 + fvalidatehinttype 111 + fcanactiveidle 112 + isoundmask 113 + hearingsensitivity 116 + barnaclevictimbitten 117 + barnaclevictimreleased 118 + preschedulethink 120 + getdeathactivity 121 + gibmonster 122 + hashumangibs 123 + hasaliengibs 124 + fademonster 125 + deathsound 127 + alertsound 128 + idlesound 129 + painsound 130 + stopfollowing 131 + + player_jump 134 + player_duck 135 + player_prethink 132 + player_postthink 133 + player_getgunposition 126 + player_shouldfadeondeath 66 + player_impulsecommands 137 + player_updateclientdata 136 + + item_addtoplayer 64 + item_addduplicate 65 + item_getiteminfo 66 + item_candeploy 67 + item_deploy 68 + item_canholster 73 + item_holster 74 + item_updateiteminfo 75 + item_preframe 76 + item_postframe 77 + item_drop 78 + item_kill 79 + item_attachtoplayer 80 + item_primaryammoindex 81 + item_secondaryammoindex 82 + item_updateclientdata 83 + item_getweaponptr 84 + item_itemslot 85 + + weapon_extractammo 86 + weapon_extractclipammo 87 + weapon_addweapon 88 + weapon_playemptysound 89 + weapon_resetemptysound 90 + weapon_isusable 92 + weapon_primaryattack 102 + weapon_secondaryattack 103 + weapon_reload 104 + weapon_weaponidle 105 + weapon_retireweapon 106 + weapon_shouldweaponidle 107 + weapon_usedecrement 108 + + dod_roundrespawn 0 + dod_roundrespawnent 1 + dod_roundstore 2 + dod_areasetindex 10 + dod_areasendstatus 11 + dod_getstate 15 + dod_getstateent 16 + dod_setscriptreset 119 + + dod_item_candrop 70 + dod_item_spawndeploy 69 + dod_item_setdmgtime 71 + dod_item_dropgren 72 + + dod_weapon_sendweaponanim 91 + dod_weapon_isuseable 92 + dod_weapon_aim 93 + dod_weapon_flaim 94 + dod_weapon_removestamina 95 + dod_weapon_changefov 96 + dod_weapon_zoomout 97 + dod_weapon_zoomin 98 + dod_weapon_getfov 99 + dod_weapon_playeriswatersniping 100 + dod_weapon_updatezoomspeed 101 + dod_weapon_special 105 +@end + +; TFC Does not have the following "standard" entries in its vtable: +; addpoints, addpointstoteam, getgunposition, teamid, usedecrement, updateclientdata +@section tfc linux + pev 4 + base 0x0 + + spawn 2 + precache 3 + keyvalue 4 + objectcaps 7 + activate 8 + setobjectcollisionbox 9 + classify 10 + deathnotice 11 + traceattack 12 + takedamage 13 + takehealth 14 + bloodcolor 16 + tracebleed 17 + mymonsterpointer 19 + mysquadmonsterpointer 20 + gettogglestate 21 + addplayeritem 22 + removeplayeritem 23 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 40 + getnexttarget 42 + think 43 + touch 44 + use 45 + blocked 46 + respawn 47 + updateowner 48 + fbecomeprone 49 + center 50 + eyeposition 51 + earposition 52 + bodytarget 53 + illumination 54 + fvisible 55 + fvecvisible 56 + + look 66 + changeyaw 69 + irelationship 71 + monsterinitdead 73 + becomedead 74 + bestvisibleenemy 76 + finviewcone 77 + fvecinviewcone 78 + + runai 67 + monsterthink 70 + monsterinit 72 + checklocalmove 79 + move 80 + moveexecute 81 + shouldadvanceroute 82 + getstoppedactivity 83 + stop 84 + checkrangeattack1 85 + checkrangeattack2 86 + checkmeleeattack1 87 + checkmeleeattack2 88 + schedulechange 94 + canplaysequence 95 + canplaysentence2 96 + playsentence 97 + playscriptedsentence 98 + sentencestop 99 + getidealstate 100 + setactivity 101 + reportaistate 102 + checkenemy 103 + ftriangulate 104 + setyawspeed 105 + buildnearestroute 106 + findcover 107 + coverradius 109 + fcancheckattacks 110 + checkammo 111 + ignoreconditions 112 + fvalidatehinttype 113 + fcanactiveidle 114 + isoundmask 115 + hearingsensitivity 118 + barnaclevictimbitten 119 + barnaclevictimreleased 120 + preschedulethink 121 + getdeathactivity 122 + gibmonster 123 + hashumangibs 124 + hasaliengibs 125 + fademonster 126 + deathsound 129 + alertsound 130 + idlesound 131 + painsound 132 + stopfollowing 133 + + player_jump 134 + player_duck 135 + player_prethink 136 + player_postthink 137 + player_shouldfadeondeath 68 + player_impulsecommands 138 + + item_addtoplayer 66 + item_addduplicate 67 + item_getiteminfo 69 + item_candeploy 70 + item_deploy 71 + item_canholster 72 + item_holster 73 + item_updateiteminfo 74 + item_preframe 75 + item_postframe 76 + item_drop 77 + item_kill 78 + item_attachtoplayer 79 + item_primaryammoindex 80 + item_secondaryammoindex 81 + item_updateclientdata 82 + item_getweaponptr 83 + item_itemslot 68 + + weapon_extractammo 84 + weapon_extractclipammo 85 + weapon_addweapon 86 + weapon_playemptysound 87 + weapon_resetemptysound 88 + weapon_sendweaponanim 89 + weapon_isusable 90 + weapon_primaryattack 91 + weapon_secondaryattack 92 + weapon_reload 93 + weapon_weaponidle 94 + weapon_retireweapon 95 + weapon_shouldweaponidle 96 + weapon_getnextattackdelay 97 + + tfc_killed 15 + tfc_istriggered 18 + tfc_giveammo 24 + tfc_dbgetitemname 41 + tfc_engineeruse 57 + tfc_finished 58 + tfc_empexplode 59 + tfc_calcempdmgrad 60 + tfc_takeempblast 61 + tfc_empremove 62 + tfc_takeconcussionblast 63 + tfc_concuss 64 + tfc_radiusdamage 127 + tfc_radiusdamage2 128 +@end +@section tfc windows + pev 4 + base 0x0 + + spawn 1 + precache 2 + keyvalue 3 + objectcaps 6 + activate 7 + setobjectcollisionbox 8 + classify 9 + deathnotice 10 + traceattack 11 + takedamage 12 + takehealth 13 + bloodcolor 15 + tracebleed 16 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addplayeritem 21 + removeplayeritem 22 + getdelay 24 + ismoving 25 + overridereset 26 + damagedecal 27 + settogglestate 28 + startsneaking 29 + stopsneaking 30 + oncontrols 31 + issneaking 32 + isalive 33 + isbspmodel 34 + reflectgauss 35 + hastarget 36 + isinworld 37 + isplayer 38 + isnetclient 39 + getnexttarget 41 + think 42 + touch 43 + use 44 + blocked 45 + respawn 46 + updateowner 47 + fbecomeprone 48 + center 49 + eyeposition 50 + earposition 51 + bodytarget 52 + illumination 53 + fvisible 55 + fvecvisible 54 + + look 65 + changeyaw 68 + irelationship 70 + monsterinitdead 72 + becomedead 73 + bestvisibleenemy 75 + finviewcone 77 + fvecinviewcone 76 + + runai 66 + monsterthink 69 + monsterinit 71 + checklocalmove 78 + move 79 + moveexecute 80 + shouldadvanceroute 81 + getstoppedactivity 82 + stop 83 + checkrangeattack1 84 + checkrangeattack2 85 + checkmeleeattack1 86 + checkmeleeattack2 87 + schedulechange 93 + canplaysequence 94 + canplaysentence2 95 + playsentence 96 + playscriptedsentence 97 + sentencestop 98 + getidealstate 99 + setactivity 100 + reportaistate 101 + checkenemy 102 + ftriangulate 103 + setyawspeed 104 + buildnearestroute 105 + findcover 106 + coverradius 108 + fcancheckattacks 109 + checkammo 110 + ignoreconditions 111 + fvalidatehinttype 112 + fcanactiveidle 113 + isoundmask 114 + hearingsensitivity 117 + barnaclevictimbitten 118 + barnaclevictimreleased 119 + preschedulethink 120 + getdeathactivity 121 + gibmonster 122 + hashumangibs 123 + hasaliengibs 124 + fademonster 125 + deathsound 128 + alertsound 129 + idlesound 130 + painsound 131 + stopfollowing 132 + + player_jump 133 + player_duck 134 + player_prethink 135 + player_postthink 136 + player_shouldfadeondeath 67 + player_impulsecommands 137 + + item_addtoplayer 65 + item_addduplicate 66 + item_getiteminfo 68 + item_candeploy 69 + item_deploy 70 + item_canholster 71 + item_holster 72 + item_updateiteminfo 73 + item_preframe 74 + item_postframe 75 + item_drop 76 + item_kill 77 + item_attachtoplayer 78 + item_primaryammoindex 79 + item_secondaryammoindex 80 + item_updateclientdata 81 + item_getweaponptr 82 + item_itemslot 67 + + weapon_extractammo 83 + weapon_extractclipammo 84 + weapon_addweapon 85 + weapon_playemptysound 86 + weapon_resetemptysound 87 + weapon_sendweaponanim 88 + weapon_isusable 89 + weapon_primaryattack 90 + weapon_secondaryattack 91 + weapon_reload 92 + weapon_weaponidle 93 + weapon_retireweapon 94 + weapon_shouldweaponidle 95 + wepaon_getnextattackdelay 96 + + tfc_killed 14 + tfc_istriggered 17 + tfc_giveammo 23 + tfc_dbgetitemname 40 + tfc_engineeruse 56 + tfc_finished 57 + tfc_empexplode 58 + tfc_calcempdmgrad 59 + tfc_takeempblast 60 + tfc_empremove 61 + tfc_takeconcussionblast 62 + tfc_concuss 63 + tfc_radiusdamage 127 + tfc_radiusdamage2 126 +@end + +@section tfc mac + pev 4 + base 0x0 + + spawn 1 + precache 2 + keyvalue 3 + objectcaps 6 + activate 7 + setobjectcollisionbox 8 + classify 9 + deathnotice 10 + traceattack 11 + takedamage 12 + takehealth 13 + bloodcolor 15 + tracebleed 16 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addplayeritem 21 + removeplayeritem 22 + getdelay 24 + ismoving 25 + overridereset 26 + damagedecal 27 + settogglestate 28 + startsneaking 29 + stopsneaking 30 + oncontrols 31 + issneaking 32 + isalive 33 + isbspmodel 34 + reflectgauss 35 + hastarget 36 + isinworld 37 + isplayer 38 + isnetclient 39 + getnexttarget 41 + think 42 + touch 43 + use 44 + blocked 45 + respawn 46 + updateowner 47 + fbecomeprone 48 + center 49 + eyeposition 50 + earposition 51 + bodytarget 52 + illumination 53 + fvisible 54 + fvecvisible 55 + + look 65 + changeyaw 68 + irelationship 70 + monsterinitdead 72 + becomedead 73 + bestvisibleenemy 75 + finviewcone 76 + fvecinviewcone 77 + + runai 66 + monsterthink 69 + monsterinit 71 + checklocalmove 78 + move 79 + moveexecute 80 + shouldadvanceroute 81 + getstoppedactivity 82 + stop 83 + checkrangeattack1 84 + checkrangeattack2 85 + checkmeleeattack1 86 + checkmeleeattack2 87 + schedulechange 93 + canplaysequence 94 + canplaysentence2 95 + playsentence 96 + playscriptedsentence 97 + sentencestop 98 + getidealstate 99 + setactivity 100 + reportaistate 101 + checkenemy 102 + ftriangulate 103 + setyawspeed 104 + buildnearestroute 105 + findcover 106 + coverradius 108 + fcancheckattacks 109 + checkammo 110 + ignoreconditions 111 + fvalidatehinttype 112 + fcanactiveidle 113 + isoundmask 114 + hearingsensitivity 117 + barnaclevictimbitten 118 + barnaclevictimreleased 119 + preschedulethink 120 + getdeathactivity 121 + gibmonster 122 + hashumangibs 123 + hasaliengibs 124 + fademonster 125 + deathsound 128 + alertsound 129 + idlesound 130 + painsound 131 + stopfollowing 132 + + player_jump 133 + player_duck 134 + player_prethink 135 + player_postthink 136 + player_shouldfadeondeath 67 + player_impulsecommands 137 + + item_addtoplayer 65 + item_addduplicate 66 + item_getiteminfo 68 + item_candeploy 69 + item_deploy 70 + item_canholster 71 + item_holster 72 + item_updateiteminfo 73 + item_preframe 74 + item_postframe 75 + item_drop 76 + item_kill 77 + item_attachtoplayer 78 + item_primaryammoindex 79 + item_secondaryammoindex 80 + item_updateclientdata 81 + item_getweaponptr 82 + item_itemslot 67 + + weapon_extractammo 83 + weapon_extractclipammo 84 + weapon_addweapon 85 + weapon_playemptysound 86 + weapon_resetemptysound 87 + weapon_sendweaponanim 88 + weapon_isusable 89 + weapon_primaryattack 90 + weapon_secondaryattack 91 + weapon_reload 92 + weapon_weaponidle 93 + weapon_retireweapon 94 + weapon_shouldweaponidle 95 + weapon_getnextattackdelay 96 + + tfc_killed 14 + tfc_istriggered 17 + tfc_giveammo 23 + tfc_dbgetitemname 40 + tfc_engineeruse 56 + tfc_finished 57 + tfc_empexplode 58 + tfc_calcempdmgrad 59 + tfc_takeempblast 60 + tfc_empremove 61 + tfc_takeconcussionblast 62 + tfc_concuss 63 + tfc_radiusdamage 126 + tfc_radiusdamage2 127 +@end + +; ns's linux binary is compiled with gcc 3.3, so the "base" is 0, and pev is 4 +@section ns linux + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 14 + bloodcolor 16 + tracebleed 17 + istriggered 18 + mymonsterpointer 19 + mysquadmonsterpointer 20 + gettogglestate 21 + addpoints 22 + addpointstoteam 23 + addplayeritem 24 + removeplayeritem 25 + giveammo 26 + getdelay 27 + ismoving 28 + overridereset 29 + damagedecal 30 + settogglestate 31 + startsneaking 32 + stopsneaking 33 + oncontrols 34 + issneaking 35 + isalive 36 + isbspmodel 37 + reflectgauss 38 + hastarget 39 + isinworld 40 + isplayer 41 + isnetclient 42 + teamid 43 + getnexttarget 46 + think 47 + touch 48 + use 49 + blocked 50 + respawn 52 + updateowner 53 + fbecomeprone 54 + center 55 + eyeposition 56 + earposition 57 + bodytarget 58 + illumination 59 + fvisible 60 + fvecvisible 61 + + changeyaw 65 + hashumangibs 66 + hasaliengibs 67 + fademonster 68 + gibmonster 69 + getdeathactivity 70 + becomedead 71 + irelationship 73 + painsound 74 + reportaistate 75 + monsterinitdead 76 + look 77 + bestvisibleenemy 78 + finviewcone 80 + fvecinviewcone 81 + + player_jump 83 + player_duck 84 + player_prethink 85 + player_postthink 86 + player_getgunposition 87 + player_shouldfadeondeath 72 + player_impulsecommands 101 + player_updateclientdata 99 + + item_addtoplayer 64 + item_addduplicate 65 + item_getiteminfo 68 + item_candeploy 69 + item_deploy 70 + item_canholster 71 + item_holster 72 + item_updateiteminfo 74 + item_preframe 75 + item_postframe 76 + item_drop 77 + item_kill 78 + item_attachtoplayer 79 + item_primaryammoindex 80 + item_secondaryammoindex 81 + item_updateclientdata 82 + item_getweaponptr 83 + item_itemslot 84 + + weapon_extractammo 85 + weapon_extractclipammo 86 + weapon_addweapon 87 + weapon_playemptysound 88 + weapon_resetemptysound 89 + weapon_sendweaponanim 94 + weapon_isusable 73 + weapon_primaryattack 98 + weapon_secondaryattack 99 + weapon_reload 100 + weapon_weaponidle 101 + weapon_retireweapon 102 + weapon_shouldweaponidle 103 + weapon_usedecrement 104 + + ns_getpointvalue 13 + ns_awardkill 15 + ns_resetentity 45 + ns_updateonremove 51 + ns_setbonecontroller 63 + ns_savedataforreset 64 + ns_gethull 79 + ns_getmaxwalkspeed 88 + ns_setteamid 90 + ns_geteffectiveplayerclass 91 + ns_getauthenticationmask 92 + ns_effectiveplayerclasschanged 93 + ns_needsteamupdate 94 + ns_sendteamupdate 95 + ns_sendweaponupdate 96 + ns_initplayerfromspawn 97 + ns_packdeadplayeritems 98 + ns_getanimationforactivity 100 + ns_startobserver 102 + ns_stopobserver 103 + ns_getadrenalinefactor 104 + ns_givenameditem 106 + ns_suicide 107 + ns_getcanuseweapon 108 + + ns_weapon_getweaponprimetime 90 + ns_weapon_primeweapon 91 + ns_weapon_getisweaponprimed 92 + ns_weapon_getisweaponpriming 93 + ns_weapon_defaultdeploy 95 + ns_weapon_defaultreload 96 + ns_weapon_getdeploytime 97 +@end + +@section ns windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 14 + bloodcolor 16 + tracebleed 17 + istriggered 18 + mymonsterpointer 19 + mysquadmonsterpointer 20 + gettogglestate 21 + addpoints 22 + addpointstoteam 23 + addplayeritem 24 + removeplayeritem 25 + giveammo 26 + getdelay 27 + ismoving 28 + overridereset 29 + damagedecal 30 + settogglestate 31 + startsneaking 32 + stopsneaking 33 + oncontrols 34 + issneaking 35 + isalive 36 + isbspmodel 37 + reflectgauss 38 + hastarget 39 + isinworld 40 + isplayer 41 + isnetclient 42 + teamid 43 + getnexttarget 46 + think 47 + touch 48 + use 49 + blocked 50 + respawn 52 + updateowner 53 + fbecomeprone 54 + center 55 + eyeposition 56 + earposition 57 + bodytarget 58 + illumination 59 + fvisible 60 + fvecvisible 61 + + changeyaw 65 + hashumangibs 66 + hasaliengibs 67 + fademonster 68 + gibmonster 69 + getdeathactivity 70 + becomedead 71 + irelationship 73 + painsound 74 + reportaistate 75 + monsterinitdead 76 + look 77 + bestvisibleenemy 78 + finviewcone 80 + fvecinviewcone 81 + + player_jump 83 + player_duck 84 + player_prethink 85 + player_postthink 86 + player_getgunposition 87 + player_shouldfadeondeath 72 + player_impulsecommands 101 + player_updateclientdata 99 + + item_addtoplayer 64 + item_addduplicate 65 + item_getiteminfo 68 + item_candeploy 69 + item_deploy 70 + item_canholster 71 + item_holster 72 + item_updateiteminfo 74 + item_preframe 75 + item_postframe 76 + item_drop 77 + item_kill 78 + item_attachtoplayer 79 + item_primaryammoindex 80 + item_secondaryammoindex 81 + item_updateclientdata 82 + item_getweaponptr 83 + item_itemslot 84 + + weapon_extractammo 85 + weapon_extractclipammo 86 + weapon_addweapon 87 + weapon_playemptysound 88 + weapon_resetemptysound 89 + weapon_sendweaponanim 94 + weapon_isusable 73 + weapon_primaryattack 98 + weapon_secondaryattack 99 + weapon_reload 100 + weapon_weaponidle 101 + weapon_retireweapon 102 + weapon_shouldweaponidle 103 + weapon_usedecrement 104 + + ns_getpointvalue 13 + ns_awardkill 15 + ns_resetentity 45 + ns_updateonremove 51 + ns_setbonecontroller 63 + ns_savedataforreset 64 + ns_gethull 79 + ns_getmaxwalkspeed 88 + ns_setteamid 90 + ns_geteffectiveplayerclass 91 + ns_getauthenticationmask 92 + ns_effectiveplayerclasschanged 93 + ns_needsteamupdate 94 + ns_sendteamupdate 95 + ns_sendweaponupdate 96 + ns_initplayerfromspawn 97 + ns_packdeadplayeritems 98 + ns_getanimationforactivity 100 + ns_startobserver 102 + ns_stopobserver 103 + ns_getadrenalinefactor 104 + ns_givenameditem 106 + ns_suicide 107 + ns_getcanuseweapon 108 + + ns_weapon_getweaponprimetime 90 + ns_weapon_primeweapon 91 + ns_weapon_getisweaponprimed 92 + ns_weapon_getisweaponpriming 93 + ns_weapon_defaultdeploy 95 + ns_weapon_defaultreload 96 + ns_weapon_getdeploytime 97 +@end + +@section ts linux + pev 0 + base 0x60 + + spawn 9 + precache 10 + keyvalue 11 + objectcaps 14 + activate 15 + setobjectcollisionbox 18 + classify 19 + deathnotice 20 + traceattack 21 + takedamage 22 + takehealth 23 + killed 24 + bloodcolor 25 + tracebleed 26 + istriggered 27 + mymonsterpointer 28 + mysquadmonsterpointer 29 + gettogglestate 30 + addpoints 31 + addpointstoteam 32 + addplayeritem 33 + removeplayeritem 34 + giveammo 35 + getdelay 36 + ismoving 37 + overridereset 38 + damagedecal 39 + settogglestate 40 + startsneaking 41 + stopsneaking 42 + oncontrols 43 + issneaking 44 + isalive 45 + isbspmodel 46 + reflectgauss 47 + hastarget 48 + isinworld 49 + isplayer 50 + isnetclient 51 + teamid 52 + getnexttarget 53 + think 54 + touch 55 + use 56 + blocked 57 + respawn 59 + updateowner 60 + fbecomeprone 61 + center 62 + eyeposition 63 + earposition 64 + bodytarget 65 + illumination 66 + fvisible 67 + fvecvisible 68 + + changeyaw 70 + hashumangibs 71 + hasaliengibs 72 + fademonster 73 + gibmonster 74 + getdeathactivity 75 + becomedead 76 + irelationship 78 + painsound 79 + reportaistate 80 + monsterinitdead 81 + look 82 + bestvisibleenemy 83 + finviewcone 84 + fvecinviewcone 85 + + player_jump 86 + player_duck 87 + player_prethink 88 + player_postthink 89 + player_getgunposition 90 + player_shouldfadeondeath 77 + player_impulsecommands 92 + player_updateclientdata 91 + + item_addtoplayer 70 + item_addduplicate 71 + item_candeploy 73 + item_deploy 74 + item_canholster 75 + item_holster 76 + item_updateiteminfo 77 + item_preframe 78 + item_postframe 79 + item_drop 80 + item_kill 81 + item_attachtoplayer 82 + item_primaryammoindex 83 + item_secondaryammoindex 84 + item_updateclientdata 85 + item_getweaponptr 86 + item_itemslot 87 + + weapon_extractammo 88 + weapon_extractclipammo 89 + weapon_addweapon 90 + weapon_playemptysound 91 + weapon_resetemptysound 92 + weapon_sendweaponanim 93 + weapon_isusable 94 + weapon_primaryattack 95 + weapon_secondaryattack 96 + weapon_reload 98 + weapon_weaponidle 99 + weapon_retireweapon 100 + weapon_shouldweaponidle 101 + weapon_usedecrement 102 + + ts_breakablerespawn 2 + ts_canusedthroughwalls 3 + ts_giveslowmul 4 + ts_goslow 5 + ts_inslow 6 + ts_isobjective 7 + ts_enableobjective 8 + ts_onfreeentprivatedata 12 + ts_shouldcollide 13 + + ts_weapon_alternateattack 97 +@end +@section ts windows + pev 4 + base 0x0 + + spawn 7 + precache 8 + keyvalue 9 + objectcaps 12 + activate 13 + setobjectcollisionbox 16 + classify 17 + deathnotice 18 + traceattack 19 + takedamage 20 + takehealth 21 + killed 22 + bloodcolor 23 + tracebleed 24 + istriggered 25 + mymonsterpointer 26 + mysquadmonsterpointer 27 + gettogglestate 28 + addpoints 29 + addpointstoteam 30 + addplayeritem 31 + removeplayeritem 32 + giveammo 33 + getdelay 34 + ismoving 35 + overridereset 36 + damagedecal 37 + settogglestate 38 + startsneaking 39 + stopsneaking 40 + oncontrols 41 + issneaking 42 + isalive 43 + isbspmodel 44 + reflectgauss 45 + hastarget 46 + isinworld 47 + isplayer 48 + isnetclient 49 + teamid 50 + getnexttarget 51 + think 52 + touch 53 + use 54 + blocked 55 + respawn 57 + updateowner 58 + fbecomeprone 59 + center 60 + eyeposition 61 + earposition 62 + bodytarget 63 + illumination 64 + fvisible 65 + fvecvisible 66 + + changeyaw 68 + hashumangibs 69 + hasaliengibs 70 + fademonster 71 + gibmonster 72 + getdeathactivity 73 + becomedead 74 + irelationship 76 + painsound 77 + reportaistate 78 + monsterinitdead 79 + look 80 + bestvisibleenemy 81 + finviewcone 82 + fvecinviewcone 83 + + player_jump 84 + player_duck 85 + player_prethink 86 + player_postthink 87 + player_getgunposition 88 + player_shouldfadeondeath 75 + player_impulsecommands 90 + player_updateclientdata 89 + + item_addtoplayer 68 + item_addduplicate 69 + item_candeploy 71 + item_deploy 72 + item_canholster 73 + item_holster 74 + item_updateiteminfo 75 + item_preframe 76 + item_postframe 77 + item_drop 78 + item_kill 79 + item_attachtoplayer 80 + item_primaryammoindex 81 + item_secondaryammoindex 82 + item_updateclientdata 83 + item_getweaponptr 84 + item_itemslot 85 + + weapon_extractammo 86 + weapon_extractclipammo 87 + weapon_addweapon 88 + weapon_playemptysound 89 + weapon_resetemptysound 90 + weapon_sendweaponanim 91 + weapon_isusable 92 + weapon_primaryattack 93 + weapon_secondaryattack 94 + weapon_reload 96 + weapon_weaponidle 97 + weapon_retireweapon 98 + weapon_shouldweaponidle 99 + weapon_usedecrement 100 + + ts_breakablerespawn 0 + ts_canusedthroughwalls 1 + ts_giveslowmul 2 + ts_goslow 3 + ts_inslow 4 + ts_isobjective 5 + ts_enableobjective 6 + ts_onfreeentprivatedata 10 + ts_shouldcollide 11 + + ts_weapon_alternateattack 95 +@end + +; Sven-Coop 5.17 +@section svencoop linux + pev 4 + base 0x0 + + spawn 1 + precache 3 + keyvalue 4 + objectcaps 9 + activate 10 + setobjectcollisionbox 11 + irelationship 14 + classify 15 + deathnotice 16 + traceattack 17 + takedamage 18 + killed 21 + bloodcolor 22 + tracebleed 23 + mymonsterpointer 25 + mysquadmonsterpointer 26 + gettogglestate 29 + addplayeritem 32 + getdelay 35 + overridereset 37 + damagedecal 38 + settogglestate 39 + startsneaking 40 + stopsneaking 41 + teamid 55 + getnexttarget 57 + think 58 + touch 59 + use 60 + blocked 61 + respawn 63 + updateowner 66 + fbecomeprone 67 + center 68 + eyeposition 69 + earposition 70 + bodytarget 71 + illumination 72 + + look 100 + runai 101 + changeyaw 104 + monsterthink 106 + monsterinit 107 + monsterinitdead 108 + becomedead 109 + bestvisibleenemy 112 + finviewcone 113 + fvecinviewcone 114 + checklocalmove 115 + move 116 + moveexecute 117 + shouldadvanceroute 118 + getstoppedactivity 119 + stop 120 + checkrangeattack1 121 + checkrangeattack2 123 + checkmeleeattack1 125 + checkmeleeattack2 127 + schedulechange 135 + playsentence 138 + sentencestop 140 + getidealstate 141 + setactivity 142 + reportaistate 144 + checkenemy 145 + setyawspeed 148 + buildnearestroute 149 + findcover 150 + coverradius 155 + fcancheckattacks 156 + checkammo 158 + ignoreconditions 159 + fvalidatehinttype 160 + fcanactiveidle 161 + isoundmask 162 + hearingsensitivity 165 + barnaclevictimbitten 166 + barnaclevictimreleased 167 + preschedulethink 174 + getdeathactivity 175 + gibmonster 176 + hashumangibs 178 + hasaliengibs 179 + fademonster 180 + deathsound 184 + alertsound 185 + idlesound 186 + painsound 187 + + player_getgunposition 181 + player_jump 208 + player_duck 209 + player_prethink 210 + player_postthink 211 + player_updateclientdata 216 + player_impulsecommands 217 + + item_holster 118 + item_updateiteminfo 119 + item_preframe 120 + item_postframe 121 + item_drop 132 + item_kill 102 + item_attachtoplayer 124 + item_primaryammoindex 126 + item_secondaryammoindex 127 + item_getweaponptr 129 + item_itemslot 130 + + weapon_extractammo 135 + weapon_extractclipammo 136 + weapon_resetemptysound 141 + weapon_sendweaponanim 142 + weapon_primaryattack 145 + weapon_secondaryattack 146 + weapon_reload 148 + weapon_weaponidle 151 + weapon_retireweapon 152 + + sc_prespawn 0 + sc_postspawn 2 + sc_onkeyvalueupdate 6 + sc_getclassification 12 + sc_setclassification 13 + sc_takehealth 19 + sc_takearmor 20 + sc_istriggered 24 + sc_mycustompointer 27 + sc_myitempointer 28 + sc_addpoints 30 + sc_addpointstoteam 31 + sc_removeplayeritem 33 + sc_giveammo 34 + sc_ismoving 36 + sc_oncontrols 42 + sc_issneaking 43 + sc_isalive 44 + sc_isbspmodel 45 + sc_reflectgauss 46 + sc_hastarget 47 + sc_isinworld 48 + sc_ismonster 49 + sc_isplayer 50 + sc_isnetclient 51 + sc_ispointentity 52 + sc_isbreakable 53 + sc_ismachine 54 + sc_criticalremove 56 + sc_updateonremove 62 + sc_subusetargets 64 + sc_islockedbymaster 65 + sc_fbecomeprone 67 + sc_fvisible 73 + sc_fvecvisible 74 + sc_fvisiblefrompos 75 + sc_isfacing 76 + sc_getpointsfordamage 77 + sc_getdamagepoints 78 + sc_setplayerally 79 + sc_oncreate 82 + sc_ondestroy 83 + sc_onsetoriginbymap 84 + sc_isrevivable 85 + sc_beginrevive 86 + sc_endrevive 87 + sc_shouldfadeondeath 103 + sc_setupfriendly 105 + sc_revive 110 + sc_startmonster 111 + sc_checkrangeattack1_move 122 + sc_checkrangeattack2_move 124 + sc_checkmeleeattack1_move 126 + sc_checkmeleeattack2_move 128 + sc_checktankusage 129 + sc_canplaysequence 136 + sc_canplaysentence2 137 + sc_playscriptedsentence 139 + sc_setgaitactivity 143 + sc_ftriangulate 145 + sc_ftriangulateextension 147 + sc_findcovergrenade 151 + sc_findcoverdistance 152 + sc_findattackpoint 153 + sc_fvalidatecover 154 + sc_checkattacker 157 + sc_nofriendlyfire1 168 + sc_nofriendlyfire2 169 + sc_nofriendlyfire3 170 + sc_nofriendlyfiretopos 171 + sc_fvisiblegunpos 172 + sc_finbulletcone 173 + sc_callgibmonster 177 + sc_checktimebaseddamage 182 + sc_isplayerfollowing 189 + sc_startplayerfollowing 193 + sc_stopplayerfollowing 194 + sc_usesound 196 + sc_unusesound 197 + sc_ridemonster 198 + sc_checkandapplygenericattacks 19ç + sc_checkscared 200 + sc_checkcreaturedanger 201 + sc_checkfalldamage 202 + sc_checkrevival 203 + sc_mediccallsound 206 + + sc_player_specialspawn 207 + sc_player_enteredobserver 212 + sc_player_leftobserver 213 + sc_player_isobserver 214 + sc_player_isconnected 215 + sc_player_isvalidinfoentity 218 + sc_player_levelend 219 + sc_player_votestarted 220 + sc_player_canstartnextvote 221 + sc_player_vote 222 + sc_player_hasvoted 223 + sc_player_resetvote 224 + sc_player_lastvoteinput 225 + sc_player_initvote 226 + sc_player_timetostartnextvote 227 + sc_player_resetview 228 + sc_player_getlogfrequency 229 + sc_player_logplayerstats 230 + + sc_item_materialize 100 + sc_item_cancollect 105 + sc_item_collect 106 + sc_item_addtoplayer 110 + sc_item_addduplicate 111 + sc_item_addammofromitem 112 + sc_item_getpickupsound 113 + sc_item_getiteminfo 114 + sc_item_candeploy 115 + sc_item_deploy 116 + sc_item_canholster 117 + sc_item_inactiveitempreframe 122 + sc_item_inactiveitempostframe 123 + sc_item_detachfromplayer 125 + sc_item_updateclientdata 128 + sc_item_getrespawntime 131 + sc_item_canhaveduplicates 133 + + sc_weapon_extractammofromitem 134 + sc_weapon_addweapon 137 + sc_weapon_getammo1drop 138 + sc_weapon_getammo2drop 139 + sc_weapon_playemptysound 140 + sc_weapon_bulletaccuracy 143 + sc_weapon_isusable 144 + sc_weapon_tertiaryattack 147 + sc_weapon_finishreload 149 + sc_weapon_shouldreload 150 + sc_weapon_shouldweaponidle 153 + sc_weapon_usedecrement 154 + sc_weapon_burstsupplement 155 + sc_weapon_getp_model 156 + sc_weapon_getw_model 157 + sc_weapon_getv_model 158 + sc_weapon_precachecustommodels 159 + sc_weapon_ismultiplayer 162 + sc_weapon_frunfuncs 163 + sc_weapon_setfov 164 + sc_weapon_fcanrun 165 + sc_weapon_customdecrement 166 + sc_weapon_setv_model 167 + sc_weapon_setp_model 168 + sc_weapon_changeweaponskin 169 +@end + +; Sven-Coop 5.17 +@section svencoop windows + pev 4 + base 0x0 + + spawn 1 + precache 3 + keyvalue 4 + objectcaps 9 + activate 10 + setobjectcollisionbox 11 + irelationship 14 + classify 15 + deathnotice 16 + traceattack 17 + takedamage 18 + killed 21 + bloodcolor 22 + tracebleed 23 + mymonsterpointer 25 + mysquadmonsterpointer 26 + gettogglestate 29 + addplayeritem 32 + getdelay 35 + overridereset 37 + damagedecal 38 + settogglestate 39 + startsneaking 40 + stopsneaking 41 + teamid 55 + getnexttarget 57 + think 58 + touch 59 + use 60 + blocked 61 + respawn 63 + updateowner 66 + center 68 + eyeposition 69 + earposition 70 + bodytarget 71 + illumination 72 + + look 99 + runai 100 + changeyaw 103 + monsterthink 105 + monsterinit 106 + monsterinitdead 107 + becomedead 108 + bestvisibleenemy 110 + finviewcone 113 + fvecinviewcone 112 + checklocalmove 114 + move 115 + moveexecute 116 + shouldadvanceroute 117 + getstoppedactivity 118 + stop 119 + checkrangeattack1 120 + checkrangeattack2 122 + checkmeleeattack1 124 + checkmeleeattack2 126 + schedulechange 134 + playsentence 137 + sentencestop 139 + getidealstate 140 + setactivity 141 + reportaistate 143 + checkenemy 144 + setyawspeed 147 + buildnearestroute 148 + findcover 149 + coverradius 154 + fcancheckattacks 155 + checkammo 157 + ignoreconditions 158 + fvalidatehinttype 159 + fcanactiveidle 160 + isoundmask 161 + hearingsensitivity 164 + barnaclevictimbitten 165 + barnaclevictimreleased 166 + preschedulethink 173 + getdeathactivity 174 + gibmonster 175 + hashumangibs 177 + hasaliengibs 178 + fademonster 179 + deathsound 183 + alertsound 184 + idlesound 185 + painsound 186 + + player_getgunposition 180 + player_jump 207 + player_duck 208 + player_prethink 209 + player_postthink 210 + player_updateclientdata 215 + player_impulsecommands 216 + + item_holster 117 + item_updateiteminfo 118 + item_preframe 119 + item_postframe 120 + item_drop 131 + item_kill 101 + item_attachtoplayer 123 + item_primaryammoindex 125 + item_secondaryammoindex 126 + item_getweaponptr 128 + item_itemslot 129 + + weapon_extractammo 134 + weapon_extractclipammo 135 + weapon_resetemptysound 140 + weapon_sendweaponanim 141 + weapon_primaryattack 144 + weapon_secondaryattack 145 + weapon_reload 147 + weapon_weaponidle 150 + weapon_retireweapon 151 + + sc_prespawn 0 + sc_postspawn 2 + sc_onkeyvalueupdate 6 + sc_getclassification 12 + sc_setclassification 13 + sc_takehealth 19 + sc_takearmor 20 + sc_istriggered 24 + sc_mycustompointer 27 + sc_myitempointer 28 + sc_addpoints 30 + sc_addpointstoteam 31 + sc_removeplayeritem 33 + sc_giveammo 34 + sc_ismoving 36 + sc_oncontrols 42 + sc_issneaking 43 + sc_isalive 44 + sc_isbspmodel 45 + sc_reflectgauss 46 + sc_hastarget 47 + sc_isinworld 48 + sc_ismonster 49 + sc_isplayer 50 + sc_isnetclient 51 + sc_ispointentity 52 + sc_isbreakable 53 + sc_ismachine 54 + sc_criticalremove 56 + sc_updateonremove 62 + sc_subusetargets 64 + sc_islockedbymaster 65 + sc_fbecomeprone 67 + sc_fvecvisible 73 + sc_fvisible 74 + sc_fvisiblefrompos 75 + sc_isfacing 76 + sc_getpointsfordamage 77 + sc_getdamagepoints 78 + sc_setplayerally 79 + sc_oncreate 81 + sc_ondestroy 82 + sc_onsetoriginbymap 83 + sc_isrevivable 84 + sc_beginrevive 85 + sc_endrevive 86 + sc_shouldfadeondeath 102 + sc_setupfriendly 104 + sc_revive 109 + sc_startmonster 110 + sc_checkrangeattack1_move 121 + sc_checkrangeattack2_move 123 + sc_checkmeleeattack1_move 125 + sc_checkmeleeattack2_move 127 + sc_checktankusage 128 + sc_canplaysequence 135 + sc_canplaysentence2 136 + sc_playscriptedsentence 138 + sc_setgaitactivity 142 + sc_ftriangulate 145 + sc_ftriangulateextension 146 + sc_findcovergrenade 150 + sc_findcoverdistance 151 + sc_findattackpoint 152 + sc_fvalidatecover 153 + sc_checkattacker 156 + sc_nofriendlyfire1 169 + sc_nofriendlyfire2 168 + sc_nofriendlyfire3 167 + sc_nofriendlyfiretopos 170 + sc_fvisiblegunpos 171 + sc_finbulletcone 172 + sc_callgibmonster 176 + sc_checktimebaseddamage 181 + sc_isplayerfollowing 188 + sc_startplayerfollowing 192 + sc_stopplayerfollowing 193 + sc_usesound 195 + sc_unusesound 196 + sc_ridemonster 197 + sc_checkandapplygenericattacks 198 + sc_checkscared 199 + sc_checkcreaturedanger 200 + sc_checkfalldamage 201 + sc_checkrevival 202 + sc_mediccallsound 205 + + sc_player_specialspawn 206 + sc_player_enteredobserver 211 + sc_player_leftobserver 212 + sc_player_isobserver 213 + sc_player_isconnected 214 + sc_player_isvalidinfoentity 217 + sc_player_levelend 218 + sc_player_votestarted 219 + sc_player_canstartnextvote 220 + sc_player_vote 221 + sc_player_hasvoted 222 + sc_player_resetvote 223 + sc_player_lastvoteinput 224 + sc_player_initvote 225 + sc_player_timetostartnextvote 226 + sc_player_resetview 227 + sc_player_getlogfrequency 228 + sc_player_logplayerstats 229 + + sc_item_materialize 99 + sc_item_cancollect 104 + sc_item_collect 105 + sc_item_addtoplayer 109 + sc_item_addduplicate 110 + sc_item_addammofromitem 111 + sc_item_getpickupsound 112 + sc_item_getiteminfo 113 + sc_item_candeploy 114 + sc_item_deploy 115 + sc_item_canholster 116 + sc_item_inactiveitempreframe 121 + sc_item_inactiveitempostframe 122 + sc_item_detachfromplayer 125 + sc_item_updateclientdata 127 + sc_item_getrespawntime 130 + sc_item_canhaveduplicates 132 + + sc_weapon_extractammofromitem 133 + sc_weapon_addweapon 136 + sc_weapon_getammo1drop 137 + sc_weapon_getammo2drop 138 + sc_weapon_playemptysound 139 + sc_weapon_bulletaccuracy 142 + sc_weapon_isusable 143 + sc_weapon_tertiaryattack 146 + sc_weapon_finishreload 148 + sc_weapon_shouldreload 149 + sc_weapon_shouldweaponidle 152 + sc_weapon_usedecrement 153 + sc_weapon_burstsupplement 154 + sc_weapon_getp_model 155 + sc_weapon_getw_model 156 + sc_weapon_getv_model 157 + sc_weapon_precachecustommodels 158 + sc_weapon_ismultiplayer 161 + sc_weapon_frunfuncs 162 + sc_weapon_setfov 163 + sc_weapon_fcanrun 164 + sc_weapon_customdecrement 165 + sc_weapon_setv_model 166 + sc_weapon_setp_model 167 + sc_weapon_changeweaponskin 168 +@end + +; Earth's Special Forces 1.2.3 +@section esf linux + pev 0 + base 0x60 + + spawn 2 + precache 3 + keyvalue 4 + objectcaps 7 + activate 8 + setobjectcollisionbox 9 + classify 10 + deathnotice 11 + traceattack 12 + takedamage 13 + takehealth 14 + killed 15 + bloodcolor 16 + tracebleed 17 + istriggered 18 + mymonsterpointer 19 + mysquadmonsterpointer 20 + gettogglestate 21 + addpoints 22 + addpointstoteam 23 + addplayeritem 24 + removeplayeritem 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvisible 56 + fvecvisible 57 + + look 59 + changeyaw 62 + irelationship 64 + monsterinitdead 66 + becomedead 67 + bestvisibleenemy 69 + finviewcone 70 + fvecinviewcone 71 + + runai 60 + monsterthink 63 + monsterinit 65 + checklocalmove 72 + move 73 + moveexecute 74 + shouldadvanceroute 75 + getstoppedactivity 76 + stop 77 + checkrangeattack1 78 + checkrangeattack2 79 + checkmeleeattack1 80 + checkmeleeattack2 81 + schedulechange 87 + canplaysequence 88 + canplaysentence2 89 + playsentence 90 + playscriptedsentence 91 + sentencestop 92 + getidealstate 93 + setactivity 94 + reportaistate 95 + checkenemy 96 + ftriangulate 97 + setyawspeed 98 + buildnearestroute 99 + findcover 100 + coverradius 102 + fcancheckattacks 103 + checkammo 104 + ignoreconditions 105 + fvalidatehinttype 106 + fcanactiveidle 107 + isoundmask 108 + hearingsensitivity 111 + barnaclevictimbitten 112 + barnaclevictimreleased 113 + preschedulethink 114 + getdeathactivity 115 + gibmonster 116 + hashumangibs 117 + hasaliengibs 118 + fademonster 119 + deathsound 121 + alertsound 122 + idlesound 123 + painsound 124 + stopfollowing 125 + + player_jump 126 + player_prethink 127 + player_postthink 128 + player_getgunposition 120 + player_shouldfadeondeath 61 + player_impulsecommands 130 + player_updateclientdata 129 + + item_addtoplayer 59 + item_addduplicate 60 + item_getiteminfo 61 + item_candeploy 62 + item_deploy 63 + item_canholster 64 + item_holster 65 + item_updateiteminfo 66 + item_preframe 67 + item_postframe 68 + item_drop 69 + item_kill 70 + item_attachtoplayer 71 + item_primaryammoindex 72 + item_secondaryammoindex 73 + item_updateclientdata 74 + item_getweaponptr 75 + item_itemslot 76 + + weapon_playemptysound 77 + weapon_resetemptysound 78 + weapon_sendweaponanim 79 + weapon_primaryattack 80 + weapon_secondaryattack 81 + weapon_weaponidle 82 + weapon_retireweapon 83 + weapon_shouldweaponidle 84 + weapon_usedecrement 85 + + esf_weapon_holsterwhenmeleed 86 +@end + +@section esf windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 19 + addpoints 20 + addpointstoteam 21 + addplayeritem 22 + removeplayeritem 23 + getdelay 24 + ismoving 25 + overridereset 26 + damagedecal 27 + settogglestate 28 + startsneaking 29 + stopsneaking 30 + oncontrols 31 + issneaking 32 + isalive 33 + isbspmodel 34 + reflectgauss 35 + hastarget 36 + isinworld 37 + isplayer 38 + isnetclient 39 + teamid 40 + getnexttarget 41 + think 42 + touch 43 + use 44 + blocked 45 + respawn 46 + updateowner 47 + fbecomeprone 48 + center 49 + eyeposition 50 + earposition 51 + bodytarget 52 + illumination 53 + fvisible 54 + fvecvisible 55 + + look 57 + changeyaw 60 + irelationship 62 + monsterinitdead 64 + becomedead 65 + bestvisibleenemy 67 + finviewcone 68 + fvecinviewcone 69 + + runai 58 + monsterthink 61 + monsterinit 63 + checklocalmove 70 + move 71 + moveexecute 72 + shouldadvanceroute 73 + getstoppedactivity 74 + stop 75 + checkrangeattack1 76 + checkrangeattack2 77 + checkmeleeattack1 78 + checkmeleeattack2 79 + schedulechange 85 + canplaysequence 86 + canplaysentence2 87 + playsentence 88 + playscriptedsentence 89 + sentencestop 90 + getidealstate 91 + setactivity 92 + reportaistate 93 + checkenemy 94 + ftriangulate 95 + setyawspeed 96 + buildnearestroute 97 + findcover 98 + coverradius 100 + fcancheckattacks 101 + checkammo 102 + ignoreconditions 103 + fvalidatehinttype 104 + fcanactiveidle 105 + isoundmask 106 + hearingsensitivity 109 + barnaclevictimbitten 110 + barnaclevictimreleased 111 + preschedulethink 112 + getdeathactivity 113 + gibmonster 114 + hashumangibs 115 + hasaliengibs 116 + fademonster 117 + deathsound 119 + alertsound 120 + idlesound 121 + painsound 122 + stopfollowing 123 + + player_jump 124 + player_prethink 125 + player_postthink 126 + player_getgunposition 118 + player_shouldfadeondeath 59 + player_impulsecommands 128 + player_updateclientdata 127 + + item_addtoplayer 57 + item_addduplicate 58 + item_getiteminfo 59 + item_candeploy 60 + item_deploy 61 + item_canholster 62 + item_holster 63 + item_updateiteminfo 64 + item_preframe 65 + item_postframe 66 + item_drop 67 + item_kill 68 + item_attachtoplayer 69 + item_primaryammoindex 70 + item_secondaryammoindex 71 + item_updateclientdata 72 + item_getweaponptr 73 + item_itemslot 74 + + weapon_playemptysound 75 + weapon_resetemptysound 76 + weapon_sendweaponanim 77 + weapon_primaryattack 78 + weapon_secondaryattack 79 + weapon_weaponidle 80 + weapon_retireweapon 81 + weapon_shouldweaponidle 82 + weapon_usedecrement 83 + + esf_weapon_holsterwhenmeleed 84 +@end + +; ESF Open Beta is built with GCC 3.x, and the VTable was slightly changed +@section esf_openbeta linux + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 13 + killed 14 + bloodcolor 15 + tracebleed 16 + istriggered 17 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 43 + teamid 44 + getnexttarget 47 + think 48 + touch 49 + use 50 + blocked 51 + respawn 52 + updateowner 53 + fbecomeprone 54 + center 55 + eyeposition 56 + earposition 57 + bodytarget 58 + illumination 59 + fvisible 60 + fvecvisible 61 + + look 63 + changeyaw 66 + irelationship 68 + monsterinitdead 70 + becomedead 71 + bestvisibleenemy 73 + finviewcone 74 + fvecinviewcone 75 + + runai 64 + monsterthink 67 + monsterinit 69 + checklocalmove 76 + move 77 + moveexecute 78 + shouldadvanceroute 79 + getstoppedactivity 80 + stop 81 + checkrangeattack1 82 + checkrangeattack2 83 + checkmeleeattack1 84 + checkmeleeattack2 85 + schedulechange 91 + canplaysequence 92 + canplaysentence2 93 + playsentence 94 + playscriptedsentence 95 + sentencestop 96 + getidealstate 97 + setactivity 98 + reportaistate 99 + checkenemy 100 + ftriangulate 101 + setyawspeed 102 + buildnearestroute 103 + findcover 104 + coverradius 106 + fcancheckattacks 107 + checkammo 108 + ignoreconditions 109 + fvalidatehinttype 110 + fcanactiveidle 111 + isoundmask 112 + hearingsensitivity 115 + barnaclevictimbitten 116 + barnaclevictimreleased 117 + preschedulethink 118 + getdeathactivity 119 + gibmonster 120 + hashumangibs 121 + hasaliengibs 122 + fademonster 123 + deathsound 125 + alertsound 126 + idlesound 127 + painsound 128 + stopfollowing 129 + + player_updateclientdata 186 + player_jump 187 + player_prethink 189 + player_postthink 190 + player_getgunposition 124 + player_shouldfadeondeath 65 + player_impulsecommands 193 + + item_addtoplayer 63 + item_addduplicate 64 + item_getiteminfo 65 + item_candeploy 66 + item_deploy 67 + item_canholster 68 + item_holster 69 + item_updateiteminfo 70 + item_preframe 71 + item_postframe 72 + item_drop 73 + item_kill 74 + item_attachtoplayer 75 + item_primaryammoindex 76 + item_secondaryammoindex 77 + item_updateclientdata 78 + item_getweaponptr 79 + item_itemslot 80 + + weapon_playemptysound 81 + weapon_resetemptysound 82 + weapon_sendweaponanim 83 + weapon_primaryattack 84 + weapon_secondaryattack 85 + weapon_weaponidle 86 + weapon_retireweapon 87 + weapon_shouldweaponidle 88 + weapon_usedecrement 89 + + esf_isenvmodel 40 + esf_takedamage2 12 + esf_isfighter 41 + esf_isbuddy 42 + esf_emitsound 45 + esf_emitnullsound 46 + esf_increasestrength 130 + esf_increasepl 131 + esf_setpowerlevel 132 + esf_setmaxpowerlevel 133 + esf_stopanitrigger 134 + esf_stopfly 135 + esf_hideweapon 136 + esf_clientremoveweapon 137 + esf_sendclientcustommodel 138 + esf_canturbo 139 + esf_canprimaryfire 140 + esf_cansecondaryfire 141 + esf_canstopfly 142 + esf_canblock 143 + esf_canraiseKi 144 + esf_canraisestamina 145 + esf_canteleport 146 + esf_canstartfly 147 + esf_canstartpowerup 148 + esf_canjump 149 + esf_canwalljump 150 + esf_issuperjump 151 + esf_ismoveback 152 + esf_checkwalljump 153 + esf_enablewalljump 154 + esf_disablewalljump 155 + esf_resetwalljumpvars 156 + esf_getwalljumpanim 157 + esf_getwalljumpanim2 158 + esf_setwalljumpanimation 159 + esf_setflymovetype 160 + esf_isflymovetype 161 + esf_iswalkmovetype 162 + esf_setwalkmovetype 163 + esf_drawchargebar 164 + esf_startblock 165 + esf_stopblock 166 + esf_startfly 167 + esf_getmaxspeed 168 + esf_setanimation 169 + esf_playanimation 170 + esf_getmoveforward 171 + esf_getmoveright 172 + esf_getmoveup 173 + esf_addblindfx 174 + esf_removeblindfx 175 + esf_disablepsbar 176 + esf_addbeamboxcrosshair 177 + esf_removebeamboxcrosshair 178 + esf_drawpswinbonus 179 + esf_drawpsbar 180 + esf_lockcrosshair 181 + esf_unlockcrosshair 182 + esf_rotatecrosshair 183 + esf_unrotatecrosshair 184 + esf_watermove 185 + esf_checktimebaseddamage 188 + esf_doessecondaryattack 191 + esf_doesprimaryattack 192 + esf_removespecialmodes 194 + esf_stopturbo 195 + esf_takebean 196 + esf_getpowerlevel 197 + esf_removeallotherweapons 198 + esf_stopswoop 199 + esf_setdeathanimation 201 + esf_setmodel 202 + esf_addattacks 203 + esf_emitclasssound 205 + esf_checklightning 206 + esf_freezecontrols 207 + esf_unfreezecontrols 208 + esf_updateki 209 + esf_updatehealth 210 + esf_getteleportdir 211 + + esf_weapon_holsterwhenmeleed 90 + +@end +@section esf_openbeta windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 13 + killed 14 + bloodcolor 15 + tracebleed 16 + istriggered 17 + mymonsterpointer 18 + mysquadmonsterpointer 19 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 43 + teamid 44 + getnexttarget 47 + think 48 + touch 49 + use 50 + blocked 51 + respawn 52 + updateowner 53 + fbecomeprone 54 + center 55 + eyeposition 56 + earposition 57 + bodytarget 58 + illumination 59 + fvisible 60 + fvecvisible 61 + + look 63 + changeyaw 66 + irelationship 68 + monsterinitdead 70 + becomedead 71 + bestvisibleenemy 73 + finviewcone 74 + fvecinviewcone 75 + + runai 64 + monsterthink 67 + monsterinit 69 + checklocalmove 76 + move 77 + moveexecute 78 + shouldadvanceroute 79 + getstoppedactivity 80 + stop 81 + checkrangeattack1 82 + checkrangeattack2 83 + checkmeleeattack1 84 + checkmeleeattack2 85 + schedulechange 91 + canplaysequence 92 + canplaysentence2 93 + playsentence 94 + playscriptedsentence 95 + sentencestop 96 + getidealstate 97 + setactivity 98 + reportaistate 99 + checkenemy 100 + ftriangulate 101 + setyawspeed 102 + buildnearestroute 103 + findcover 104 + coverradius 106 + fcancheckattacks 107 + checkammo 108 + ignoreconditions 109 + fvalidatehinttype 110 + fcanactiveidle 111 + isoundmask 112 + hearingsensitivity 115 + barnaclevictimbitten 116 + barnaclevictimreleased 117 + preschedulethink 118 + getdeathactivity 119 + gibmonster 120 + hashumangibs 121 + hasaliengibs 122 + fademonster 123 + deathsound 125 + alertsound 126 + idlesound 127 + painsound 128 + stopfollowing 129 + + player_updateclientdata 186 + player_jump 187 + player_prethink 189 + player_postthink 190 + player_getgunposition 124 + player_shouldfadeondeath 65 + player_impulsecommands 193 + + item_addtoplayer 63 + item_addduplicate 64 + item_getiteminfo 65 + item_candeploy 66 + item_deploy 67 + item_canholster 68 + item_holster 69 + item_updateiteminfo 70 + item_preframe 71 + item_postframe 72 + item_drop 73 + item_kill 74 + item_attachtoplayer 75 + item_primaryammoindex 76 + item_secondaryammoindex 77 + item_updateclientdata 78 + item_getweaponptr 79 + item_itemslot 80 + + weapon_playemptysound 81 + weapon_resetemptysound 82 + weapon_sendweaponanim 83 + weapon_primaryattack 84 + weapon_secondaryattack 85 + weapon_weaponidle 86 + weapon_retireweapon 87 + weapon_shouldweaponidle 88 + weapon_usedecrement 89 + + esf_isenvmodel 40 + esf_takedamage2 12 + esf_isfighter 41 + esf_isbuddy 42 + esf_emitsound 45 + esf_emitnullsound 46 + esf_increasestrength 130 + esf_increasepl 131 + esf_setpowerlevel 132 + esf_setmaxpowerlevel 133 + esf_stopanitrigger 134 + esf_stopfly 135 + esf_hideweapon 136 + esf_clientremoveweapon 137 + esf_sendclientcustommodel 138 + esf_canturbo 139 + esf_canprimaryfire 140 + esf_cansecondaryfire 141 + esf_canstopfly 142 + esf_canblock 143 + esf_canraiseKi 144 + esf_canraisestamina 145 + esf_canteleport 146 + esf_canstartfly 147 + esf_canstartpowerup 148 + esf_canjump 149 + esf_canwalljump 150 + esf_issuperjump 151 + esf_ismoveback 152 + esf_checkwalljump 153 + esf_enablewalljump 154 + esf_disablewalljump 155 + esf_resetwalljumpvars 156 + esf_getwalljumpanim 157 + esf_getwalljumpanim2 158 + esf_setwalljumpanimation 159 + esf_setflymovetype 160 + esf_isflymovetype 161 + esf_iswalkmovetype 162 + esf_setwalkmovetype 163 + esf_drawchargebar 164 + esf_startblock 165 + esf_stopblock 166 + esf_startfly 167 + esf_getmaxspeed 168 + esf_setanimation 169 + esf_playanimation 170 + esf_getmoveforward 171 + esf_getmoveright 172 + esf_getmoveup 173 + esf_addblindfx 174 + esf_removeblindfx 175 + esf_disablepsbar 176 + esf_addbeamboxcrosshair 177 + esf_removebeamboxcrosshair 178 + esf_drawpswinbonus 179 + esf_drawpsbar 180 + esf_lockcrosshair 181 + esf_unlockcrosshair 182 + esf_rotatecrosshair 183 + esf_unrotatecrosshair 184 + esf_watermove 185 + esf_checktimebaseddamage 188 + esf_doessecondaryattack 191 + esf_doesprimaryattack 192 + esf_removespecialmodes 194 + esf_stopturbo 195 + esf_takebean 196 + esf_getpowerlevel 197 + esf_removeallotherweapons 198 + esf_stopswoop 199 + esf_setdeathanimation 201 + esf_setmodel 202 + esf_addattacks 203 + esf_emitclasssound 205 + esf_checklightning 206 + esf_freezecontrols 207 + esf_unfreezecontrols 208 + esf_updateki 209 + esf_updatehealth 210 + esf_getteleportdir 211 + + esf_weapon_holsterwhenmeleed 90 + +@end +@section valve linux + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 19 + addpoints 20 + addpointstoteam 21 + addplayeritem 22 + removeplayeritem 23 + giveammo 24 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 40 + teamid 41 + getnexttarget 42 + think 43 + touch 44 + use 45 + blocked 46 + respawn 47 + updateowner 48 + fbecomeprone 49 + center 50 + eyeposition 51 + earposition 52 + bodytarget 53 + illumination 54 + fvisible 55 + fvecvisible 56 + + look 58 + changeyaw 61 + irelationship 63 + monsterinitdead 65 + becomedead 66 + bestvisibleenemy 68 + finviewcone 69 + fvecinviewcone 70 + + runai 59 + monsterthink 62 + monsterinit 64 + checklocalmove 71 + move 72 + moveexecute 73 + shouldadvanceroute 74 + getstoppedactivity 75 + stop 76 + checkrangeattack1 77 + checkrangeattack2 78 + checkmeleeattack1 79 + checkmeleeattack2 80 + schedulechange 86 + canplaysequence 87 + canplaysentence2 88 + playsentence 89 + playscriptedsentence 90 + sentencestop 91 + getidealstate 92 + setactivity 93 + reportaistate 94 + checkenemy 95 + ftriangulate 96 + setyawspeed 97 + buildnearestroute 98 + findcover 99 + coverradius 101 + fcancheckattacks 102 + checkammo 103 + ignoreconditions 104 + fvalidatehinttype 105 + fcanactiveidle 106 + isoundmask 107 + hearingsensitivity 110 + barnaclevictimbitten 111 + barnaclevictimreleased 112 + preschedulethink 113 + getdeathactivity 114 + gibmonster 115 + hashumangibs 116 + hasaliengibs 117 + fademonster 118 + deathsound 120 + alertsound 121 + idlesound 122 + painsound 123 + stopfollowing 124 + + player_jump 125 + player_duck 126 + player_prethink 127 + player_postthink 128 + player_getgunposition 119 + player_shouldfadeondeath 60 + player_impulsecommands 130 + player_updateclientdata 129 + + item_addtoplayer 58 + item_addduplicate 59 + item_getiteminfo 60 + item_candeploy 61 + item_deploy 62 + item_canholster 63 + item_holster 64 + item_updateiteminfo 65 + item_preframe 66 + item_postframe 67 + item_drop 68 + item_kill 69 + item_attachtoplayer 70 + item_primaryammoindex 71 + item_secondaryammoindex 72 + item_updateclientdata 73 + item_getweaponptr 74 + item_itemslot 75 + + weapon_extractammo 76 + weapon_extractclipammo 77 + weapon_addweapon 78 + weapon_playemptysound 79 + weapon_resetemptysound 80 + weapon_sendweaponanim 81 + weapon_isusable 82 + weapon_primaryattack 83 + weapon_secondaryattack 84 + weapon_reload 85 + weapon_weaponidle 86 + weapon_retireweapon 87 + weapon_shouldweaponidle 88 + weapon_usedecrement 89 +@end +@section valve windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 19 + addpoints 20 + addpointstoteam 21 + addplayeritem 22 + removeplayeritem 23 + giveammo 24 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 40 + teamid 41 + getnexttarget 42 + think 43 + touch 44 + use 45 + blocked 46 + respawn 47 + updateowner 48 + fbecomeprone 49 + center 50 + eyeposition 51 + earposition 52 + bodytarget 53 + illumination 54 + fvisible 55 + fvecvisible 56 + + look 58 + changeyaw 61 + irelationship 63 + monsterinitdead 65 + becomedead 66 + bestvisibleenemy 68 + finviewcone 69 + fvecinviewcone 70 + + runai 59 + monsterthink 62 + monsterinit 64 + checklocalmove 71 + move 72 + moveexecute 73 + shouldadvanceroute 74 + getstoppedactivity 75 + stop 76 + checkrangeattack1 77 + checkrangeattack2 78 + checkmeleeattack1 79 + checkmeleeattack2 80 + schedulechange 86 + canplaysequence 87 + canplaysentence2 88 + playsentence 89 + playscriptedsentence 90 + sentencestop 91 + getidealstate 92 + setactivity 93 + reportaistate 94 + checkenemy 95 + ftriangulate 96 + setyawspeed 97 + buildnearestroute 98 + findcover 99 + coverradius 101 + fcancheckattacks 102 + checkammo 103 + ignoreconditions 104 + fvalidatehinttype 105 + fcanactiveidle 106 + isoundmask 107 + hearingsensitivity 110 + barnaclevictimbitten 111 + barnaclevictimreleased 112 + preschedulethink 113 + getdeathactivity 114 + gibmonster 115 + hashumangibs 116 + hasaliengibs 117 + fademonster 118 + deathsound 120 + alertsound 121 + idlesound 122 + painsound 123 + stopfollowing 124 + + player_jump 125 + player_duck 126 + player_prethink 127 + player_postthink 128 + player_getgunposition 119 + player_shouldfadeondeath 60 + player_impulsecommands 130 + player_updateclientdata 129 + + item_addtoplayer 58 + item_addduplicate 59 + item_getiteminfo 60 + item_candeploy 61 + item_deploy 62 + item_canholster 63 + item_holster 64 + item_updateiteminfo 65 + item_preframe 66 + item_postframe 67 + item_drop 68 + item_kill 69 + item_attachtoplayer 70 + item_primaryammoindex 71 + item_secondaryammoindex 72 + item_updateclientdata 73 + item_getweaponptr 74 + item_itemslot 75 + + weapon_extractammo 76 + weapon_extractclipammo 77 + weapon_addweapon 78 + weapon_playemptysound 79 + weapon_resetemptysound 80 + weapon_sendweaponanim 81 + weapon_isusable 82 + weapon_primaryattack 83 + weapon_secondaryattack 84 + weapon_reload 85 + weapon_weaponidle 86 + weapon_retireweapon 87 + weapon_shouldweaponidle 88 + weapon_usedecrement 89 +@end + +@section valve mac + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 19 + addpoints 20 + addpointstoteam 21 + addplayeritem 22 + removeplayeritem 23 + giveammo 24 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 40 + teamid 41 + getnexttarget 42 + think 43 + touch 44 + use 45 + blocked 46 + respawn 47 + updateowner 48 + fbecomeprone 49 + center 50 + eyeposition 51 + earposition 52 + bodytarget 53 + illumination 54 + fvisible 55 + fvecvisible 56 + + look 58 + changeyaw 61 + irelationship 63 + monsterinitdead 65 + becomedead 66 + bestvisibleenemy 68 + finviewcone 69 + fvecinviewcone 70 + + runai 59 + monsterthink 62 + monsterinit 64 + checklocalmove 71 + move 72 + moveexecute 73 + shouldadvanceroute 74 + getstoppedactivity 75 + stop 76 + checkrangeattack1 77 + checkrangeattack2 78 + checkmeleeattack1 79 + checkmeleeattack2 80 + schedulechange 86 + canplaysequence 87 + canplaysentence2 88 + playsentence 89 + playscriptedsentence 90 + sentencestop 91 + getidealstate 92 + setactivity 93 + reportaistate 94 + checkenemy 95 + ftriangulate 96 + setyawspeed 97 + buildnearestroute 98 + findcover 99 + coverradius 101 + fcancheckattacks 102 + checkammo 103 + ignoreconditions 104 + fvalidatehinttype 105 + fcanactiveidle 106 + isoundmask 107 + hearingsensitivity 110 + barnaclevictimbitten 111 + barnaclevictimreleased 112 + preschedulethink 113 + getdeathactivity 114 + gibmonster 115 + hashumangibs 116 + hasaliengibs 117 + fademonster 118 + deathsound 120 + alertsound 121 + idlesound 122 + painsound 123 + stopfollowing 124 + + player_jump 125 + player_duck 126 + player_prethink 127 + player_postthink 128 + player_getgunposition 119 + player_shouldfadeondeath 60 + player_impulsecommands 130 + player_updateclientdata 129 + + item_addtoplayer 58 + item_addduplicate 59 + item_getiteminfo 60 + item_candeploy 61 + item_deploy 62 + item_canholster 63 + item_holster 64 + item_updateiteminfo 65 + item_preframe 66 + item_postframe 67 + item_drop 68 + item_kill 69 + item_attachtoplayer 70 + item_primaryammoindex 71 + item_secondaryammoindex 72 + item_updateclientdata 73 + item_getweaponptr 74 + item_itemslot 75 + + weapon_extractammo 76 + weapon_extractclipammo 77 + weapon_addweapon 78 + weapon_playemptysound 79 + weapon_resetemptysound 80 + weapon_sendweaponanim 81 + weapon_isusable 82 + weapon_primaryattack 83 + weapon_secondaryattack 84 + weapon_reload 85 + weapon_weaponidle 86 + weapon_retireweapon 87 + weapon_shouldweaponidle 88 + weapon_usedecrement 89 +@end + +@section gearbox windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + giveammo 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvisible 57 + fvecvisible 56 + + look 60 + changeyaw 63 + irelationship 65 + monsterinitdead 67 + becomedead 68 + bestvisibleenemy 70 + finviewcone 72 + fvecinviewcone 71 + + runai 61 + monsterthink 64 + monsterinit 66 + checklocalmove 73 + move 74 + moveexecute 75 + shouldadvanceroute 76 + getstoppedactivity 77 + stop 78 + checkrangeattack1 79 + checkrangeattack2 80 + checkmeleeattack1 81 + checkmeleeattack2 82 + schedulechange 88 + canplaysequence 89 + canplaysentence2 90 + playsentence 91 + playscriptedsentence 92 + sentencestop 93 + getidealstate 94 + setactivity 95 + reportaistate 96 + checkenemy 97 + ftriangulate 98 + setyawspeed 99 + buildnearestroute 100 + findcover 101 + coverradius 103 + fcancheckattacks 104 + checkammo 105 + ignoreconditions 106 + fvalidatehinttype 107 + fcanactiveidle 108 + isoundmask 109 + hearingsensitivity 112 + barnaclevictimbitten 113 + barnaclevictimreleased 114 + preschedulethink 115 + getdeathactivity 116 + gibmonster 117 + hashumangibs 118 + hasaliengibs 119 + fademonster 120 + deathsound 123 + alertsound 124 + idlesound 125 + painsound 126 + stopfollowing 127 + + player_jump 127 + player_duck 128 + player_prethink 129 + player_postthink 130 + player_getgunposition 121 + player_shouldfadeondeath 62 + player_impulsecommands 132 + player_updateclientdata 131 + + item_addtoplayer 60 + item_addduplicate 61 + item_getiteminfo 62 + item_candeploy 63 + item_deploy 64 + item_canholster 65 + item_holster 66 + item_updateiteminfo 67 + item_preframe 68 + item_postframe 69 + item_drop 70 + item_kill 71 + item_attachtoplayer 72 + item_primaryammoindex 73 + item_secondaryammoindex 74 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 78 + + weapon_extractammo 79 + weapon_extractclipammo 80 + weapon_addweapon 81 + weapon_playemptysound 82 + weapon_resetemptysound 83 + weapon_sendweaponanim 84 + weapon_isusable 85 + weapon_primaryattack 86 + weapon_secondaryattack 87 + weapon_reload 88 + weapon_weaponidle 89 + weapon_retireweapon 90 + weapon_shouldweaponidle 91 + weapon_usedecrement 92 + + gearbox_mysquadtalkmonsterpointer 19 + gearbox_weapontimebase 58 +@end + +@section gearbox linux + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + giveammo 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvisible 56 + fvecvisible 57 + + look 60 + changeyaw 63 + irelationship 65 + monsterinitdead 67 + becomedead 68 + bestvisibleenemy 70 + finviewcone 71 + fvecinviewcone 72 + + runai 61 + monsterthink 64 + monsterinit 66 + checklocalmove 73 + move 74 + moveexecute 75 + shouldadvanceroute 76 + getstoppedactivity 77 + stop 78 + checkrangeattack1 79 + checkrangeattack2 80 + checkmeleeattack1 81 + checkmeleeattack2 82 + schedulechange 88 + canplaysequence 89 + canplaysentence2 90 + playsentence 91 + playscriptedsentence 92 + sentencestop 93 + getidealstate 94 + setactivity 95 + reportaistate 96 + checkenemy 97 + ftriangulate 98 + setyawspeed 99 + buildnearestroute 100 + findcover 101 + coverradius 103 + fcancheckattacks 104 + checkammo 105 + ignoreconditions 106 + fvalidatehinttype 107 + fcanactiveidle 108 + isoundmask 109 + hearingsensitivity 112 + barnaclevictimbitten 113 + barnaclevictimreleased 114 + preschedulethink 115 + getdeathactivity 116 + gibmonster 117 + hashumangibs 118 + hasaliengibs 119 + fademonster 120 + deathsound 123 + alertsound 124 + idlesound 125 + painsound 126 + stopfollowing 127 + + player_jump 127 + player_duck 128 + player_prethink 129 + player_postthink 130 + player_getgunposition 121 + player_shouldfadeondeath 62 + player_impulsecommands 132 + player_updateclientdata 131 + + item_addtoplayer 60 + item_addduplicate 61 + item_getiteminfo 62 + item_candeploy 63 + item_deploy 64 + item_canholster 65 + item_holster 66 + item_updateiteminfo 67 + item_preframe 68 + item_postframe 69 + item_drop 70 + item_kill 71 + item_attachtoplayer 72 + item_primaryammoindex 73 + item_secondaryammoindex 74 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 78 + + weapon_extractammo 79 + weapon_extractclipammo 80 + weapon_addweapon 81 + weapon_playemptysound 82 + weapon_resetemptysound 83 + weapon_sendweaponanim 84 + weapon_isusable 85 + weapon_primaryattack 86 + weapon_secondaryattack 87 + weapon_reload 88 + weapon_weaponidle 89 + weapon_retireweapon 90 + weapon_shouldweaponidle 91 + weapon_usedecrement 92 + + gearbox_mysquadtalkmonsterpointer 19 + gearbox_weapontimebase 58 +@end + +@section gearbox mac + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 20 + addpoints 21 + addpointstoteam 22 + addplayeritem 23 + removeplayeritem 24 + giveammo 25 + getdelay 26 + ismoving 27 + overridereset 28 + damagedecal 29 + settogglestate 30 + startsneaking 31 + stopsneaking 32 + oncontrols 33 + issneaking 34 + isalive 35 + isbspmodel 36 + reflectgauss 37 + hastarget 38 + isinworld 39 + isplayer 40 + isnetclient 41 + teamid 42 + getnexttarget 43 + think 44 + touch 45 + use 46 + blocked 47 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvisible 56 + fvecvisible 57 + + look 60 + changeyaw 63 + irelationship 65 + monsterinitdead 67 + becomedead 68 + bestvisibleenemy 70 + finviewcone 71 + fvecinviewcone 72 + + runai 61 + monsterthink 64 + monsterinit 66 + checklocalmove 73 + move 74 + moveexecute 75 + shouldadvanceroute 76 + getstoppedactivity 77 + stop 78 + checkrangeattack1 79 + checkrangeattack2 80 + checkmeleeattack1 81 + checkmeleeattack2 82 + schedulechange 88 + canplaysequence 89 + canplaysentence2 90 + playsentence 91 + playscriptedsentence 92 + sentencestop 93 + getidealstate 94 + setactivity 95 + reportaistate 96 + checkenemy 97 + ftriangulate 98 + setyawspeed 99 + buildnearestroute 100 + findcover 101 + coverradius 103 + fcancheckattacks 104 + checkammo 105 + ignoreconditions 106 + fvalidatehinttype 107 + fcanactiveidle 108 + isoundmask 109 + hearingsensitivity 112 + barnaclevictimbitten 113 + barnaclevictimreleased 114 + preschedulethink 115 + getdeathactivity 116 + gibmonster 117 + hashumangibs 118 + hasaliengibs 119 + fademonster 120 + deathsound 123 + alertsound 124 + idlesound 125 + painsound 126 + stopfollowing 127 + + player_jump 127 + player_duck 128 + player_prethink 129 + player_postthink 130 + player_getgunposition 121 + player_shouldfadeondeath 62 + player_impulsecommands 132 + player_updateclientdata 131 + + item_addtoplayer 60 + item_addduplicate 61 + item_getiteminfo 62 + item_candeploy 63 + item_deploy 64 + item_canholster 65 + item_holster 66 + item_updateiteminfo 67 + item_preframe 68 + item_postframe 69 + item_drop 70 + item_kill 71 + item_attachtoplayer 72 + item_primaryammoindex 73 + item_secondaryammoindex 74 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 78 + + weapon_extractammo 79 + weapon_extractclipammo 80 + weapon_addweapon 81 + weapon_playemptysound 82 + weapon_resetemptysound 83 + weapon_sendweaponanim 84 + weapon_isusable 85 + weapon_primaryattack 86 + weapon_secondaryattack 87 + weapon_reload 88 + weapon_weaponidle 89 + weapon_retireweapon 90 + weapon_shouldweaponidle 91 + weapon_usedecrement 92 + + gearbox_mysquadtalkmonsterpointer 19 + gearbox_weapontimebase 58 +@end + +@section ag linux + pev 0 + base 0x60 + + spawn 2 + precache 3 + keyvalue 4 + objectcaps 7 + activate 8 + setobjectcollisionbox 9 + classify 10 + deathnotice 11 + traceattack 12 + takedamage 13 + takehealth 14 + killed 15 + bloodcolor 16 + tracebleed 17 + istriggered 18 + mymonsterpointer 19 + mysquadmonsterpointer 20 + gettogglestate 21 + addpoints 22 + addpointstoteam 23 + addplayeritem 24 + removeplayeritem 25 + giveammo 26 + getdelay 27 + ismoving 28 + overridereset 29 + damagedecal 30 + settogglestate 31 + startsneaking 32 + stopsneaking 33 + oncontrols 34 + issneaking 35 + isalive 36 + isbspmodel 37 + reflectgauss 38 + hastarget 39 + isinworld 40 + isplayer 41 + isnetclient 42 + teamid 43 + getnexttarget 44 + think 45 + touch 46 + use 47 + blocked 48 + respawn 50 + updateowner 51 + fbecomeprone 52 + center 53 + eyeposition 54 + earposition 55 + bodytarget 56 + illumination 57 + fvisible 58 + fvecvisible 59 + + look 62 + changeyaw 65 + irelationship 67 + monsterinitdead 69 + becomedead 70 + bestvisibleenemy 72 + finviewcone 73 + fvecinviewcone 74 + + runai 63 + monsterthink 66 + monsterinit 68 + checklocalmove 75 + move 76 + moveexecute 77 + shouldadvanceroute 78 + getstoppedactivity 79 + stop 80 + checkrangeattack1 81 + checkrangeattack2 82 + checkmeleeattack1 83 + checkmeleeattack2 84 + schedulechange 90 + canplaysequence 91 + canplaysentence2 92 + playsentence 93 + playscriptedsentence 94 + sentencestop 95 + getidealstate 96 + setactivity 97 + reportaistate 98 + checkenemy 99 + ftriangulate 100 + setyawspeed 101 + buildnearestroute 102 + findcover 103 + coverradius 105 + fcancheckattacks 106 + checkammo 107 + ignoreconditions 108 + fvalidatehinttype 109 + fcanactiveidle 110 + isoundmask 111 + hearingsensitivity 114 + barnaclevictimbitten 115 + barnaclevictimreleased 116 + preschedulethink 117 + getdeathactivity 118 + gibmonster 119 + hashumangibs 120 + hasaliengibs 121 + fademonster 122 + deathsound 124 + alertsound 125 + idlesound 126 + painsound 127 + stopfollowing 128 + + player_jump 129 + player_duck 130 + player_prethink 131 + player_postthink 132 + player_getgunposition 123 + player_shouldfadeondeath 64 + player_impulsecommands 134 + player_updateclientdata 133 + + item_addtoplayer 61 + item_addduplicate 62 + item_getiteminfo 63 + item_candeploy 64 + item_deploy 65 + item_canholster 66 + item_holster 67 + item_updateiteminfo 68 + item_preframe 69 + item_postframe 70 + item_drop 71 + item_kill 72 + item_attachtoplayer 73 + item_primaryammoindex 74 + item_secondaryammoindex 75 + item_updateclientdata 76 + item_getweaponptr 77 + item_itemslot 78 + + weapon_extractammo 79 + weapon_extractclipammo 80 + weapon_addweapon 81 + weapon_playemptysound 82 + weapon_resetemptysound 83 + weapon_sendweaponanim 84 + weapon_isusable 85 + weapon_primaryattack 86 + weapon_secondaryattack 87 + weapon_reload 88 + weapon_weaponidle 89 + weapon_retireweapon 90 + weapon_shouldweaponidle 91 + weapon_usedecrement 92 + +@end +@section ag windows + pev 4 + base 0x0 + + spawn 0 + precache 1 + keyvalue 2 + objectcaps 5 + activate 6 + setobjectcollisionbox 7 + classify 8 + deathnotice 9 + traceattack 10 + takedamage 11 + takehealth 12 + killed 13 + bloodcolor 14 + tracebleed 15 + istriggered 16 + mymonsterpointer 17 + mysquadmonsterpointer 18 + gettogglestate 19 + addpoints 20 + addpointstoteam 21 + addplayeritem 22 + removeplayeritem 23 + giveammo 24 + getdelay 25 + ismoving 26 + overridereset 27 + damagedecal 28 + settogglestate 29 + startsneaking 30 + stopsneaking 31 + oncontrols 32 + issneaking 33 + isalive 34 + isbspmodel 35 + reflectgauss 36 + hastarget 37 + isinworld 38 + isplayer 39 + isnetclient 40 + teamid 41 + getnexttarget 42 + think 43 + touch 44 + use 45 + blocked 46 + respawn 48 + updateowner 49 + fbecomeprone 50 + center 51 + eyeposition 52 + earposition 53 + bodytarget 54 + illumination 55 + fvisible 56 + fvecvisible 57 + + look 60 + changeyaw 63 + irelationship 65 + monsterinitdead 67 + becomedead 68 + bestvisibleenemy 70 + finviewcone 71 + fvecinviewcone 72 + + runai 61 + monsterthink 64 + monsterinit 66 + checklocalmove 73 + move 74 + moveexecute 75 + shouldadvanceroute 76 + getstoppedactivity 77 + stop 78 + checkrangeattack1 79 + checkrangeattack2 80 + checkmeleeattack1 81 + checkmeleeattack2 82 + schedulechange 88 + canplaysequence 89 + canplaysentence2 90 + playsentence 91 + playscriptedsentence 92 + sentencestop 93 + getidealstate 94 + setactivity 95 + reportaistate 96 + checkenemy 97 + ftriangulate 98 + setyawspeed 99 + buildnearestroute 100 + findcover 101 + coverradius 103 + fcancheckattacks 104 + checkammo 105 + ignoreconditions 106 + fvalidatehinttype 107 + fcanactiveidle 108 + isoundmask 109 + hearingsensitivity 112 + barnaclevictimbitten 113 + barnaclevictimreleased 114 + preschedulethink 115 + getdeathactivity 116 + gibmonster 117 + hashumangibs 118 + hasaliengibs 119 + fademonster 120 + deathsound 122 + alertsound 123 + idlesound 124 + painsound 125 + stopfollowing 126 + + player_jump 127 + player_duck 128 + player_prethink 129 + player_postthink 130 + player_getgunposition 121 + player_shouldfadeondeath 62 + player_impulsecommands 132 + player_updateclientdata 131 + + item_addtoplayer 59 + item_addduplicate 60 + item_getiteminfo 61 + item_candeploy 62 + item_deploy 63 + item_canholster 64 + item_holster 65 + item_updateiteminfo 66 + item_preframe 67 + item_postframe 68 + item_drop 69 + item_kill 70 + item_attachtoplayer 71 + item_primaryammoindex 72 + item_secondaryammoindex 73 + item_updateclientdata 74 + item_getweaponptr 75 + item_itemslot 76 + + weapon_extractammo 77 + weapon_extractclipammo 78 + weapon_addweapon 79 + weapon_playemptysound 80 + weapon_resetemptysound 81 + weapon_sendweaponanim 82 + weapon_isusable 83 + weapon_primaryattack 84 + weapon_secondaryattack 85 + weapon_reload 86 + weapon_weaponidle 87 + weapon_retireweapon 88 + weapon_shouldweaponidle 89 + weapon_usedecrement 90 +@end + \ No newline at end of file diff --git a/amxmodx/configs/kz/start.ini b/amxmodx/configs/kz/start.ini new file mode 100644 index 0000000..95b91e3 --- /dev/null +++ b/amxmodx/configs/kz/start.ini @@ -0,0 +1,92 @@ +kz_cfl_ceramicblock 482.552185 -607.127197 -154.968750 +kz_kzsca_toonworld2 -184.377380 2141.364013 52.009040 +uq_suncliff -431.652618 -512.236206 -219.968750 +kz_cg_wigbl0ck -490.224151 -81.784660 84.031250 +kzus_pharaohs_complex 459.919860 2872.557128 -412.743377 +kz_cg_extreme 3380.907958 3281.780029 -887.968750 +notkz_very-easy 797.561828 447.679626 -155.968750 +kz_waterplant 638.881042 1032.994750 -3063.968750 +kz_cellblock -672.996215 -479.054199 -3563.968750 +cg_cbblebhop 792.860534 -3909.157714 37.031250 +cg_beginner 241.153610 -2497.370117 -2091.968750 +av_degyptianez -374.001434 -2854.653076 -443.968750 +bkz_goldbhop -3494.738037 -3368.443847 36.031250 +risk_lego_firehouse 741.396850 1123.125976 -99.968750 +bkz_wallblock -2644.146240 -20.633344 -3867.968750 +slide_kzfr_glass 1094.802612 3215.976806 2980.031250 +slide_kzfr_valley -2185.127685 2264.824218 2996.031250 +kz_cfl_mountainchurch -759.735412 -740.729675 -411.968750 +dr0_surfari -1575.641601 2448.921875 -2520.968750 +cg_gridblock -108.453140 290.916717 36.031250 +kz_man_halloween2004 3545.014892 2645.649414 2532.031250 +kz_ea_caveclimb_e 1952.570922 -1013.018859 -1107.968750 +pbkz_superbhop -297.601928 62.950740 -86.268447 +carg_autumn -430.499023 -770.796997 -123.968750 +kz_kzlt_dementia 3300.939941 -3074.375000 -3579.968750 +ins_kurenogoes17 -706.367187 86.354331 100.031250 +kz_faith 38.791370 -24.602649 -27.968750 +gayl0rd_bhop 70.699287 -1357.202758 36.031250 +kz_cg_pianoclimb 1260.391967 -731.549621 -731.968750 +kz_hop 1534.196899 3087.901123 -827.968750 +cypress_mariorun 1533.891845 -420.592376 -347.968750 +kz_kzdk_radiobase 105.843444 8.725816 -251.968750 +cypress_waterfall 227.277252 -727.978027 -475.968750 +risk_stargate -909.051025 -2044.077636 -67.968750 +kz_emblem -183.011322 1142.139892 -3227.968750 +risk_snowcastle 166.539596 2789.058837 -299.968750 +kzno_xtremeblock -609.514709 -262.755523 3108.031250 +kz_sandblock2_ez 914.473083 819.916992 -2451.968750 +cypress_maya 80.000000 -544.000000 -476.000000 +kzcn_mount 803.516113 1703.370849 92.031250 +fof_chillbhop -3225.228271 3085.548339 36.031250 +kz_sola -782.678161 20.899518 420.031250 +kz_kzdk_templebhop -686.047180 -1061.353393 -91.968750 +kz_kzse_toonworld -1687.922851 -66.802017 532.031250 +kz_adventure2 -307.807128 -498.900390 -667.968750 +de_dust2 160.000000 2464.000000 -91.968750 +fof_dale 250.028884 -446.229461 -1147.968750 + -3483.158203 -3445.133300 36.031250 +kz_longjumps2 29.943288 -63.099910 -27.968750 +kz_synergy_x -386.782958 -3104.565917 -3803.968750 +kzua_zp_egypthops 783.406127 -2591.112060 468.031250 +fof_utopia -1609.442504 -1242.913085 -1739.968750 +3T_xiaocaibi -1556.977416 2824.364746 917.163391 +4U_factory_wjs -3012.511718 -772.218627 -219.968749 +Bhop_Blackjump -2098.711669 -2751.591064 -283.968749 +ml_monsterbhop -198.276519 -2570.185058 996.031249 +bhkz_bronzebhop -3777.534667 -3779.836425 100.031249 +1324_hellhouse -191.299346 1139.644165 -923.968749 +bhop_cave2 -2913.318359 -1976.860961 -459.958282 +kzua_zp_hamunaptra_x 510.950561 2592.031249 -2811.968749 +bk_bhop 1096.847290 -1247.442382 132.031249 +bhop_temple 28.047641 -412.206817 -91.968749 +rkz_easy_bhop_cross_runner -430.302947 -235.016326 -155.968749 +bhop_platinum -2769.455078 -2053.750732 36.031249 +kzro_brickybhop 72.729797 -86.958480 -475.968749 +d2_mario_bhop 869.261291 -335.439788 116.031249 +kzro_jaashsbhop -881.666259 440.452819 164.031249 +kzro_bhopbl0ck 663.665161 -3238.708496 -1403.968749 +bhop_cave 1239.796997 -845.409179 -464.194946 +kz-endo_bikinihop 85.550720 -856.860961 -459.968749 +cnd_bairesbhop -1081.642944 62.961006 100.031249 +bhop_slackibira -358.630645 -175.599151 -155.968749 +nobkz_minimal -2046.550659 2785.161865 132.031249 +1324_svalley -233.489471 121.547187 -59.999992 +kzr_greybhop -3436.196777 -1462.296997 164.031249 +bkm_problock 1129.148071 1097.507202 164.031249 +cLt_firstbhop 146.479812 369.555725 -36.968749 +bhop_aeonflux -2065.736083 -459.436126 -219.968749 +holy_lame -897.203613 2006.934326 -411.968749 +kz_nobkz_factoryrun -2853.400146 -3523.885009 3108.031249 +kzarg_ih_sandhop 2312.964599 -2571.216552 -75.968749 +kzua_mk_illumina_h -22.185686 265.968749 -31.968749 +py_mix 818.165039 -2888.277832 -219.968749 +bhop_blocks -198.061599 -599.801635 36.031249 +bhop_brainiac 158.726745 -2991.689208 68.031249 +BBbhop -3143.772949 2425.358886 -1115.968749 +kzsca_snakebhop 2995.236328 -3328.874755 2708.031249 +cypress_p0burkan -51.607265 -1240.702636 -155.968749 +bkz_bhopaztec -2838.329833 40.871498 132.031250 +cg_lighthops 959.825988 -1805.003906 -315.968750 +bkz_junglebhop -2926.710693 -2886.644775 -1371.968750 +bhop_kaninpuff 1133.260009 59.047939 -123.968750 diff --git a/amxmodx/configs/maphist.ini b/amxmodx/configs/maphist.ini new file mode 100644 index 0000000..b25a26f --- /dev/null +++ b/amxmodx/configs/maphist.ini @@ -0,0 +1,5 @@ +gayl0rd_bhop +gayl0rd_bhop +gayl0rd_bhop +gayl0rd_bhop +gayl0rd_bhop diff --git a/amxmodx/configs/maps.ini b/amxmodx/configs/maps.ini new file mode 100755 index 0000000..41d2c5f --- /dev/null +++ b/amxmodx/configs/maps.ini @@ -0,0 +1,322 @@ +1324_hellhouse +1324_svalley +3T_xiaocaibi +4U_factory_wjs +BBbhop +Bhop_Blackjump +av_degyptianez +bhkz_bronzebhop +bhop_aeonflux +bhop_astro +bhop_avantura +bhop_blocks +bhop_brainiac +bhop_c21 +bhop_cave +bhop_cave2 +bhop_colorhop +bhop_csr +bhop_darkstars +bhop_dustzone +bhop_fabrit +bhop_gamebox +bhop_its_2caves +bhop_jbg_grass +bhop_kaninpuff +bhop_lego +bhop_lyy_egypt +bhop_mz_chaosmedia90 +bhop_perfect2012 +bhop_platinum +bhop_reys +bhop_slackibira +bhop_temple +bhop_terrainhop +bhop_tropic_h +bk_bhop +bk_icerock +bkm_problock +bkz_bhopaztec +bkz_bhopvalley +bkz_dqvolski_most +bkz_forestrace +bkz_goldbhop +bkz_goldbhop_v2 +bkz_junglebhop +bkz_lostbase +bkz_noob +bkz_toonworld +bkz_volcanobhop +bkz_wallblock +bkz_whatisthis +bkzgt_aasault +bla_reactorhop +bn_tombbhop +bw_pcjump +cLt_firstbhop +cah_lost +cd_bhop +ce_house_3ways +cg_arizonabhop +cg_cbblebhop +cg_coldbhop +cg_coldbhop_v2 +cg_d2block_h +cg_lighthops +cg_wildwesthop +chip_bhopnoob_x +chk_cruel +ckz_corsair +clintmo_bhopbarrels +clintmo_bhoptoon +clintmo_bhopwarehouse +cnd_bairesbhop +cobkz_toonworld +coma_X +cosy_cavebhop +cosy_marioworld +cypress_bhoprun +cypress_p0burkan +cypress_volcancliff +d2_mario_bhop +daza_cityblock +daza_cobkz_inducility +daza_colorswitch +daza_dimensionjumper +doze_ljrun +dr0_lost_sector +dyd_bhop +dyd_brick +dyd_hb_betty_k +dyd_insulate +dyd_onlime +dyd_toonblock +etl_forsakenblock +etl_spacebhop +fb_ultimateclimb +firs_room_x +fof_32 +fof_chillbhop +fof_dale +fof_utopia +fs_streetjump +ftw_deathzone +fu_bawhop +fu_bhop +fu_devhops +fu_frosty +fu_plainhop +fu_replayhop +fu_sane +gayl0rd_bhop +gbc_randombhop +gbc_towers2 +gg_jackson2 +ham_bricks +hama_bricksv2 +hb_Creep +hb_DotAntipro +hb_PurpLeRainN +hb_inj3ct0r +hb_lambdaaa +hb_patchouli +hfr_302 +hfr_descent_h +hit_canyonbhop +hm_crazystairs +holy_lame +holy_somethingalamode +holy_strafemaster +imkz_tsfh +ins_blueline +ins_hlteaser +ivns_arcadium +j2s_4floors +j2s_4tunnels +j2s_autumn +j2s_sandland +jail_logo +jro_goldbhop +k_sun +kaspek_caverna_v1 +kek_google +kg_duckhops_flawless +klz_sherbrooke +ksz_zuma +kz-endo_bikinihop +kz-endo_blue +kz-endo_carrington +kz-endo_congo +kz-endo_toonbhopz +kz-endo_topspeed +kz_6fd_volcano +kz_adventure +kz_anubis +kz_ascension_b8 +kz_bkz_egyptbhop +kz_bkz_tropicbhop +kz_canyon +kz_cellblock +kz_cg_lavacliff +kz_cg_venice +kz_cg_xtremedesert +kz_cxg_jekyll +kz_dbh_pipehop +kz_deathvalley +kz_excavation +kz_exodus_hard +kz_facility +kz_giantbean_b15 +kz_heat +kz_hopez +kz_indusrun +kz_ins_ancientgardens +kz_ins_bhoptown +kz_j2s_cupblock +kz_j2s_icevalley +kz_j2s_westbl0ck +kz_kz-endo_portal +kz_kzarg_catacombsbhop +kz_kzdk_covebhop +kz_kzdk_delianshop +kz_kzdk_templebhop_h +kz_kzfr_rabbithighway +kz_kzlt_dementia +kz_kzlt_femtobhop +kz_kzlv_wanderer +kz_kzro_roscbhop +kz_kzro_winter +kz_kzsca_bhopindustry +kz_kzsca_escape +kz_kzsca_still +kz_kzse_dustbhop_h +kz_kzse_toonworld +kz_longjumps2 +kz_man_bhopsnow +kz_man_neighbourhood +kz_megabhop_hard +kz_nix +kz_nobkz_factoryrun +kz_owensvalley +kz_pacman +kz_radium +kz_rd_oldmine +kz_satomi +kz_shrubhop_ez +kz_shrubhop_h +kz_starwars_deeja +kz_synergy +kz_synergy_x +kz_synergy_x2 +kz_tkz_desertbl00ks +kz_undergroundvillage +kz_waterplant +kz_wild +kz_world +kz_xj_communitybhop +kzarg_bhopcircuit +kzarg_cellhop +kzarg_ih_sandhop +kzarg_lostrome +kzblt_dx_blueshadow2 +kzblt_dx_mercy +kzbr_hii_cartoonbhop +kzcn_2012 +kzdk_explorer_x +kzeed_bhop_madness +kzeed_prohop +kzex_darksiders +kzex_earthruins +kzla_cdbanana +kzls_bhop_china +kzls_kodash +kzls_smile +kzlt_arabhop +kzlt_dark_vault +kzm_cityhops +kzpf_deathless_x +kzr_greybhop +kzra_bhopmemories +kzra_crystal_palace +kzra_greencave +kzra_somecaves +kzra_stonebhop +kzra_stonebhop2 +kzra_stoneishbhop +kzra_worlds +kzray_rocky-bhop +kzro_bhopbl0ck +kzro_brickybhop +kzro_excitedbhop +kzro_gohome +kzro_island +kzro_jaashsbhop +kzro_mountainbhop +kzro_tits +kzru_Mam6ahop +kzru_spacehop +kzru_technology_x +kzsca_bagdad +kzsca_burrow +kzsca_heaven +kzsca_snakebhop +kzsca_watertemple +kzsca_watertemple2 +kzse_bhopblock +kzsk_cubeblock +kzsk_rocksland +kztw_abyss_2014 +kzua_de_portal +kzua_goldbhop_x +kzua_mk_illumina +kzua_mk_illumina_h +kzua_zp_cellaregypt +kzua_zp_godroom_h +kzua_zp_hamunaptra_x +kzy_juhxbhop +kzz_bhop +ladder_0logic +mad_bhopit +mad_tomb +mad_tomb2 +mck_vudu +mh_bhopljs_h +ml_monsterbhop +mls_floppytown_bh +mls_greenstyle_bh +mls_icefall_bhop +mls_stairsbhop +mto_bhops +nobkz_minimal +nobkz_mst_honduras_h +notkz_amazing +notkz_bhopcolour +nz_playstation +pixelhop +pprn_violetta_x +pro_kzcn_blow2 +prochallenge_bhop +py_mix +qsk_azure +qsk_still +radon_desertpassage +rd_jump_house +risk_bhop_bunny +risk_sector +risk_snowcastle +rkz_easy_bhop_cross_runner +rr_inside^outside +rush_adventure +rush_countless +rvp_tundra-bhop +slD_bside_nightblock +smk_evergreen +smk_factory +smk_kzsca_factory +sn_dustown +sn_ezycity +speed_ytt_castle +stf_creepytemple +ugly_stairstoon +ytt_light_stars +ytt_wow_mix diff --git a/amxmodx/configs/miscstats.ini b/amxmodx/configs/miscstats.ini new file mode 100644 index 0000000..460cab8 --- /dev/null +++ b/amxmodx/configs/miscstats.ini @@ -0,0 +1,26 @@ +; To disable a sound, disable it from amxmodmenu (stats settings) or from command amx_statscfgmenu +; Sound name length mustn't exceed 54 characters (without sound/ and without .wav extension) +; Otherwise plugin won't take it in account because fast download wouldn't be supported + +FirstBloodSound misc/firstblood +LastManVsOthersSound misc/oneandonly +LastManDuelSound misc/maytheforce +HeadShotKillSoundKiller misc/headshot +HeadShotKillSoundVictim fvox/flatline +KnifeKillSound misc/humiliation +DoubleKillSound misc/doublekill +RoundCounterSound misc/prepare +GrenadeKillSound djeyl/grenade +GrenadeSuicideSound djeyl/witch +BombPlantedSound djeyl/c4powa +BombDefusedSound djeyl/laugh +BombFailedSound djeyl/witch + +; KillingStreak and MultiKill Sounds +MultiKillSound misc/multikill +UltraKillSound misc/ultrakill +KillingSpreeSound misc/killingspree +RampageSound misc/rampage +UnstopableSound misc/unstoppable +MonsterKillSound misc/monsterkill +GodLike misc/godlike diff --git a/amxmodx/configs/modules.ini b/amxmodx/configs/modules.ini new file mode 100755 index 0000000..f46d5dd --- /dev/null +++ b/amxmodx/configs/modules.ini @@ -0,0 +1,41 @@ + +;;; +; To enable a module, remove the semi-colon (;) in front of its name. +; If it's not here, simply add it its name, one per line. +; You don't need to write the _amxx part or the file extension. +;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; SQL Modules usually need to be enabled manually ;; +;; You can have any number on at a time. Use ;; +;; amx_sql_type in sql.cfg to specify the default ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +mysql +;sqlite + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Put third party modules below here. ;; +;; You can just list their names, without the _amxx ;; +;; or file extension. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;curl +amxxarch + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; These modules will be auto-detected and loaded ;; +;; as needed. You do not need to enable them here ;; +;; unless you have problems. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;fun +;engine +;fakemeta +;geoip +;sockets +;regex +;nvault +;cstrike +;csx +;hamsandwich diff --git a/amxmodx/configs/mpbhop.cfg b/amxmodx/configs/mpbhop.cfg new file mode 100644 index 0000000..cda1610 --- /dev/null +++ b/amxmodx/configs/mpbhop.cfg @@ -0,0 +1,17 @@ +// "MultiPlayer Bhop" configuration file +// Author : "ConnorMcLeod" +// Version : "1.1.2" +// File : "mpbhop.amxx" + +// Console Commands : +// kz_mpbhop | Access:"h" | "<0/1> set blocks so they can't move when players touch them" +// kz_mpbhop_entitytouch | Access:"h" | "<0/1> set blocks so they can't move when other entities than players touch them" +// kz_mpbhopmenu | Access:"h" | "" +// kz_safe_inform | Access:"h" | "<0/1> Inform recorders that their demo will be safe or not safe according to plugin state" +// kz_showblocks | Access:"h" | "" + +// Cvars : +// mp_bhop_version "1.1.2" + +kz_mpbhop 1 +kz_mpbhop_entitytouch 1 diff --git a/amxmodx/configs/mpbhop/BKZ_Primitive.dat b/amxmodx/configs/mpbhop/BKZ_Primitive.dat new file mode 100644 index 0000000..f4f2fe9 --- /dev/null +++ b/amxmodx/configs/mpbhop/BKZ_Primitive.dat @@ -0,0 +1,2 @@ +-2943.999999 1687.999999 -255.999999 1 +-695.999999 2015.999999 -295.999999 1 diff --git a/amxmodx/configs/mpbhop/bhop_celsbrick.dat b/amxmodx/configs/mpbhop/bhop_celsbrick.dat new file mode 100644 index 0000000..7d1023e --- /dev/null +++ b/amxmodx/configs/mpbhop/bhop_celsbrick.dat @@ -0,0 +1,9 @@ +727.999999 1719.999999 -1175.999999 1 +663.999999 1671.999999 -1175.999999 1 +1535.999999 455.999999 -1207.999999 1 +1479.999999 503.999999 -1207.999999 1 +-511.999999 -80.000000 -1223.999999 1 +-527.999999 -167.999999 -1215.999999 1 +-551.999999 -255.999999 -1207.999999 1 +-583.999999 -343.999999 -1199.999999 1 +-623.999999 -431.999999 -1191.999999 1 diff --git a/amxmodx/configs/mpbhop/bhop_hard.dat b/amxmodx/configs/mpbhop/bhop_hard.dat new file mode 100644 index 0000000..13e1290 --- /dev/null +++ b/amxmodx/configs/mpbhop/bhop_hard.dat @@ -0,0 +1,2 @@ +927.999999 -351.999999 -383.999999 1 +863.999999 -223.999999 -383.999999 1 diff --git a/amxmodx/configs/mpbhop/bhopkz_raz.dat b/amxmodx/configs/mpbhop/bhopkz_raz.dat new file mode 100644 index 0000000..2915559 --- /dev/null +++ b/amxmodx/configs/mpbhop/bhopkz_raz.dat @@ -0,0 +1,18 @@ +1087.999999 -239.999999 -311.999999 1 +1471.999999 -239.999999 -311.999999 1 +1087.999999 -479.999999 -311.999999 1 +1087.999999 -703.999999 -311.999999 1 +1087.999999 -1215.999999 -311.999999 1 +1087.999999 -991.999999 -311.999999 1 +1471.999999 -479.999999 -311.999999 1 +1471.999999 -703.999999 -311.999999 1 +1471.999999 -991.999999 -311.999999 1 +1471.999999 -1215.999999 -311.999999 1 +1375.999999 -1103.999999 -311.999999 1 +1183.999999 -1103.999999 -311.999999 1 +1183.999999 -575.999999 -311.999999 1 +1375.999999 -575.999999 -311.999999 1 +1183.999999 -351.999999 -311.999999 1 +1375.999999 -351.999999 -311.999999 1 +1183.999999 -119.999999 -311.999999 1 +1375.999999 -119.999999 -311.999999 1 diff --git a/amxmodx/configs/mpbhop/bn_tombbhop.dat b/amxmodx/configs/mpbhop/bn_tombbhop.dat new file mode 100644 index 0000000..9dc57e4 --- /dev/null +++ b/amxmodx/configs/mpbhop/bn_tombbhop.dat @@ -0,0 +1,7 @@ +-119.999999 -1863.999999 -507.499999 1 +-295.999999 -1927.999999 -508.499999 1 +-567.999999 -1799.999999 -508.499999 1 +-951.999999 -1767.999999 -508.499999 1 +-1031.999999 -1623.999999 -508.499999 1 +-1063.999999 -1239.999999 -508.499999 1 +-1031.999999 -1031.999999 -508.499999 1 diff --git a/amxmodx/configs/mpbhop/bz_sand.dat b/amxmodx/configs/mpbhop/bz_sand.dat new file mode 100644 index 0000000..b7e69c6 --- /dev/null +++ b/amxmodx/configs/mpbhop/bz_sand.dat @@ -0,0 +1,18 @@ +3167.999999 2503.999999 -135.999999 1 +2783.999999 2631.999999 -111.999999 1 +2783.999999 2719.999999 -87.999999 1 +3167.999999 2855.999999 -135.999999 1 +3711.999999 2439.999999 -31.999999 1 +3711.999999 2311.999999 -71.999999 1 +3711.999999 2207.999999 -40.000000 1 +3359.999999 1895.999999 -55.999999 1 +3359.999999 1791.999999 -40.000000 1 +3359.999999 1687.999999 -23.999999 1 +3335.999999 1055.999999 183.999999 1 +3399.999999 1055.999999 167.999999 1 +3463.999999 1055.999999 151.999999 1 +3527.999999 1055.999999 135.999999 1 +2807.999999 2071.999999 -227.999999 1 +2887.999999 1983.999999 -203.999999 1 +2939.999999 2307.999999 -223.999999 1 +3073.999999 2305.999999 -211.999999 1 diff --git a/amxmodx/configs/mpbhop/cg_cbblebhop.dat b/amxmodx/configs/mpbhop/cg_cbblebhop.dat new file mode 100644 index 0000000..8d6c709 --- /dev/null +++ b/amxmodx/configs/mpbhop/cg_cbblebhop.dat @@ -0,0 +1,5 @@ +523.499999 233.499999 -43.999999 1 +245.499999 324.499999 -43.999999 1 +245.499999 139.499999 -43.999999 1 +-178.499999 324.499999 -43.999999 1 +-178.499999 139.499999 -43.999999 1 diff --git a/amxmodx/configs/mpbhop/drh_bhop_dust2.dat b/amxmodx/configs/mpbhop/drh_bhop_dust2.dat new file mode 100644 index 0000000..a1d370c --- /dev/null +++ b/amxmodx/configs/mpbhop/drh_bhop_dust2.dat @@ -0,0 +1,2 @@ +-235.999999 -1095.999999 -75.499999 1 +375.999999 171.999999 -67.999999 1 diff --git a/amxmodx/configs/mpbhop/kz_kzdk_droughthop.dat b/amxmodx/configs/mpbhop/kz_kzdk_droughthop.dat new file mode 100644 index 0000000..86a66fb --- /dev/null +++ b/amxmodx/configs/mpbhop/kz_kzdk_droughthop.dat @@ -0,0 +1,8 @@ +1661.499999 2032.999999 1197.999999 1 +1774.499999 2176.499999 1197.999999 1 +655.499999 -3605.999999 1187.999999 1 +729.499999 -3437.999999 1193.999999 1 +644.499999 -3217.999999 1223.999999 1 +540.499999 -3144.999999 1223.999999 1 +435.999999 -1830.999999 1188.499999 1 +435.999999 -1712.999999 1188.499999 1 diff --git a/amxmodx/configs/mpbhop/kz_kzsca_sewerbhop.dat b/amxmodx/configs/mpbhop/kz_kzsca_sewerbhop.dat new file mode 100644 index 0000000..5a15f1d --- /dev/null +++ b/amxmodx/configs/mpbhop/kz_kzsca_sewerbhop.dat @@ -0,0 +1 @@ +-1399.999999 1207.999999 1599.999999 1 diff --git a/amxmodx/configs/mpbhop/kz_longjumps2.dat b/amxmodx/configs/mpbhop/kz_longjumps2.dat new file mode 100644 index 0000000..335d83b --- /dev/null +++ b/amxmodx/configs/mpbhop/kz_longjumps2.dat @@ -0,0 +1 @@ +-1111.999999 1103.999999 -2663.999999 1 diff --git a/amxmodx/configs/mpbhop/kz_megabhop.dat b/amxmodx/configs/mpbhop/kz_megabhop.dat new file mode 100644 index 0000000..20b93ef --- /dev/null +++ b/amxmodx/configs/mpbhop/kz_megabhop.dat @@ -0,0 +1,2 @@ +427.999999 2323.999999 -959.999999 0 +-991.999999 1471.999999 -967.999999 0 diff --git a/amxmodx/configs/mpbhop/kz_megabhop_hard.dat b/amxmodx/configs/mpbhop/kz_megabhop_hard.dat new file mode 100644 index 0000000..20b93ef --- /dev/null +++ b/amxmodx/configs/mpbhop/kz_megabhop_hard.dat @@ -0,0 +1,2 @@ +427.999999 2323.999999 -959.999999 0 +-991.999999 1471.999999 -967.999999 0 diff --git a/amxmodx/configs/mpbhop/kzblt_zigzaghop.dat b/amxmodx/configs/mpbhop/kzblt_zigzaghop.dat new file mode 100644 index 0000000..bca37ab --- /dev/null +++ b/amxmodx/configs/mpbhop/kzblt_zigzaghop.dat @@ -0,0 +1,2 @@ +1271.999999 15.999999 -103.999999 1 +1271.999999 -87.999999 -103.999999 1 diff --git a/amxmodx/configs/mpbhop/kzlt_castlehops.dat b/amxmodx/configs/mpbhop/kzlt_castlehops.dat new file mode 100644 index 0000000..2c6d50a --- /dev/null +++ b/amxmodx/configs/mpbhop/kzlt_castlehops.dat @@ -0,0 +1 @@ +-575.999999 -695.999999 -247.999999 1 diff --git a/amxmodx/configs/mpbhop/kzlv_vaz_ujo_e.dat b/amxmodx/configs/mpbhop/kzlv_vaz_ujo_e.dat new file mode 100644 index 0000000..e268380 --- /dev/null +++ b/amxmodx/configs/mpbhop/kzlv_vaz_ujo_e.dat @@ -0,0 +1,19 @@ +42.499999 335.499999 -552.499999 1 +164.499999 335.499999 -552.499999 1 +528.499999 526.499999 -552.499999 1 +528.499999 683.499999 -552.499999 1 +199.499999 370.499999 -552.499999 1 +199.499999 526.499999 -552.499999 1 +199.499999 683.499999 -552.499999 1 +466.499999 745.499999 -552.499999 1 +260.999999 744.499999 -552.499999 1 +662.499999 838.499999 -552.499999 1 +662.499999 681.999999 -552.499999 1 +662.499999 524.999999 -552.499999 1 +65.499999 524.999999 -552.499999 1 +65.499999 681.999999 -552.499999 1 +65.499999 838.499999 -552.499999 1 +208.499999 840.499999 -554.499999 1 +364.499999 840.499999 -554.499999 1 +521.499999 840.499999 -554.499999 1 +-235.999999 260.999999 -483.999999 1 diff --git a/amxmodx/configs/mpbhop/kzlv_vaz_ujo_h.dat b/amxmodx/configs/mpbhop/kzlv_vaz_ujo_h.dat new file mode 100644 index 0000000..e268380 --- /dev/null +++ b/amxmodx/configs/mpbhop/kzlv_vaz_ujo_h.dat @@ -0,0 +1,19 @@ +42.499999 335.499999 -552.499999 1 +164.499999 335.499999 -552.499999 1 +528.499999 526.499999 -552.499999 1 +528.499999 683.499999 -552.499999 1 +199.499999 370.499999 -552.499999 1 +199.499999 526.499999 -552.499999 1 +199.499999 683.499999 -552.499999 1 +466.499999 745.499999 -552.499999 1 +260.999999 744.499999 -552.499999 1 +662.499999 838.499999 -552.499999 1 +662.499999 681.999999 -552.499999 1 +662.499999 524.999999 -552.499999 1 +65.499999 524.999999 -552.499999 1 +65.499999 681.999999 -552.499999 1 +65.499999 838.499999 -552.499999 1 +208.499999 840.499999 -554.499999 1 +364.499999 840.499999 -554.499999 1 +521.499999 840.499999 -554.499999 1 +-235.999999 260.999999 -483.999999 1 diff --git a/amxmodx/configs/mpbhop/kzm_cityhops.dat b/amxmodx/configs/mpbhop/kzm_cityhops.dat new file mode 100644 index 0000000..4887d7c --- /dev/null +++ b/amxmodx/configs/mpbhop/kzm_cityhops.dat @@ -0,0 +1,3 @@ +200.000000 300.000000 -495.999999 1 +891.999999 3735.999999 177.999999 1 +731.999999 3647.999999 111.999999 1 diff --git a/amxmodx/configs/mpbhop/kzru_pharaonrun.dat b/amxmodx/configs/mpbhop/kzru_pharaonrun.dat new file mode 100644 index 0000000..b17c808 --- /dev/null +++ b/amxmodx/configs/mpbhop/kzru_pharaonrun.dat @@ -0,0 +1,20 @@ +-23.999999 -31.999999 -63.999999 1 +-159.999999 95.999999 -63.999999 1 +8.000000 159.999999 -63.999999 1 +8.000000 351.999999 -63.999999 1 +-143.999999 415.999999 -63.999999 1 +8.000000 527.999999 -63.999999 1 +-175.999999 623.999999 -63.999999 1 +-23.999999 719.999999 -63.999999 1 +-127.999999 863.999999 -63.999999 1 +95.999999 1055.999999 -63.999999 1 +543.999999 927.999999 -63.999999 1 +415.999999 800.000000 -63.999999 1 +335.999999 671.999999 -63.999999 1 +479.999999 575.999999 -63.999999 1 +575.999999 447.999999 -63.999999 1 +415.999999 351.999999 -63.999999 1 +543.999999 223.999999 -63.999999 1 +383.999999 127.999999 -63.999999 1 +527.999999 0.000000 -63.999999 1 +287.999999 1055.999999 -63.999999 1 diff --git a/amxmodx/configs/mpbhop/kzse_ancienthopez.dat b/amxmodx/configs/mpbhop/kzse_ancienthopez.dat new file mode 100644 index 0000000..34d443b --- /dev/null +++ b/amxmodx/configs/mpbhop/kzse_ancienthopez.dat @@ -0,0 +1 @@ +-231.999999 2189.999999 77.999999 1 diff --git a/amxmodx/configs/mpbhop/ms_rockbhop.dat b/amxmodx/configs/mpbhop/ms_rockbhop.dat new file mode 100644 index 0000000..d613340 --- /dev/null +++ b/amxmodx/configs/mpbhop/ms_rockbhop.dat @@ -0,0 +1 @@ +327.999999 -23.999999 -74.499999 1 diff --git a/amxmodx/configs/mpbhop/mtd_mariobhop.dat b/amxmodx/configs/mpbhop/mtd_mariobhop.dat new file mode 100644 index 0000000..2b29df1 --- /dev/null +++ b/amxmodx/configs/mpbhop/mtd_mariobhop.dat @@ -0,0 +1 @@ +-4.000000 -553.499999 -1378.999999 1 diff --git a/amxmodx/configs/mpbhop/notkz_bhopcolour.dat b/amxmodx/configs/mpbhop/notkz_bhopcolour.dat new file mode 100644 index 0000000..3750322 --- /dev/null +++ b/amxmodx/configs/mpbhop/notkz_bhopcolour.dat @@ -0,0 +1 @@ +759.999999 -279.999999 -1095.999999 1 diff --git a/amxmodx/configs/mpbhop/notkz_ceylanhop.dat b/amxmodx/configs/mpbhop/notkz_ceylanhop.dat new file mode 100644 index 0000000..e8793aa --- /dev/null +++ b/amxmodx/configs/mpbhop/notkz_ceylanhop.dat @@ -0,0 +1,56 @@ +655.999999 351.999999 -271.999999 1 +719.999999 463.999999 -271.999999 1 +591.999999 543.999999 -271.999999 1 +591.999999 687.999999 -271.999999 1 +447.999999 719.999999 -271.999999 1 +255.999999 1119.999999 -271.999999 1 +400.000000 1183.999999 -271.999999 1 +527.999999 1119.999999 -271.999999 1 +655.999999 1247.999999 -271.999999 1 +591.999999 1359.999999 -271.999999 1 +495.999999 1439.999999 -271.999999 1 +559.999999 1583.999999 -271.999999 1 +719.999999 1583.999999 -271.999999 1 +2879.999999 1375.999999 -279.999999 1 +3007.999999 1247.999999 -279.999999 1 +2639.999999 1039.999999 -279.999999 1 +2527.999999 1263.999999 -287.999999 1 +2415.999999 1359.999999 -287.999999 1 +2255.999999 1359.999999 -287.999999 1 +2175.999999 1215.999999 -287.999999 1 +2047.999999 1055.999999 -255.999999 1 +2000.000000 911.999999 -271.999999 1 +2591.999999 1151.999999 -287.999999 1 +2943.999999 1535.999999 -279.999999 1 +2959.999999 2447.999999 -271.999999 1 +2815.999999 2591.999999 -271.999999 1 +2703.999999 2559.999999 -271.999999 1 +2559.999999 2559.999999 -271.999999 1 +2463.999999 2671.999999 -271.999999 1 +2287.999999 2671.999999 -271.999999 1 +2831.999999 1631.999999 -279.999999 1 +2319.999999 3055.999999 -255.999999 1 +2415.999999 3151.999999 -255.999999 1 +2575.999999 3119.999999 -239.999999 1 +2735.999999 3199.999999 -271.999999 1 +2863.999999 3087.999999 -271.999999 1 +3007.999999 3167.999999 -271.999999 1 +143.999999 2959.999999 -279.999999 1 +-47.999999 2975.999999 -279.999999 1 +-159.999999 2895.999999 -279.999999 1 +-319.999999 2911.999999 -279.999999 1 +-800.000000 2863.999999 -279.999999 1 +-927.999999 2943.999999 -271.999999 1 +-927.999999 3087.999999 -263.999999 1 +-1071.999999 3135.999999 -255.999999 1 +-1279.999999 3103.999999 -279.999999 1 +-1343.999999 2943.999999 -279.999999 1 +2543.999999 -1311.999999 -800.000000 1 +1599.999999 -1327.999999 -800.000000 1 +1663.999999 -1487.999999 -800.000000 1 +1823.999999 -1551.999999 -800.000000 1 +607.999999 -1407.999999 -759.999999 1 +415.999999 -1407.999999 -767.999999 1 +351.999999 -1567.999999 -767.999999 1 +431.999999 -1695.999999 -759.999999 1 +351.999999 -1839.999999 -767.999999 1 diff --git a/amxmodx/configs/mpbhop/notkz_ml_bhop_3ways.dat b/amxmodx/configs/mpbhop/notkz_ml_bhop_3ways.dat new file mode 100644 index 0000000..a0d52e0 --- /dev/null +++ b/amxmodx/configs/mpbhop/notkz_ml_bhop_3ways.dat @@ -0,0 +1 @@ +1563.999999 1467.999999 55.999999 0 diff --git a/amxmodx/configs/mpbhop/notkz_straighthops_beta_v1.dat b/amxmodx/configs/mpbhop/notkz_straighthops_beta_v1.dat new file mode 100644 index 0000000..2134634 --- /dev/null +++ b/amxmodx/configs/mpbhop/notkz_straighthops_beta_v1.dat @@ -0,0 +1,4 @@ +-1215.999999 -1327.999999 -255.999999 1 +1175.999999 -1047.999999 -255.999999 1 +1175.999999 -1143.999999 -255.999999 1 +1175.999999 -1239.999999 -255.999999 1 diff --git a/amxmodx/configs/mpbhop/oHS_bhop_hell.dat b/amxmodx/configs/mpbhop/oHS_bhop_hell.dat new file mode 100644 index 0000000..3c9978c --- /dev/null +++ b/amxmodx/configs/mpbhop/oHS_bhop_hell.dat @@ -0,0 +1 @@ +1063.999999 -1239.999999 -319.499999 1 diff --git a/amxmodx/configs/mpbhop/risk_sector.dat b/amxmodx/configs/mpbhop/risk_sector.dat new file mode 100644 index 0000000..0ffd778 --- /dev/null +++ b/amxmodx/configs/mpbhop/risk_sector.dat @@ -0,0 +1 @@ +543.999999 -2543.999999 -47.999999 1 diff --git a/amxmodx/configs/mpbhop/xjbg_climbhop.dat b/amxmodx/configs/mpbhop/xjbg_climbhop.dat new file mode 100644 index 0000000..cbc6770 --- /dev/null +++ b/amxmodx/configs/mpbhop/xjbg_climbhop.dat @@ -0,0 +1 @@ +159.999999 -497.999999 147.999999 1 diff --git a/amxmodx/configs/pausecfg.ini b/amxmodx/configs/pausecfg.ini new file mode 100644 index 0000000..274f63d --- /dev/null +++ b/amxmodx/configs/pausecfg.ini @@ -0,0 +1,2 @@ +;Generated by Pause Plugins Plugin. Do not modify! +;Title Filename diff --git a/amxmodx/configs/plugins.ini b/amxmodx/configs/plugins.ini new file mode 100755 index 0000000..502a91b --- /dev/null +++ b/amxmodx/configs/plugins.ini @@ -0,0 +1,54 @@ +; AMX Mod X plugins + +; Admin Base - Always one has to be activated +;admin.amxx ; admin base (required for any admin-related) +admin_sql.amxx ; admin base - SQL version (comment admin.amxx) + +; Basic +admincmd.amxx ; basic admin console commands +adminhelp.amxx ; help command for admin console commands +adminslots.amxx ; slot reservation +multilingual.amxx ; Multi-Lingual management + +; Menus +menufront.amxx ; front-end for admin menus +cmdmenu.amxx ; command menu (speech, settings) +plmenu.amxx ; players menu (kick, ban, client cmds.) +telemenu.amxx ; teleport menu (Fun Module required!) +mapsmenu.amxx ; maps menu (vote, changelevel) +pluginmenu.amxx ; Menus for commands/cvars organized by plugin + +; Chat / Messages +adminchat.amxx ; console chat commands +antiflood.amxx ; prevent clients from chat-flooding the server +scrollmsg.amxx ; displays a scrolling message +imessage.amxx ; displays information messages +adminvote.amxx ; vote commands + +; Map related +;nextmap.amxx ; displays next map in mapcycle +;mapchooser.amxx ; allows to vote for next map +rtv.amxx +;timeleft.amxx ; displays time left on map + +; Configuration +pausecfg.amxx ; allows to pause and unpause some plugins +;statscfg.amxx ; allows to manage stats plugins via menu and commands + +; Counter-Strike +;restmenu.amxx ; restrict weapons menu +;statsx.amxx ; stats on death or round end (CSX Module required!) +;miscstats.amxx ; bunch of events announcement for Counter-Strike +;stats_logging.amxx ; weapons stats logging (CSX Module required!) + +; Custom - Add 3rd party plugins here +sys_timing.amxx + +uq_jumpstats.amxx +uq_jumpstats_tops.amxx + +KZ_Engine.amxx +KZ_Chat.amxx +KZ_Bot.amxx + +mpbhop.amxx diff --git a/amxmodx/configs/speech.ini b/amxmodx/configs/speech.ini new file mode 100755 index 0000000..725acf6 --- /dev/null +++ b/amxmodx/configs/speech.ini @@ -0,0 +1,34 @@ +; Menu configuration file +; File location: $moddir/addons/amxmodx/configs/speech.ini +; To use with Commands Menu plugin + +; NOTE: By default in all settings the access level is set to "u". +; However you can change that, to limit the access to some settings. + +; Commands Menu: ; < description > < command > < flags > < access level > +; "a" - execute from server console +; "b" - execute from admin console +; "c" - execute on all clients +; "d" - back to menu when executed + +"Hello!" "spk \'vox/hello\'" "cd" "u" +"Don't think so" "spk \'barney/dontguess\'" "cd" "u" +"Don't ask me" "spk \'barney/dontaskme\'" "cd" "u" +"Hey! Stop that!" "spk \'barney/donthurtem\'" "cd" "u" +"Yup" "spk \'barney/yup\'" "cd" "u" +"Nope" "spk \'barney/nope\'" "cd" "u" +"Maybe" "spk \'barney/maybe\'" "cd" "u" +"Seeya" "spk \'barney/seeya\'" "cd" "u" +"Man that sounded bad" "spk \'barney/soundsbad\'" "cd" "u" +"Hello and die" "spk \'vox/hello and die\'" "cd" "u" +"Move!" "spk \'hgrunt/move! _comma yessir!\'" "cd" "u" +"You will definitely pay!" "spk \'hgrunt/c2a2_hg_chat5a\'" "cd" "u" +"Laughter" "spk \'hgrunt/c2a3_hg_laugh\'" "cd" "u" +"Silence!" "spk \'hgrunt/silence!\'" "cd" "u" +"You talk too much" "spk \'barney/youtalkmuch\'" "cd" "u" +"You thinkin?" "spk \'barney/thinking\'" "cd" "u" +"Open fire Gordon!" "spk \'barney/openfire\'" "cd" "u" +"Couldnt make a bigger mess" "spk \'barney/bigmess\'" "cd" "u" +"I have a Bad feeling" "spk \'barney/badfeeling\'" "cd" "u" +"Yes sir!" "spk \'hgrunt/yessir!\'" "cd" "u" +"No sir" "spk \'barney/nosir\'" "cd" "u" diff --git a/amxmodx/configs/stats.ini b/amxmodx/configs/stats.ini new file mode 100755 index 0000000..13a1218 --- /dev/null +++ b/amxmodx/configs/stats.ini @@ -0,0 +1,8 @@ +;Generated by Stats Configuration Plugin. Do not modify! +;Variable Description +ShowAttackers ;Show Attackers +ShowVictims ;Show Victims +ShowStats ;HUD-stats default +SayRankStats ;Say /rankstats +SayRank ;Say /rank +SayTop15 ;Say /top15 diff --git a/amxmodx/configs/uqjumpstats.cfg b/amxmodx/configs/uqjumpstats.cfg new file mode 100644 index 0000000..94e74e7 --- /dev/null +++ b/amxmodx/configs/uqjumpstats.cfg @@ -0,0 +1,261 @@ +// Mysql Connect +kz_uq_host = 127.0.0.1 +kz_uq_user = kreedz +kz_uq_pass = AQZbQN6TnttcSZVKQCKVX +kz_uq_db = kreedz + +// 0 = none +// a = colorchat +// b = stats +// c = speed +// d = showpre +// e = strafe stats +// f = beam +// g = duck stats for mcj +// h = shows message when your bhop prestrafe is failed +// i = show multibhop pre +// j = show prestrafe after duck +// k = show lj prestrafe +// l = show edge +// m = show edge when fail (without block) +// n = on/off sound's on players +kz_uq_connect "abdeghijklmno" + +kz_uq_bots "1" + +// Min distance +kz_uq_min_dist 215 + +// Min distance (Ups bhop, MultiBhop, Real Ladder Bhop, Ducks Bhop, Ladder Jump) +kz_uq_min_dist_other 150 + +// Max distance +kz_uq_max_dist 290 + +// Allow sounds (1 = on, 0 = off) +kz_uq_sounds 1 + +// Allow check to legal settings (1 = on, 0 = off) +kz_uq_legal_settings 1 +kz_uq_fps 1 +kz_uq_bug_check 1 +kz_uq_script_detection 1 + +// Allow InGame Strafe Stats (laggy feature) +kz_uq_istrafes 0 + +// How to set up a server by value sv_airaccelerate (0=10aa, 1=100aa) +kz_uq_airaccelerate 1 + +kz_uq_noslowdown 0 + +// Max strafes (if players strafes>Max, stats doesnt shows) +kz_uq_max_strafes 14 + +// Color Hud message statistics when you jump, in the RGB +kz_uq_stats_red 50 +kz_uq_stats_green 189 +kz_uq_stats_blue 100 + +// Color Hud messages Fail statistics when you jump, in the RGB +kz_uq_failstats_red 238 +kz_uq_failstats_green 0 +kz_uq_failstats_blue 0 + +// Color Hud messages prestrafe, in the RGB +kz_uq_prestrafe_red 30 +kz_uq_prestrafe_green 255 +kz_uq_prestrafe_blue 255 + +// Color of speed, in the RGB +kz_uq_speed_red 255 +kz_uq_speed_green 255 +kz_uq_speed_blue 255 + +//Coordinates Hud messages + +//General stats jump +kz_uq_stats_x "-1.0" +kz_uq_stats_y "0.70" + +//Strafes Stats +kz_uq_strafe_x "0.70" +kz_uq_strafe_y "0.35" + +//Ducks Stats for Multi dd +kz_uq_duck_x "0.6" +kz_uq_duck_y "0.78" + +//Speed +kz_uq_speed_x "-1.0" +kz_uq_speed_y "0.83" + +//Prestrafe +kz_uq_prestrafe_x "-1.0" +kz_uq_prestrafe_y "0.65" + +// Channel Hud messages of general stats jump +kz_uq_hud_stats 3 + +// Channel Hud messages of strafes Stats +kz_uq_hud_strafe 2 + +// Channel Hud messages of ducks Stats for Multi CountJump +kz_uq_hud_duck 1 + +// Channel Hud messages of speed +kz_uq_hud_speed 2 + +// Channel Hud messages of prestafe +kz_uq_hud_pre 1 + +// For what technique stats enable +kz_uq_lj 1 +kz_uq_cj 1 +kz_uq_bj 1 +kz_uq_sbj 1 +kz_uq_wj 1 +kz_uq_dcj 1 +kz_uq_mcj 1 +kz_uq_drbj 1 +kz_uq_drcj 1 +kz_uq_ladder 1 +kz_uq_ldbj 1 + +// Max,Min block to show in edge +kz_uq_max_block 290 +kz_uq_min_block 200 + +// Minimum Prestrafe to show +kz_uq_min_pre 60 + +// For what Extra technique stats enable +kz_uq_scj 1 +kz_uq_dscj 1 +kz_uq_mscj 1 +kz_uq_dropscj 1 +kz_uq_dropdscj 1 +kz_uq_dropmscj 1 +kz_uq_duckbhop 0 +kz_uq_bhopinduck 1 +kz_uq_realldbhop 1 +kz_uq_upbj 1 +kz_uq_upsbj 1 +kz_uq_upbhopinduck 1 +kz_uq_multibhop 0 +kz_uq_dropdcj 1 +kz_uq_dropmcj 1 + +// Color for chat messages of jump distances (good = grey, pro = green, holy = blue, leet = red, god = red (with sound godlike for all players)) +// LongJump/HighJump +kz_uq_good_lj 240 +kz_uq_pro_lj 245 +kz_uq_holy_lj 250 +kz_uq_leet_lj 252 +kz_uq_god_lj 254 +kz_uq_dom_lj 255 + +// CountJump +kz_uq_good_cj 250 +kz_uq_pro_cj 255 +kz_uq_holy_cj 260 +kz_uq_leet_cj 263 +kz_uq_god_cj 265 +kz_uq_dom_cj 267 + +// Double CountJump/Multi CountJump +kz_uq_good_dcj 250 +kz_uq_pro_dcj 255 +kz_uq_holy_dcj 260 +kz_uq_leet_dcj 265 +kz_uq_god_dcj 268 +kz_uq_dom_dcj 270 + +// LadderJump +kz_uq_good_ladder 150 +kz_uq_pro_ladder 160 +kz_uq_holy_ladder 170 +kz_uq_leet_ladder 180 +kz_uq_god_ladder 185 +kz_uq_dom_ladder 190 + +// BhopJump/StandUp BhopJump +kz_uq_good_bj 230 +kz_uq_pro_bj 235 +kz_uq_holy_bj 240 +kz_uq_leet_bj 243 +kz_uq_god_bj 245 +kz_uq_dom_bj 247 + +// WeirdJump/Drop CountJump(double,multi)/Ladder BhopJump +kz_uq_good_wj 250 +kz_uq_pro_wj 255 +kz_uq_holy_wj 260 +kz_uq_leet_wj 265 +kz_uq_god_wj 268 +kz_uq_dom_wj 270 + +// Drop BhopJump +kz_uq_good_dbj 240 +kz_uq_pro_dbj 250 +kz_uq_holy_dbj 260 +kz_uq_leet_dbj 263 +kz_uq_god_dbj 265 +kz_uq_dom_dbj 267 + +// StandUp CountJump (Double or Multi StandUp CountJump=SCJ+10units)(if 100aa all cvar dist +10 units) +kz_uq_good_scj 245 +kz_uq_pro_scj 250 +kz_uq_holy_scj 255 +kz_uq_leet_scj 257 +kz_uq_god_scj 260 +kz_uq_dom_scj 262 + +// Drop StandUp CountJump(double,multi) +kz_uq_good_dropscj 250 +kz_uq_pro_dropscj 255 +kz_uq_holy_dropscj 260 +kz_uq_leet_dropscj 263 +kz_uq_god_dropscj 265 +kz_uq_dom_dropscj 267 + +// Up Bhop +kz_uq_good_upbj 225 +kz_uq_pro_upbj 230 +kz_uq_holy_upbj 235 +kz_uq_leet_upbj 240 +kz_uq_god_upbj 242 +kz_uq_dom_upbj 245 + +// Up StandBhop +kz_uq_good_upsbj 225 +kz_uq_pro_upsbj 230 +kz_uq_holy_upsbj 235 +kz_uq_leet_upsbj 240 +kz_uq_god_upsbj 242 +kz_uq_dom_upsbj 245 + +// Bhop In Duck(Up Bhop In Duck) +kz_uq_good_bhopinduck 205 +kz_uq_pro_bhopinduck 210 +kz_uq_holy_bhopinduck 212 +kz_uq_leet_bhopinduck 215 +kz_uq_god_bhopinduck 217 +kz_uq_dom_bhopinduck 220 + +// Duck Bhop +kz_uq_good_duckbhop 120 +kz_uq_pro_duckbhop 130 +kz_uq_holy_duckbhop 140 +kz_uq_leet_duckbhop 150 +kz_uq_god_duckbhop 160 +kz_uq_dom_duckbhop 162 + +// Real Ladder Bhop +kz_uq_good_realldbhop 240 +kz_uq_pro_realldbhop 250 +kz_uq_holy_realldbhop 255 +kz_uq_leet_realldbhop 260 +kz_uq_god_realldbhop 265 +kz_uq_god_realldbhop 267 + diff --git a/amxmodx/configs/users.ini b/amxmodx/configs/users.ini new file mode 100755 index 0000000..7649319 --- /dev/null +++ b/amxmodx/configs/users.ini @@ -0,0 +1,53 @@ +; Users configuration file +; File location: $moddir/addons/amxmodx/configs/users.ini + +; Line starting with ; is a comment + +; Access flags: +; a - immunity (can't be kicked/banned/slayed/slapped and affected by other commmands) +; b - reservation (can join on reserved slots) +; c - amx_kick command +; d - amx_ban and amx_unban commands (permanent and temporary bans) +; e - amx_slay and amx_slap commands +; f - amx_map command +; g - amx_cvar command (not all cvars will be available) +; h - amx_cfg command +; i - amx_chat and other chat commands +; j - amx_vote and other vote commands +; k - access to sv_password cvar (by amx_cvar command) +; l - access to amx_rcon command and rcon_password cvar (by amx_cvar command) +; m - custom level A (for additional plugins) +; n - custom level B +; o - custom level C +; p - custom level D +; q - custom level E +; r - custom level F +; s - custom level G +; t - custom level H +; u - menu access +; v - amx_ban and amx_unban commands (temporary bans only, about amx_unban, only self performed ban during map gonna be allowed) +; z - user (no admin) + +; Account flags: +; a - disconnect player on invalid password +; b - clan tag +; c - this is steamid/wonid +; d - this is ip +; e - password is not checked (only name/ip/steamid needed) +; k - name or tag is case sensitive. eg: if you set it so the name "Ham" +; is protected and case sensitive (flags "k" only), then anybody +; can use the names "haM", "HAM", "ham", etc, but not "Ham" + +; Password: +; Add to your autoexec.cfg: setinfo _pw "" +; Change _pw to the value of amx_password_field + +; Format of admin account: +; + +; Examples of admin accounts: +; "STEAM_0:0:123456" "" "abcdefghijklmnopqrstuv" "ce" +; "123.45.67.89" "" "abcdefghijklmnopqrstuv" "de" +; "My Name" "my_password" "abcdefghijklmnopqrstuv" "a" + +"loopback" "" "abcdefghijklmnopqrstuv" "de" diff --git a/amxmodx/dlls/amxmodx_mm_i386.so b/amxmodx/dlls/amxmodx_mm_i386.so new file mode 100644 index 0000000..2af224b Binary files /dev/null and b/amxmodx/dlls/amxmodx_mm_i386.so differ diff --git a/amxmodx/modules/amxxarch_amxx_i386.so b/amxmodx/modules/amxxarch_amxx_i386.so new file mode 100644 index 0000000..c389cd7 Binary files /dev/null and b/amxmodx/modules/amxxarch_amxx_i386.so differ diff --git a/amxmodx/modules/cstrike_amxx_i386.so b/amxmodx/modules/cstrike_amxx_i386.so new file mode 100755 index 0000000..429dbf1 Binary files /dev/null and b/amxmodx/modules/cstrike_amxx_i386.so differ diff --git a/amxmodx/modules/csx_amxx_i386.so b/amxmodx/modules/csx_amxx_i386.so new file mode 100755 index 0000000..860a4c8 Binary files /dev/null and b/amxmodx/modules/csx_amxx_i386.so differ diff --git a/amxmodx/modules/curl_amxx_i386.so b/amxmodx/modules/curl_amxx_i386.so new file mode 100644 index 0000000..48c4a51 Binary files /dev/null and b/amxmodx/modules/curl_amxx_i386.so differ diff --git a/amxmodx/modules/curl_amxx_i386.so.bak b/amxmodx/modules/curl_amxx_i386.so.bak new file mode 100644 index 0000000..b5e4184 Binary files /dev/null and b/amxmodx/modules/curl_amxx_i386.so.bak differ diff --git a/amxmodx/modules/engine_amxx_i386.so b/amxmodx/modules/engine_amxx_i386.so new file mode 100755 index 0000000..c9943b1 Binary files /dev/null and b/amxmodx/modules/engine_amxx_i386.so differ diff --git a/amxmodx/modules/fakemeta_amxx_i386.so b/amxmodx/modules/fakemeta_amxx_i386.so new file mode 100755 index 0000000..148936b Binary files /dev/null and b/amxmodx/modules/fakemeta_amxx_i386.so differ diff --git a/amxmodx/modules/fun_amxx_i386.so b/amxmodx/modules/fun_amxx_i386.so new file mode 100755 index 0000000..71fd571 Binary files /dev/null and b/amxmodx/modules/fun_amxx_i386.so differ diff --git a/amxmodx/modules/geoip_amxx_i386.so b/amxmodx/modules/geoip_amxx_i386.so new file mode 100755 index 0000000..c7fdad5 Binary files /dev/null and b/amxmodx/modules/geoip_amxx_i386.so differ diff --git a/amxmodx/modules/hamsandwich_amxx_i386.so b/amxmodx/modules/hamsandwich_amxx_i386.so new file mode 100755 index 0000000..734b6fb Binary files /dev/null and b/amxmodx/modules/hamsandwich_amxx_i386.so differ diff --git a/amxmodx/modules/json_amxx_i386.so b/amxmodx/modules/json_amxx_i386.so new file mode 100755 index 0000000..9894d6c Binary files /dev/null and b/amxmodx/modules/json_amxx_i386.so differ diff --git a/amxmodx/modules/mysql_amxx_i386.so b/amxmodx/modules/mysql_amxx_i386.so new file mode 100755 index 0000000..912fcde Binary files /dev/null and b/amxmodx/modules/mysql_amxx_i386.so differ diff --git a/amxmodx/modules/nvault_amxx_i386.so b/amxmodx/modules/nvault_amxx_i386.so new file mode 100755 index 0000000..6a34a08 Binary files /dev/null and b/amxmodx/modules/nvault_amxx_i386.so differ diff --git a/amxmodx/modules/regex_amxx_i386.so b/amxmodx/modules/regex_amxx_i386.so new file mode 100755 index 0000000..a14c47f Binary files /dev/null and b/amxmodx/modules/regex_amxx_i386.so differ diff --git a/amxmodx/modules/sockets_amxx_i386.so b/amxmodx/modules/sockets_amxx_i386.so new file mode 100755 index 0000000..ef41865 Binary files /dev/null and b/amxmodx/modules/sockets_amxx_i386.so differ diff --git a/amxmodx/modules/sqlite_amxx_i386.so b/amxmodx/modules/sqlite_amxx_i386.so new file mode 100755 index 0000000..ac78537 Binary files /dev/null and b/amxmodx/modules/sqlite_amxx_i386.so differ diff --git a/amxmodx/scripting/KZ_Bot.sma b/amxmodx/scripting/KZ_Bot.sma new file mode 100644 index 0000000..1671287 --- /dev/null +++ b/amxmodx/scripting/KZ_Bot.sma @@ -0,0 +1,2232 @@ +#include +#include +#include +#include +#include +#include +#include + + +#pragma dynamic 131072; + +#pragma tabsize 0 +#pragma semicolon 1 + +#define PLUGIN "KZ:Bots" +#define VERSION "2.0.6b" +#define AUTHOR "Garey - Destroman Edited" + +#if defined client_disconnected +#define client_disconnect client_disconnected +#endif + + + +#define MAX_SOURCES 16 + +#define DEBUG + +enum dl_data +{ + dl_distance, + dl_name[32], + dl_type[32], + dl_time[32], + dl_mapname[64] +} + + +enum source_data +{ + source_id, + source_type, + source_name[32], //name + source_time[32], //block & type + source_mapname[64], //mapname + source_path[128], + source_startframe, + Float:source_starttime, + Float:source_stoptime, + Array:source_array +} + +new bot_sources[MAX_SOURCES][source_data]; +new dl_sources[MAX_SOURCES][dl_data]; + +new RARArchive[128], g_szCurrentMap[32]; +static g_FOUNDED_COMMUNITY; +new Array: update_file_data; +new Array: need_update_com; + +new bool:CheckAgain = false; +new bool:bFoundDemo = false; +new bool:g_Check_Filetime = false; +new g_Check_Files; +new const dl_dir[] = "addons/amxmodx/data/kz_downloader"; +new const update_file[] = "addons/amxmodx/data/kz_downloader/wr_filetime.ini"; +new const archive_dir[] = "addons/amxmodx/data/kz_downloader/archives"; +new const temp_dir[] = "addons/amxmodx/data/kz_downloader/temp"; +new local_demo_folder[64] = "addons/amxmodx/data/kz_bot"; +new const kz_lj[] = "addons/amxmodx/configs/kz_longjumps2.txt"; +new bool:kz_lj2 = false; + +const COMMUNITIES = 2; + +new const g_szDemoFiles[][][] = +{ + { "demofilesurl", "demosfilename", "rarfilelink", "community"}, + { "https://xtreme-jumps.eu/demos.txt", "addons/amxmodx/data/kz_downloader/demos.txt", "http://files.xtreme-jumps.eu/demos", "Xtreme-Jumps"}, + { "https://cosy-climbing.net/demoz.txt", "addons/amxmodx/data/kz_downloader/demoz.txt", "https://cosy-climbing.net/files/demos", "Cosy-Climbing"} +}; + +enum _:RecordDemo +{ + URLS, + DEMOS, + LINK, + NAME +}; +//////////////////////////////////////////////////////////////////////////////////////////// + +enum FWrite +{ + FW_NONE = 0, + FW_DELETESOURCE = (1<<0), + FW_CANOVERRIDE = (1<<1) +} + +enum +{ + SOURCE_REC = 1, + SOURCE_WR = 2 +} + +new map_records_dir[128]; + +new const rec_recorder[] = "ent_recorder"; +new const rec_demoparser[] = "dem_think"; +new Array:record_info[33]; + +new global_bot; + + +new sources_num = 0; +new src_num = 0; +enum _:MODES +{ + MODE_CYCLE, + MODE_USE, + MODE_WAIT +} + +new bot_modes[MODES][] = +{ + "Cycle Run", + "Restart on USE", + "Restart on USE + Wait on distance" +}; + +new bool:plr_botnamed[33]; +new plr_sound[33]; +new plr_mode[33]; +new plr_source[33]; +new plr_frame_it[33]; +new plr_jump[33] = {300, ... }; +new plr_saverun_time[32][32]; +new bool:plr_delayed_save[33]; +new Float:plr_delayed_timer[33]; +new bool:plr_playback[33]; +new bool:bot_inrestart[33]; +new Float:bot_restarttime[33]; +new bool:is_recording[33]; + +enum frame_data +{ + Float:frame_origin[3], + Float:frame_angles[3], + Float:frame_velocity[3], + Float:frame_movetype[3], + frame_buttons, + Float:frame_time +} + +new ghost_data[33][frame_data]; + +new maxplayers; + +new cvar_mode; +new cvar_deletedemos; + + +new Trie:start_buttons; +new Trie:stop_buttons; + +new step_sounds[5][4]; + +//new CheckVisibilityForward; + + +//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// +public plugin_natives() +{ + register_native("save_run", "native_save_run"); + register_native("pause_run", "native_pause_run"); + register_native("unpause_run", "native_unpause_run"); + register_native("reset_run", "native_reset_run"); +} + +public plugin_precache() +{ + step_sounds[0][0] = precache_sound("player/pl_step1.wav"); + step_sounds[0][1] = precache_sound("player/pl_step2.wav"); + step_sounds[0][2] = precache_sound("player/pl_step3.wav"); + step_sounds[0][3] = precache_sound("player/pl_step4.wav"); + + step_sounds[1][0] = precache_sound("player/pl_slosh1.wav"); + step_sounds[1][1] = precache_sound("player/pl_slosh2.wav"); + step_sounds[1][2] = precache_sound("player/pl_slosh3.wav"); + step_sounds[1][3] = precache_sound("player/pl_slosh4.wav"); + + step_sounds[2][0] = precache_sound("player/pl_wade1.wav"); + step_sounds[2][1] = precache_sound("player/pl_wade2.wav"); + step_sounds[2][2] = precache_sound("player/pl_wade3.wav"); + step_sounds[2][3] = precache_sound("player/pl_wade4.wav"); + + step_sounds[3][0] = precache_sound("player/pl_swim1.wav"); + step_sounds[3][1] = precache_sound("player/pl_swim2.wav"); + step_sounds[3][2] = precache_sound("player/pl_swim3.wav"); + step_sounds[3][3] = precache_sound("player/pl_swim4.wav"); + + step_sounds[4][0] = precache_sound("player/pl_ladder1.wav"); + step_sounds[4][1] = precache_sound("player/pl_ladder2.wav"); + step_sounds[4][2] = precache_sound("player/pl_ladder3.wav"); + step_sounds[4][3] = precache_sound("player/pl_ladder4.wav"); +} + +public plugin_init () +{ + register_plugin( PLUGIN, VERSION, AUTHOR); + + register_clcmd( "kzbot_settings","kzbot_settings" ); + register_clcmd( "amx_botmenu","kzbot_settings" ); + register_clcmd( "say /bot","kzbot_settings" ); + register_clcmd( "say /replay","kzbot_settings" ); + register_clcmd( "say /demo","kzbot_settings" ); + + cvar_mode = register_cvar("kzbot_on", "1"); + cvar_deletedemos = register_cvar("kzbot_removedemos", "0"); + + start_buttons = TrieCreate(); + stop_buttons = TrieCreate(); + new const start_names[][] = { "counter_start", "clockstartbutton", "firsttimerelay", "gogogo", "startcounter", "multi_start" }; + new const stop_names[][] = { "counter_off", "clockstopbutton", "clockstop", "stop_counter", "stopcounter", "multi_stop" }; + for(new i = 0; i < sizeof(start_names); i++) + { + TrieSetCell(start_buttons, start_names[i], 1); + } + for(new i = 0; i < sizeof(stop_names); i++) + { + TrieSetCell(stop_buttons, stop_names[i], 1); + } + + + RegisterHam( Ham_Use, "func_button", "fwdUse", 1); + register_forward(FM_AddToFullPack,"fw_addtofullpack_pre", 1); + register_forward(FM_AddToFullPack,"fw_addtofullpack", 1); + register_forward(FM_UpdateClientData, "fw_updateclientdata", 1); + register_forward(FM_CheckVisibility,"checkVisibility"); + register_forward(FM_ClientUserInfoChanged, "fw_clientinfochanged", 1); + + new ent = fm_create_entity( "info_target" ); + if ( ent ) + { + set_pev( ent, pev_classname, rec_recorder ); + set_pev( ent, pev_nextthink, get_gametime() + 0.01 ); + RegisterHam( Ham_Think, "info_target", "forward_think", 1 ); + } + maxplayers = get_maxplayers(); + for ( new i = 1; i <= maxplayers; i++ ) + { + record_info[i] = ArrayCreate( frame_data ); + } + for ( new i = 0; i < MAX_SOURCES; i++) + { + bot_sources[i][source_array] = _:ArrayCreate( frame_data ); + } + + get_mapname(g_szCurrentMap, charsmax(g_szCurrentMap)); + if(equali(g_szCurrentMap, "kz_longjumps2")) + { + kz_lj2 = true; + kz_longjumps2(); + } + set_task(5.0, "checkwrs"); + +} + +public checkwrs() +{ + if(kz_lj2) + { + new ljname[64]; + + formatex(ljname, charsmax(ljname), "%d_%s", dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type]); + if(!already_parsed(dl_sources[src_num][dl_name], ljname)) + { + Check_Download_Demos( 1, true, true); + } + } + else + { + Check_Download_Demos( 1, false, false); + } +} + +public kz_longjumps2() +{ + if(file_exists(kz_lj)) + { + g_FOUNDED_COMMUNITY = 1; + new lj2_file = fopen( kz_lj, "rb" ); + new Line[64]; + new ExplodedString[4][65]; + + while (!feof(lj2_file)) + { + fgets (lj2_file, Line, charsmax(Line)); + + ExplodeString(ExplodedString, 3, 64, Line, ' '); + if(strlen(Line) > 0) + { + trim(ExplodedString[0]); + trim(ExplodedString[1]); + trim(ExplodedString[2]); + + if(!equal(ExplodedString[0], "Block")) + { + src_num++; + dl_sources[src_num][dl_distance] = str_to_num(ExplodedString[0]); + formatex(dl_sources[src_num][dl_type], charsmax(dl_sources[][dl_type]), ExplodedString[1]); + formatex(dl_sources[src_num][dl_name], charsmax(dl_sources[][dl_name]), ExplodedString[2]); + } + } + } + fclose(lj2_file); + } + else + { + server_print("File %s not exists", kz_lj); + } +} + + +public plugin_cfg() +{ + new file; + if(!dir_exists(dl_dir)) + mkdir(dl_dir); + + if(!file_exists(update_file)) + { + file = fopen(update_file, "w"); + fclose(file); + } + + if(file_size(update_file, 1) < COMMUNITIES) + { + delete_file(update_file); + file = fopen(update_file, "w"); + new line[32]; + for(new data = 1; data <= COMMUNITIES; data++) + { + format(line, charsmax(line), "%d 1337%d", data, data); + write_file(update_file, line, -1); + } + fclose(file); + } + + if(!dir_exists(archive_dir)) + mkdir(archive_dir); + if(!dir_exists(temp_dir)) + mkdir(temp_dir); + if(!dir_exists(local_demo_folder)) + mkdir(local_demo_folder); + if(get_pcvar_num(cvar_deletedemos)) + rmdir_recursive(local_demo_folder); + format(map_records_dir, charsmax(map_records_dir), "%s/%s", local_demo_folder ,g_szCurrentMap); + if(!dir_exists(map_records_dir)) + { + mkdir(map_records_dir); + } + + + new szFileName[64]; + new hDir = open_dir(map_records_dir, szFileName, charsmax(szFileName)); + do + { + if(equal(szFileName, "..") || equal(szFileName, ".")) + continue; + + new len = strlen(szFileName); + if(!equal(szFileName[len-3], "rec")) + { + continue; + } + + new path[128]; + format(path, 128, "%s/%s", map_records_dir, szFileName); + load_run(path); + } + while ( next_file( hDir, szFileName, charsmax( szFileName ) ) ); + close_dir(hDir); + + set_task(3.0, "create_bot"); + + update_file_data = ArrayCreate(32); + need_update_com = ArrayCreate(COMMUNITIES); +} + + +public client_putinserver(id) +{ + plr_playback[id] = true; + plr_source[id] = 0; + plr_frame_it[id] = 0; + plr_botnamed[id] = false; +} + +public client_disconnect(id) +{ + if(plr_delayed_save[id]) + { + save_run(id, plr_saverun_time[id], false); + plr_delayed_save[id] = false; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////CURL FOR CHECK AND DOWNLOAD DEMOS AND ARCHIVES//////////////////// +////////////////////////////////////////FileType//////////////////////////////////////////// +/////////////////////////////// 0 - Demos, 1 - Archive ///////////////////////////////////// +///////////////////////////////for kz_lj2 community, download/////////////////////////////// + +public Check_Download_Demos(Community, bool:Download, bool:Filetype) +{ + #if defined DEBUG + server_print("PARSING CHECK COMMUNITY-%d, DOWNLOAD-%d, FILETYPE-%d", Community, Download ,Filetype ); + #endif + + new data[3]; + data[1] = Community; + data[2] = Filetype; + + new CURL:curl = curl_easy_init(); + + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + #if defined DEBUG + //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); //CURL ANALYZE OPTION + #endif + if(kz_lj2) + { + new Link[256]; + format(Link, charsmax(Link), "%s/lj/%s/%d_%s_%s.rar", g_szDemoFiles[Community][LINK], dl_sources[src_num][dl_type], dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name]); + + #if defined DEBUG + server_print("[LINK] : %s", Link); + #endif + + curl_easy_setopt(curl, CURLOPT_URL, Link); + new archivefile[128]; + format (archivefile, charsmax(archivefile), "%s/%d_%s_%s.rar", archive_dir, dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name]); + + data[0] = fopen(archivefile, "wb"); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20); + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 512); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, data[0]); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write"); + curl_easy_perform(curl, "complete", data, sizeof(data)); + } + else + { + if (!Filetype) + { + curl_easy_setopt(curl, CURLOPT_URL, g_szDemoFiles[Community][URLS]); + if(Download) + { + data[0] = fopen(g_szDemoFiles[Community][DEMOS], "wb"); + } + } + else + { + new destname[128]; + format(destname, charsmax(destname), "%s_%s_%s.rar", dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); + + new Link[256]; + format(Link, charsmax(Link), "%s/%s", g_szDemoFiles[Community][LINK], destname); + #if defined DEBUG + server_print("[LINK] : %s", Link); + #endif + + curl_easy_setopt(curl, CURLOPT_URL, Link); + + new archivefile[128]; + format (archivefile, charsmax(archivefile), "%s/%s", archive_dir, destname); + data[0] = fopen(archivefile, "wb"); + } + if(Download) + { + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 512); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, data[0]); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write"); + } + else + { + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20); + curl_easy_setopt(curl, CURLOPT_NOBODY, 1); + curl_easy_setopt(curl, CURLOPT_FILETIME, 1); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_null"); + } + curl_easy_perform(curl, "complete", data, sizeof(data)); + } +} + +public write(data[], size, nmemb, file) +{ + new actual_size = size * nmemb; + fwrite_blocks(file, data, actual_size, BLOCK_CHAR); + return actual_size; +} + +public write_null(data[], size, nmemb, file) +{ + new actual_size = size * nmemb; + return actual_size; +} + +public complete(CURL:curl, CURLcode:code, data[]) +{ + new Community = data[1]; + static filetime, iResponceCode; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, iResponceCode); + curl_easy_getinfo(curl, CURLINFO_FILETIME, filetime); + curl_easy_cleanup(curl); + + new comm[64]; + + if(data[0]) + { + fclose(data[0]); + } + if(kz_lj2) + { + new filename[128]; + + format (filename, charsmax(filename), "%s/%d_%s_%s.rar", archive_dir, dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name] ); + + if (iResponceCode > 399) + { + delete_file(filename); + #if defined DEBUG + server_print("[ERROR] : iResponceCode: %d", iResponceCode); + #endif + server_print("Can't Download archive %s from file %s", filename , kz_lj); + } + else + { + #if defined DEBUG + server_print("[COMPLETE] : iResponceCode: %d - file: %s", iResponceCode, filename); + #endif + DownloadArchiveComplete(filename); + } + } + else + { + if(!data[0]) + { + if(iResponceCode == 0 && filetime == -1) + { + #if defined DEBUG + server_print("Can't Connect to %s", g_szDemoFiles[Community][NAME]); + #endif + set_task (1.0, "UpdateComplete"); + return; + } + #if defined DEBUG + server_print("Connection to %s successfull", g_szDemoFiles[Community][NAME]); + #endif + new com, dat; + new Line[32], ExplodedString[3][33], newLine[32]; + + new recordsfile = fopen( update_file, "rb" ); + while (!feof(recordsfile)) + { + fgets (recordsfile, Line, charsmax(Line)); + ExplodeString(ExplodedString, 2, 32, Line, ' '); + + if(strlen(Line) > 0) { + + + com = str_to_num(ExplodedString[0]); + dat = str_to_num(ExplodedString[1]); + + + if(com == Community && dat) + { + if((filetime != dat && filetime > 0) || file_exists( g_szDemoFiles[Community][DEMOS]) == 0) + { + dat = filetime; + ArrayPushCell(need_update_com, Community); + } + format(newLine, charsmax(newLine), "%d %d", Community, dat); + ArrayPushString(update_file_data, newLine); + } + } + } + fclose(recordsfile); + if(Community == COMMUNITIES) + { + g_Check_Filetime = true; + new i_size = ArraySize(need_update_com); + if(i_size) + { + bFoundDemo = false; + g_Check_Files = i_size; + delete_file(update_file); + new file = fopen(update_file, "w"); + for(new i = 0; i < COMMUNITIES; i++) + { + ArrayGetString(update_file_data, i, comm, charsmax(comm)); + write_file(update_file, comm, i); + } + fclose(file); + } + } + else + { + Check_Download_Demos(Community + 1, false, false); + return; + } + } + if(g_Check_Filetime) + { + if(g_Check_Files > 0) + { + #if defined DEBUG + server_print("UpdateNeeded() - %d", g_Check_Files); + #endif + new upd; + upd = ArrayGetCell(need_update_com, g_Check_Files - 1); + g_Check_Files--; + Check_Download_Demos(upd, true, false); + return; + } + else + { + g_Check_Filetime = false; + set_task (1.0, "UpdateComplete"); + return; + } + } + if(data[2]) + { + new destname[128]; + + format(destname, charsmax(destname), "%s_%s_%s", dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); + + new filename[128]; + format( filename, charsmax( filename ), "%s/%s.rar",archive_dir, destname); + + if (iResponceCode > 399 && !CheckAgain) + { + delete_file(filename); + bFoundDemo = false; + CheckAgain = true; + #if defined DEBUG + server_print("[ERROR] : iResponceCode: %d", iResponceCode); + #endif + OnDemosComplete(Community); + return; + + } + else if (iResponceCode > 399 && CheckAgain) + { + delete_file(filename); + server_print("*No World Record on this map!"); + } + else + { + if(iResponceCode > 0) + { + CheckAgain = false; + #if defined DEBUG + server_print("[COMPLETE] : iResponceCode: %d - file: %s", iResponceCode, filename); + #endif + DownloadArchiveComplete(filename); + return; + } + } + } + } +} + +public UpdateComplete() +{ + #if defined DEBUG + server_print("UpdateComplete()"); + #endif + if(!bFoundDemo) + { + new i; + for(i = 1; i <= COMMUNITIES; i++) + { + if(bFoundDemo) + { + break; + } + OnDemosComplete(i); + } + } + if(!bFoundDemo) + { + server_print("*No WR on this map!"); + } +} + +public OnDemosComplete(Community) +{ + new demoslist[128]; + format( demoslist, charsmax(demoslist), "%s", g_szDemoFiles[Community][DEMOS] ); + + #if defined DEBUG + server_print( "Parsing %s Demo List", g_szDemoFiles[Community][NAME]); + #endif + new iDemosList = fopen( demoslist, "rb" ); + new ExplodedString[7][64]; + new Line[64]; + + while ( !feof( iDemosList ) ) + { + fgets(iDemosList, Line, charsmax(Line)); + ExplodeString(ExplodedString, 6, 63, Line, ' '); + new parsedmap[64], DLMap[64], Extens[32], Mapa[32]; + + parsedmap = ExplodedString[0]; + trim(parsedmap); + new Float:Time = str_to_float( ExplodedString[1]); + + if (containi(parsedmap, g_szCurrentMap ) == 0 && Time > 0.0) + { + split(parsedmap, Mapa, 31, Extens, 31, "["); + trim(Mapa); + trim(Extens); + + if(equali(Mapa, g_szCurrentMap)) + { + src_num++; + if(containi(parsedmap, "[" ) > -1) + { + format( DLMap, charsmax( DLMap ), "%s[%s", Mapa, Extens ); + if(CheckAgain) + { + strtolower(DLMap); + } + + } + else { + format( DLMap, charsmax( DLMap ), "%s", Mapa ); + if(CheckAgain) + { + strtolower(DLMap); + } + } + + #if defined DEBUG + server_print("Parsedmap |%s|", DLMap); + #endif + bFoundDemo = true; + g_FOUNDED_COMMUNITY = Community; + + formatex(dl_sources[src_num][dl_name], charsmax(dl_sources[][dl_name]), ExplodedString[2]); + formatex(dl_sources[src_num][dl_mapname], charsmax(dl_sources[][dl_mapname]), DLMap); + + fnConvertTime(Time, dl_sources[src_num][dl_time], charsmax( dl_sources[][dl_time])); + + #if defined DEBUG + //server_print("Archivename %s_%s_%s", dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); + #endif + } + } + } + fclose(iDemosList); + if(!already_parsed(dl_sources[src_num][dl_name], dl_sources[src_num][dl_time])) + { + Check_Download_Demos(Community, true, true); + } +} + +public already_parsed(player_name[], wr_time[]) +{ + for(new i = 0; i < MAX_SOURCES; i++) + { + remove_quotes(bot_sources[i][source_name]); + remove_quotes(bot_sources[i][source_time]); + trim(bot_sources[i][source_name]); + trim(bot_sources[i][source_time]); + if(equal(bot_sources[i][source_time],wr_time) && equal(bot_sources[i][source_name], player_name)) + { + return true; + } + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////AMXXARCH FOR UNARCHIVE ZIP AND RAR FILES////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// + +public DownloadArchiveComplete(Archive[]) +{ + format( RARArchive, charsmax( RARArchive ), "%s", Archive); + + #if defined DEBUG + server_print("RARArchive: %s", RARArchive); + #endif + AA_Unarchive(RARArchive, temp_dir, "@OnComplete", 0); +} + + +@OnComplete(id, iError) +{ + if(iError != AA_NO_ERROR) + { + #if defined DEBUG + server_print("Failed to unpack. Error code: %d", iError); + #endif + } + else + { + delete_file(RARArchive); + new destname[128]; + if(kz_lj2) + { + format(destname, charsmax(destname), "%s/%d_%s_%s.dem", temp_dir, dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name]); + } + else + { + format(destname, charsmax(destname), "%s/%s_%s_%s.dem", temp_dir, dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); + } + new file = fopen(destname, "rb"); + if(is_valid_demo_file(file)) + { + if(read_demo_header( file )) + { + new Ent = engfunc( EngFunc_CreateNamedEntity , engfunc( EngFunc_AllocString,"info_target" ) ); + set_pev(Ent, pev_classname, rec_demoparser); + set_pev(Ent, pev_iuser1, file ); + set_pev(Ent, pev_iuser2, sources_num ); + set_pev(Ent, pev_iuser3, EncodeText(destname) ); + if(kz_lj2) + { + format(bot_sources[sources_num][source_name], 32, "%s", dl_sources[src_num][dl_name]); + format(bot_sources[sources_num][source_time], 32, "%d_%s", dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type] ); + } + else + { + formatex(bot_sources[sources_num][source_name], 32, "%s", dl_sources[src_num][dl_name]); + formatex(bot_sources[sources_num][source_time], 32, "%s", dl_sources[src_num][dl_time]); + } + set_pev(Ent, pev_nextthink, get_gametime() + 3.0 ); + sources_num++; + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////BOT//////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// + +public create_bot() +{ + global_bot = makebot("Record Bot"); + // is_recbot[global_bot] = true; +} + + +public fw_clientinfochanged(id, buffer) +{ + if(id == global_bot) + { + arrayset(plr_botnamed, false, 32); + } +} + +public fw_prethink(id) +{ + static Float:oldorigin[33][3]; + static Float:oldangles[33][3]; + static oldbuttons[33]; + static damaged_frames[33]; + new bool:dontstep = false; + if(id == global_bot) + { + return FMRES_IGNORED; + } + + if(is_user_connected(id) && !plr_botnamed[id] && global_bot && bot_sources[plr_source[id]][source_type] && plr_frame_it[id]) + { + update_sourcename(id); + plr_botnamed[id] = true; + } + if(bot_inrestart[id]) + { + if(get_gametime() > bot_restarttime[id]) + { + bot_inrestart[id] = false; + plr_frame_it[id] = 0; + } + } + if(bot_sources[plr_source[id]][source_stoptime] && plr_frame_it[id] > 100 && ghost_data[id][frame_time] >= bot_sources[plr_source[id]][source_stoptime]) + { + if(!bot_inrestart[id]) + { + bot_inrestart[id] = true; + bot_restarttime[id] = get_gametime()+0.7; + } + } + if(plr_playback[id]) + { + if(plr_mode[id] == MODE_WAIT ) + { + new Float:origin[2][3]; + pev(id, pev_origin, origin[0]); + xs_vec_copy(ghost_data[id][frame_origin], origin[1]); + if(get_distance_f(origin[0], origin[1]) < 200.0) + { + plr_frame_it[id]++; + } + else + { + dontstep = true; + } + } + else + plr_frame_it[id]++; + } + else + { + dontstep = true; + } + if(!bot_sources[plr_source[id]][source_array] || !ArraySize(bot_sources[plr_source[id]][source_array])) + { + return FMRES_IGNORED; + } + if(plr_frame_it[id] > ArraySize(bot_sources[plr_source[id]][source_array])-1) + { + if(!bot_inrestart[id]) + { + bot_inrestart[id] = true; + bot_restarttime[id] = get_gametime()+0.7; + get_gametime(); + } + plr_frame_it[id] = ArraySize(bot_sources[plr_source[id]][source_array])-1; + return FMRES_IGNORED; + } + new Float:vel[3], Float:origins[3]; + //xs_vec_copy(ghost_data[id][frame_origin], origins); + ArrayGetArray(bot_sources[plr_source[id]][source_array], plr_frame_it[id], ghost_data[id]); + + new onground = ghost_data[id][frame_velocity][2] == 0.0 || ghost_data[id][frame_velocity][2] == 260.25 ? true : false; + + xs_vec_copy(ghost_data[id][frame_origin], origins); + xs_vec_copy(ghost_data[id][frame_velocity], vel); + + if(ghost_data[id][frame_buttons] & IN_USE && ~oldbuttons[id] & IN_USE) + { + if(!bot_sources[plr_source[id]][source_starttime] || !bot_sources[plr_source[id]][source_stoptime]) + { + CheckButton(id); + } + } + + if(get_distance_f(oldorigin[id], origins) > 100.0) + { + damaged_frames[id]++; + } + else + { + xs_vec_copy(origins, oldorigin[id]); + xs_vec_copy(ghost_data[id][frame_angles], oldangles[id]); + damaged_frames[id] = 0; + } + if(damaged_frames[id] > 10) + { + damaged_frames[id] = 0; + xs_vec_copy(origins, oldorigin[id]); + xs_vec_copy(ghost_data[id][frame_angles], oldangles[id]); + } + xs_vec_copy(oldorigin[id], ghost_data[id][frame_origin]); + xs_vec_copy(oldangles[id], ghost_data[id][frame_angles]); + if(get_distance_f(origins, oldorigin[id]) < 100.0 && !damaged_frames[id]) + { + xs_vec_copy(ghost_data[id][frame_origin], oldorigin[id]); + xs_vec_copy(ghost_data[id][frame_angles], oldangles[id]); + } + vel[2] = 0.0; + if(!dontstep) + { + static Float:botorigin[3]; + pev(id, pev_origin, botorigin); + + new on_ladder; + new ent = 0; + static Float:entorigin[3]; + static Classname[33]; + + // Change distance if you want. + const Float:Distance_ladder = 15.0; + while((ent = engfunc(EngFunc_FindEntityInSphere, ent, botorigin, Distance_ladder)) != 0) { + if(!pev_valid(ent)) + continue; + + pev(ent, pev_classname, Classname, 32); + if(equal(Classname, "func_ladder")) + { + pev(ent, pev_origin, entorigin); + on_ladder = 1; + break; + } + } + + if(/*pev(id, pev_movetype) == MOVETYPE_FLY*/on_ladder) + { + playback_sound(id, origins, 4); + } + else if(pev(id, pev_watertype) == CONTENTS_WATER) + { + if(pev(id, pev_waterlevel) >= 2) + { + playback_sound(id, origins, 3); + } + else if(pev(id, pev_waterlevel) == 1) + { + playback_sound(id, origins, 2); + } + else + { + playback_sound(id, origins, 1); + } + } + else + { + if(onground && (vector_length(vel) > 120.0)) + { + if(ghost_data[id][frame_buttons] & IN_JUMP && ~oldbuttons[id] & IN_JUMP && plr_sound[id] < 200) + { + plr_sound[id] = 0; + } + if(pev(id, pev_groupinfo) && pev(id, pev_iuser2) == global_bot) + { + playback_sound(id, origins,0); + } + else if(!pev(id, pev_groupinfo)) + { + playback_sound(id, origins, 0); + } + } + } + } + oldbuttons[id] = ghost_data[id][frame_buttons]; + + plr_sound[id] -= 10; + + + return FMRES_IGNORED; +} + + +public fw_updateclientdata(id, sendweapons, cd_handle ) +{ + if(id == global_bot) + return FMRES_IGNORED; + + new ent = pev(id, pev_iuser2); + if(!ent) + return FMRES_IGNORED; + + if((global_bot == ent && sources_num) && (ArraySize(bot_sources[plr_source[id]][source_array]) > plr_frame_it[id])) + { + //forward_return(FMV_CELL, dllfunc(DLLFunc_UpdateClientData, ent, sendweapons, cd_handle)); + set_cd(cd_handle, CD_Origin, ghost_data[id][frame_origin]); + + static Float:neworigin[3]; + xs_vec_copy(ghost_data[id][frame_origin], neworigin); + neworigin[2]+= 20.0; + set_pev(ent, pev_origin, neworigin); + set_cd(cd_handle, CD_iUser1, pev(id, pev_iuser1)); + set_cd(cd_handle, CD_iUser2, ent); + set_cd(cd_handle, CD_Velocity, ghost_data[id][frame_velocity]); + if(ghost_data[id][frame_buttons] & IN_DUCK) + set_cd(cd_handle, CD_ViewOfs, Float:{0.0, 0.0, 12.0}); + else + set_cd(cd_handle, CD_ViewOfs, Float:{0.0, 0.0, 17.0}); + static sz_time[12]; + static Float:ftime; + + if(bot_sources[plr_source[id]][source_stoptime] && plr_frame_it[id] > 100 && ghost_data[id][frame_time] >= bot_sources[plr_source[id]][source_stoptime]) + { + ftime = bot_sources[plr_source[id]][source_stoptime]-bot_sources[plr_source[id]][source_starttime]; + if(!bot_inrestart[id]) + { + bot_inrestart[id] = true; + bot_restarttime[id] = get_gametime()+0.7; + } + } + else + { + ftime = ghost_data[id][frame_time]-bot_sources[plr_source[id]][source_starttime]; + } + + fnConvertTime( ftime, sz_time, charsmax( sz_time ) ); + if(ftime > 0.0 && !kz_lj2) + { + client_print(id, print_center, "[ %.2s:%.2s.%.2s ]", sz_time, sz_time[2], sz_time[5]); + } + return FMRES_IGNORED; + } + return FMRES_IGNORED; +} + + +public checkVisibility(id, pset) +{ + if(!pev_valid(id)) + { + return FMRES_IGNORED; + } + + if(id == global_bot) + { + /*unregister_forward(FM_CheckVisibility,CheckVisibilityForward); + CheckVisibilityForward = 0;*/ + + forward_return(FMV_CELL, 1); + return FMRES_SUPERCEDE; + } + return FMRES_IGNORED; +} + +public fw_addtofullpack_pre(es, e, ent, host, hostflags, player, pSet) +{ + if(global_bot == host) + { + return FMRES_IGNORED; + } + if(player) + { + if((global_bot == ent || pev(host, pev_iuser2) == global_bot) && sources_num) + { + engfunc(EngFunc_CheckVisibility,ent, pSet); + + /*if(!engfunc(EngFunc_CheckVisibility,ent, pSet)) + { + if(!CheckVisibilityForward) + { + CheckVisibilityForward = register_forward(FM_CheckVisibility, "checkVisibility"); + } + }*/ + } + } + return FMRES_IGNORED; +} + +public fw_addtofullpack(es_handle,e,ent,host,hostflags,player,pSet) +{ + if(global_bot == host) + { + return FMRES_IGNORED; + } + if(player) + { + if(ArraySize(bot_sources[plr_source[host]][source_array]) > plr_frame_it[host]) + { + if(global_bot == ent && sources_num) + { + new Float:origin[2][3]; + pev(host, pev_origin, origin[0]); + xs_vec_copy(ghost_data[host][frame_origin], origin[1]); + new spec = pev(host, pev_iuser2); + if(spec && spec != ent) + { + ghost_data[host] = ghost_data[spec]; + } + set_es(es_handle, ES_Velocity, ghost_data[host][frame_velocity]); + ghost_data[host][frame_angles][0] /= -3.0; + new bool:onground = ghost_data[host][frame_velocity][2] == 0.0 ? true : false; + animate_legs(es_handle, ghost_data[host][frame_buttons], onground); + set_es(es_handle, ES_Angles, ghost_data[host][frame_angles]); + set_es(es_handle, ES_Origin, ghost_data[host][frame_origin]); + set_es(es_handle, ES_Solid, SOLID_NOT); + // fix ugly sequence + set_es(es_handle, ES_Sequence , 75); + set_es(es_handle, ES_RenderMode, kRenderTransAdd); + set_es(es_handle, ES_RenderFx, kRenderFxSolidFast, 0); + set_es(es_handle, ES_RenderFx, kRenderFxSolidSlow, 0); + + if(is_user_alive(host)) + { + set_es(es_handle, ES_RenderAmt, floatround(get_distance_f(origin[0], origin[1]) * 255.0 / 360.0, floatround_floor)); + } + else + { + set_es(es_handle, ES_RenderAmt, 150.0); + } + return FMRES_SUPERCEDE; + } + } + } + return FMRES_IGNORED; +} + + + + +public fwdUse(ent, id) +{ + if(!pev_valid(id) || id > maxplayers) + { + return HAM_IGNORED; + } + + new target[32]; + pev(ent, pev_target, target, charsmax(target)); + + new bool:start_timer = false; + new bool:stop_timer = false; + if(TrieKeyExists(start_buttons, target)) + { + start_timer = true; + } + else if(TrieKeyExists(stop_buttons, target)) + { + stop_timer = true; + } + + if(id == global_bot) + { + if(start_timer && !bot_sources[plr_source[id]][source_starttime]) + { + bot_sources[plr_source[id]][source_starttime] = _:ghost_data[id][frame_time]; + bot_sources[plr_source[id]][source_startframe] = plr_frame_it[id]; + } + else if(stop_timer && !bot_sources[plr_source[id]][source_stoptime]) + { + bot_sources[plr_source[id]][source_stoptime] = _:ghost_data[id][frame_time]; + } + return HAM_SUPERCEDE; + } + + if(start_timer && plr_mode[id] >= MODE_USE) + { + plr_frame_it[id] = bot_sources[plr_source[id]][source_startframe]; + } + + return HAM_IGNORED; +} + +/************************************************ +* * +* RECORDING & PLAYBACK ARRAYS SECTION * +* * +*************************************************/ + + +#define NUM_THREADS 256 + +public forward_think( ent ) +{ + static classname[64]; + pev(ent, pev_classname, classname, 63); + if ( equal( classname, rec_demoparser ) ) + { + new file = pev(ent, pev_iuser1); + new source_index = pev(ent, pev_iuser2); + if(!file) + { + set_pev( ent, pev_flags, pev(ent, pev_flags) | FL_KILLME); + return FMRES_IGNORED; + } + new bool:Finished; + if(!Finished) + { + for(new i = 0; i < NUM_THREADS; i++) + { + if(read_frames(file, bot_sources[source_index][source_array])) + { + Finished = true; + break; + } + } + } + if(Finished) + { + new filename[128]; + DecodeText(pev(ent, pev_iuser3), filename, charsmax(filename)); + fclose( file ); + delete_file(filename); + src_num--; + if(src_num > 0) + { + Check_Download_Demos( g_FOUNDED_COMMUNITY, true, true); + } + new demo_time[32]; + demo_time = bot_sources[source_index][source_time]; + save_run(source_index, demo_time, true); + set_pev(ent, pev_iuser1, 0); + set_pev( ent, pev_flags, pev(ent, pev_flags) | FL_KILLME); + } + else + { + set_pev( ent, pev_nextthink, get_gametime() + 0.001 ); + } + return FMRES_IGNORED; + } + else if(equal(classname, rec_recorder)) + { + new Float:nextthink = 0.01; + //new Float:nextthink = 1//0.009; + if(!get_pcvar_num(cvar_mode)) + return FMRES_IGNORED; + else + { + static players[32], inum; + get_players( players, inum ); + + if(global_bot && inum == 1) + { + set_pev( ent, pev_nextthink, get_gametime()+nextthink); + //server_print("paused"); + return FMRES_IGNORED; + } + for ( new i = 0; i < inum; i++ ) + { + + new id = players[i]; + + if(global_bot == id) + { + //dllfunc(DLLFunc_PlayerPreThink, id); + dllfunc(DLLFunc_PlayerPostThink, id); + //dllfunc(DLLFunc_UpdateClientData, id); + //set_pev(id, pev_solid, SOLID_SLIDEBOX) + set_pev(id, pev_deadflag, DEAD_NO); + set_pev(id, pev_health, 100.0); + } + else + { + if(global_bot && sources_num) + fw_prethink(id); + + if(is_recording[id] || plr_delayed_save[id]) + { + if(plr_delayed_save[id]) + { + if(get_gametime() > plr_delayed_timer[id]) + { + plr_delayed_save[id] = false; + save_run(id, plr_saverun_time[id], false); + } + } + player_record( id ); + } + } + } + } + + set_pev( ent, pev_nextthink, get_gametime()+nextthink); + } + + return FMRES_IGNORED; +} + +public CheckButton( id ) +{ + static ent = -1; + static Float:origin[3]; + xs_vec_copy(ghost_data[id][frame_origin], origin); + while ( (ent = fm_find_ent_in_sphere( ent, origin, 100.0 ) ) != 0 ) + { + new classname[32]; + pev( ent, pev_classname, classname, charsmax( classname ) ); + if ( equal( classname, "func_button" ) ) + { + new Float:eorigin[3]; + fm_get_brush_entity_origin( ent, eorigin ); + static target[32]; + pev( ent, pev_target, target, 31 ); + if(global_bot) + { + if (!bot_sources[plr_source[id]][source_starttime] && TrieKeyExists( start_buttons, target ) ) + { + //bot_findbuttons(id, global_bot) + bot_sources[plr_source[id]][source_startframe] = plr_frame_it[id]; + bot_sources[plr_source[id]][source_starttime] = _:ghost_data[id][frame_time]; + } + if (!bot_sources[plr_source[id]][source_stoptime] && TrieKeyExists( stop_buttons, target ) ) + { + //bot_findbuttons(id, global_bot) + bot_sources[plr_source[id]][source_stoptime] = _:ghost_data[id][frame_time]; + } + } + } + } +} + + +public player_record( id ) +{ + static temp_data[frame_data]; + + temp_data[frame_buttons] = pev(id, pev_button); + + pev(id, pev_origin, temp_data[frame_origin]); + pev(id, pev_v_angle, temp_data[frame_angles]); + pev(id, pev_velocity, temp_data[frame_velocity]); + temp_data[frame_time] = _:get_gametime(); + + ArrayPushArray(record_info[id], temp_data); +} + + +stock bool:read_demo_header( file ) +{ + static temp, entries; + fseek( file, 8, SEEK_SET ); + fread( file, temp, BLOCK_INT ); + + if ( temp != 5 ) + { + return false; + } + + fread( file, temp, BLOCK_INT ); + + if ( temp != 48 ) + { + return false; + } + + fseek( file, 260, SEEK_CUR ); + fseek( file, 260, SEEK_CUR ); + + fseek( file, BLOCK_INT, SEEK_CUR ); + fread( file, temp, BLOCK_INT ); + + fseek( file, temp, SEEK_SET ); + + fread( file, entries, BLOCK_INT ); + for ( new i = 0; i < entries; i++ ) + { + fseek( file, BLOCK_INT, SEEK_CUR ); + fseek( file, 64, SEEK_CUR ); + fseek( file, BLOCK_INT, SEEK_CUR ); + fseek( file, BLOCK_INT, SEEK_CUR ); + fseek( file, BLOCK_INT, SEEK_CUR ); + fseek( file, BLOCK_INT, SEEK_CUR ); + fread( file, temp, BLOCK_INT ); + fseek( file, BLOCK_INT, SEEK_CUR ); + } + + fseek( file, temp, SEEK_SET ); + + return true; + + /* server_print( "%d %d %s %s %d %d %d", iDemoHeader[demoProtocol], iDemoHeader[netProtocol], iDemoHeader[mapName], iDemoHeader[gameDir], iDemoHeader[mapCRC], iDemoHeader[directoryOffset], iDemoEntry[dirEntryCount] ); */ +} + + + +public read_frame_header( file, &Float:gametime) +{ + static type; + fread( file, type, BLOCK_BYTE ); + fread( file, _:gametime, BLOCK_INT ); + fseek( file, 4, SEEK_CUR); + + return(type); +} + + +public read_frames( file, Array:array_to ) +{ + new temp_data[frame_data]; + //if ( !feof( file ) ) + { + new Float:gametime; + new type = read_frame_header( file, gametime ); + new bool:breakme; + + switch ( type ) + { + case 0: + { + } + case 1: + { + static length; + fseek( file, 84, SEEK_CUR ); + //fread( file, _:temp_data[frame_onground], BLOCK_INT ); + fseek( file, 8, SEEK_CUR ); + //fseek( file, 92, SEEK_CUR ); + fread( file, _:temp_data[frame_velocity][0], BLOCK_INT ); + fread( file, _:temp_data[frame_velocity][1], BLOCK_INT ); + fread( file, _:temp_data[frame_velocity][2], BLOCK_INT ); + for ( new i = 0; i < 3; ++i ) + fread( file, _:temp_data[frame_origin][i], BLOCK_INT ); + fseek( file, 124, SEEK_CUR ); + fread( file, _:temp_data[frame_angles][0], BLOCK_INT ); + fread( file, _:temp_data[frame_angles][1], BLOCK_INT ); + fread( file, _:temp_data[frame_angles][2], BLOCK_INT ); + fseek( file, 14, SEEK_CUR ); + fread( file, temp_data[frame_buttons], BLOCK_SHORT ); + fseek( file, 196, SEEK_CUR ); + fread( file, length, BLOCK_INT ); + fseek( file, length, SEEK_CUR ); + } + case 2: + { + } + case 3: + { + fseek( file, 64, SEEK_CUR); + } + case 4: + { + //for ( new i = 0; i < 3; ++i ) + //fread( file, _:temp_data[frame_origin][i], BLOCK_INT ); + + fseek( file, 32, SEEK_CUR ); + + } + case 5: + { + breakme = true; + } + case 6: + { + fseek( file, 84, SEEK_CUR ); + } + case 7: + { + fseek( file, 8, SEEK_CUR ); + } + case 8: + { + static length; + fseek( file, 4, SEEK_CUR ); + fread( file, length, BLOCK_INT ); + fseek( file, length, SEEK_CUR ); + fseek( file, 16, SEEK_CUR ); + } + case 9: + { + static length; + fread( file, length, BLOCK_INT ); + fseek( file, length, SEEK_CUR ); + } + default: + { + breakme = true; + } + } + + if(type == 1) + { + temp_data[frame_time] = _:gametime; + ArrayPushArray(array_to, temp_data); + } + + if(breakme) + { + return true; + } + } + + return false; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////BOT MANAGE SECTION//////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// + +public kzbot_settings(id) +{ + new menu = menu_create( "\rBot Playback:", "kzbot_settings_handle" ); + new text[256]; + menu_additem( menu, "\wStart/Restart Bot", "1"); + menu_additem( menu, "\wPause/Unpause Bot", "2"); + menu_additem( menu, "\wStop Bot", "3"); + if(global_bot) + menu_additem( menu, "\wKick Bot", "4", ADMIN_KICK); + else + menu_additem( menu, "\wAdd Bot", "4", ADMIN_KICK); + menu_additem( menu, "\wFast forward", "5"); + menu_additem( menu, "\wFast backward", "6"); + format(text, charsmax(text), "\wFast Interval: %0.f sec ", float(plr_jump[id])/100.0); + menu_additem(menu, text, "7"); + format(text, charsmax(text), "\wBot mode: %s", bot_modes[plr_mode[id]]); + menu_additem(menu, text, "8"); + new sz_name[32]; + if(kz_lj2) + { + format(sz_name, charsmax(sz_name), "[WR] %s %s" , bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time]); + } + else + { + format(sz_name, charsmax(sz_name), "[%s] %s %.2s:%.2s.%.2s", bot_sources[plr_source[id]][source_type] == SOURCE_WR ? "WR" : "REC", bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time], bot_sources[plr_source[id]][source_time][2], bot_sources[plr_source[id]][source_time][5]); + } + format(text, charsmax(text), "\wBot Source: %s", sz_name); + menu_additem( menu, text, "9"); + menu_additem( menu, "Exit", "0" ); + + menu_setprop(menu, MPROP_PERPAGE, 0); + menu_setprop( menu, MPROP_EXIT, MEXIT_ALL ); + menu_display( id, menu, 0 ); + + return PLUGIN_HANDLED; +} + +public kzbot_settings_handle(id, menu, item) +{ + if( item == MENU_EXIT ) + { + menu_destroy( menu ); + return PLUGIN_HANDLED; + } + switch( item ) + { + case 0: + { + plr_frame_it[id] = 0; + plr_playback[id] = true; + } + case 1: + { + plr_playback[id] = !plr_playback[id]; + } + case 2: + { + plr_frame_it[id] = 0; + plr_playback[id] = false; + } + case 3: + { + if((get_user_flags(id) & ADMIN_KICK)) + { + if(global_bot) + { + server_cmd("kick #%d",get_user_userid(global_bot)); + global_bot = 0; + } + else + { + global_bot = makebot("Record Bot"); + //set_task(0.1, "update_sourcename", id) + } + } + } + case 4: + { + plr_frame_it[id] += plr_jump[id]; + if(plr_frame_it[id] > ArraySize(bot_sources[plr_source[id]][source_array])-1) + { + plr_frame_it[id] = 0; + } + } + case 5: + { + plr_frame_it[id] -= plr_jump[id]; + + if(plr_frame_it[id] < 0) + { + plr_frame_it[id] = 0; + } + } + case 6: + { + plr_jump[id] += 300; + if(plr_jump[id] > 3000) + { + plr_jump[id] = 300; + } + + } + case 7: + { + if(++plr_mode[id] > sizeof(bot_modes)-1) + plr_mode[id] = 0; + } + case 8: + { + if(++plr_source[id] == sources_num) + plr_source[id] = 0; + + if(global_bot) + update_sourcename(id); + } + case 9: + { + menu_destroy( menu ); + return PLUGIN_HANDLED; + } + } + + kzbot_settings(id); + + return PLUGIN_HANDLED; +} + +public makebot(name[64]) +{ + remove_quotes(name); + trim(name); + new bot = engfunc( EngFunc_CreateFakeClient, name ); + if ( !bot ) + { + server_print( "Couldn't create a bot, server full?" ); + return 0; + } + + engfunc( EngFunc_FreeEntPrivateData, bot ); + bot_settings( bot ); + + static szRejectReason[128]; + dllfunc( DLLFunc_ClientConnect, bot, name, "127.0.0.1", szRejectReason ); + if ( !is_user_connected( bot ) ) + { + server_print( "Connection rejected: %s", szRejectReason ); + return 0; + } + + dllfunc( DLLFunc_ClientPutInServer, bot ); + set_pev( bot, pev_spawnflags, pev( bot, pev_spawnflags ) | FL_FAKECLIENT ); + set_pev( bot, pev_flags, pev( bot, pev_flags ) | FL_FAKECLIENT ); + + engclient_cmd( bot , "jointeam" , "2" ); + engclient_cmd( bot , "joinclass" , "1" ); + fm_cs_set_user_team(bot, 2); + ExecuteHamB( Ham_CS_RoundRespawn, bot ); + fm_give_item(bot, "weapon_knife" ); + set_user_godmode( bot, 1 ); + + set_pev(bot, pev_origin, Float:{8192.0, 8192.0, 8192.0}); + return bot; +} + +#define PEV_PDATA_SAFE 2 +#define OFFSET_TEAM 114 +#define OFFSET_DEFUSE_PLANT 193 +#define HAS_DEFUSE_KIT (1<<16) +#define OFFSET_INTERNALMODEL 126 + +stock fm_cs_set_user_team(id, team) +{ + if(!(1 <= id <= maxplayers) || pev_valid(id) != PEV_PDATA_SAFE) + { + return 0; + } + + switch(team) + { + case 1: + { + new iDefuser = get_pdata_int(id, OFFSET_DEFUSE_PLANT); + if(iDefuser & HAS_DEFUSE_KIT) + { + iDefuser -= HAS_DEFUSE_KIT; + set_pdata_int(id, OFFSET_DEFUSE_PLANT, iDefuser); + } + set_pdata_int(id, OFFSET_TEAM, 1); + // set_pdata_int(id, OFFSET_INTERNALMODEL, 4) + } + case 2: + { + if(pev(id, pev_weapons) & (1< 0) + { + return 0; + } + + stepleft[id] = !stepleft[id]; + new irand = random_num(0,1) + (stepleft[id] * 2); + plr_sound[id] = 300; + spawnStaticSound(id, origin, step_sounds[type][irand], 1.0, ATTN_NORM, PITCH_NORM, 0); + + return 0; +} + +#define clamp_byte(%1) ( clamp( %1, 0, 255 ) ) +#define write_coord_f(%1) ( engfunc( EngFunc_WriteCoord, %1 ) ) + +stock spawnStaticSound( const index, const Float:origin[3], const soundIndex, const Float:vol, const Float:atten, const pitch, const flags ) +{ + message_begin( index ? MSG_ONE : MSG_ALL, SVC_SPAWNSTATICSOUND, .player = index ); + { + write_coord_f( origin[0] ); + write_coord_f( origin[1] ); + write_coord_f( origin[2] ); + write_short( soundIndex ); + write_byte( clamp_byte( floatround( vol * 255 ) ) ); + write_byte( clamp_byte( floatround( atten * 64 ) ) ); + write_short( 0 ); + write_byte( pitch ); + write_byte( flags ); + } + message_end(); +} + +stock set_user_fake_name(const id, const name[]) +{ + message_begin(MSG_ONE, SVC_UPDATEUSERINFO, _, id); + write_byte(global_bot - 1); + write_long(get_user_userid(global_bot)); + write_char('\'); + write_char('n'); + write_char('a'); + write_char('m'); + write_char('e'); + write_char('\'); + write_string(name); + for(new i; i < 16; i++) write_byte(0); + message_end(); +} + +public update_sourcename( id ) +{ + new sz_name[32]; + + if(kz_lj2) + { + format(sz_name, charsmax(sz_name), "[WR] %s %s", bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time]); + } + else + { + format(sz_name, charsmax(sz_name), "[%s] %s %.2s:%.2s.%.2s", bot_sources[plr_source[id]][source_type] == SOURCE_WR ? "WR" : "REC", bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time], bot_sources[plr_source[id]][source_time][2], bot_sources[plr_source[id]][source_time][5]); + } + + + set_user_fake_name(id, sz_name); +} + +new RecordFile[128]; + +public load_run(filename[128]) +{ + new file = fopen(filename, "r"); + new string[300]; + new player_name[32], demo_time[32], demo_type[32]; + + fgets(file, string, charsmax(string)); + if(containi(string, "HEADER") == -1) + { + fclose(file); + return -1; + } + static ExplodedString[14][32]; + ExplodeString( ExplodedString, 4, 127, string, ' ' ); + + copy(player_name, 32, ExplodedString[1]); + copy(demo_type, 32, ExplodedString[2]); + copy(demo_time, 32, ExplodedString[3]); + static temp_frame[frame_data]; + new id = sources_num; + bot_sources[id][source_type] = SOURCE_REC; + bot_sources[id][source_id] = sources_num; + bot_sources[id][source_name] = player_name; + bot_sources[id][source_time] = demo_time; + bot_sources[id][source_path] = filename; + remove_quotes(bot_sources[id][source_name]); + remove_quotes(bot_sources[id][source_time]); + remove_quotes(demo_type); + trim(bot_sources[id][source_name]); + trim(bot_sources[id][source_time]); + trim(demo_type); + if(equal(demo_type, "DEMO")) + { + bot_sources[id][source_type] = SOURCE_WR; + } + else + { + format(RecordFile, charsmax(RecordFile), filename); + } + sources_num++; + ArrayClear(bot_sources[id][source_array]); + while(fgets(file, string, charsmax(string))) + { + ExplodeString( ExplodedString, 13, 31, string, ' ' ); + temp_frame[frame_origin][0] = _:str_to_float(ExplodedString[1]); + temp_frame[frame_origin][1] = _:str_to_float(ExplodedString[2]); + temp_frame[frame_origin][2] = _:str_to_float(ExplodedString[3]); + temp_frame[frame_angles][0] = _:str_to_float(ExplodedString[4]); + temp_frame[frame_angles][1] = _:str_to_float(ExplodedString[5]); + temp_frame[frame_angles][2] = _:str_to_float(ExplodedString[6]); + temp_frame[frame_velocity][0] = _:str_to_float(ExplodedString[7]); + temp_frame[frame_velocity][1] = _:str_to_float(ExplodedString[8]); + temp_frame[frame_velocity][2] = _:str_to_float(ExplodedString[9]); + temp_frame[frame_buttons] = _:str_to_num(ExplodedString[10]); + temp_frame[frame_time] = _:str_to_float(ExplodedString[11]); + ArrayPushArray(bot_sources[id][source_array], temp_frame); + + } + fclose(file); + + return id; +} + + +public save_run(id, demo_time[32], bool:is_demofile) +{ + new sz_name[32], sz_steam[32], filename[128]; + if(!is_demofile) + { + get_user_name(id, sz_name, 63); + get_user_authid(id, sz_steam, 63); + if(file_exists(RecordFile)) + delete_file(RecordFile); + } + else + { + copy(sz_name, 32, bot_sources[id][source_name]); + copy(demo_time, 32, bot_sources[id][source_time]); + bot_sources[id][source_type] = SOURCE_WR; + sz_steam = "DEMO"; + } + replace_all(sz_name, charsmax(sz_name), "^"", ""); + replace_all(sz_name, charsmax(sz_name), "^'", ""); + + format(filename, charsmax(filename), "%s/[%s]_%s.rec", map_records_dir, demo_time, sz_name); + new file = fopen(filename, "wb"); + new string[300]; + format(string, charsmax(string), "HEADER ^"%s^" ^"%s^" ^"%s^" ^n", sz_name, sz_steam, demo_time); + fputs(file, string); + //client_print(0, print_chat, "%d", ArraySize( record_info[id] )); + + new Array:array; + if(is_demofile) + { + array = bot_sources[id][source_array]; + + } + else + { + array = record_info[id]; + } + + new arrsize = ArraySize(array); + new temp_frame[frame_data]; + for(new i = 0; i < arrsize; i++ ) + { + ArrayGetArray( array, i, temp_frame ); + format(string, charsmax(string), "INFO %f %f %f %f %f %f %f %f %f %d %f^n", temp_frame[frame_origin][0], + temp_frame[frame_origin][1], temp_frame[frame_origin][2], temp_frame[frame_angles][0], temp_frame[frame_angles][1], + temp_frame[frame_angles][2], temp_frame[frame_velocity][0], temp_frame[frame_velocity][1], temp_frame[frame_velocity][2], + temp_frame[frame_buttons], temp_frame[frame_time]); + fputs(file, string); + } + + fclose(file); + + if(!is_demofile) + { + format(RecordFile, charsmax(RecordFile), filename); + new bool:replacesource = false; + new replaceid; + if(sources_num) + { + for(new i = 0; i < sources_num; i++) + { + + if(bot_sources[i][source_type] == SOURCE_REC) + { + + replacesource = true; + ArrayClear(bot_sources[i][source_array]); + replaceid = i; + break; + } + } + } + if(replacesource) + { + arrayset(plr_botnamed, false, 32); + } + new id = sources_num; + if(replacesource) + id = replaceid; + bot_sources[id][source_id] = id; + bot_sources[id][source_name] = sz_name; + bot_sources[id][source_time] = demo_time; + bot_sources[id][source_path] = filename; + bot_sources[id][source_startframe] = 0; + ArrayGetArray( array, id, temp_frame ); + bot_sources[id][source_starttime] = _:temp_frame[frame_time]; + bot_sources[id][source_stoptime] = _:0.0; + bot_sources[id][source_type] = SOURCE_REC; + CloneRun(array, bot_sources[id][source_array], true); + if(!replacesource) + sources_num++; + } +} \ No newline at end of file diff --git a/amxmodx/scripting/KZ_Chat.sma b/amxmodx/scripting/KZ_Chat.sma new file mode 100644 index 0000000..4677d1e --- /dev/null +++ b/amxmodx/scripting/KZ_Chat.sma @@ -0,0 +1,317 @@ +#include +#include +#include + +#define PLUGIN "KZ[L]Chat" +#define VERSION "1.05" +#define AUTHOR "`L." + +#pragma tabsize 0 + +new g_msgChannel; + +new g_Values[10][] = {{255, 255, 255}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}, {227, 96, 8}, {45, 89, 116}, {103, 44, 38}}; +new Float:g_Pos[4][] = {{0.0, 0.0}, {0.05, 0.55}, {-1.0, 0.2}, {-1.0, 0.7}}; + +// ALL CHAT +new COLCHAR[3][2] = { "^x03"/*team col*/, "^x04"/*green*/, "^x01"/*white*/ }; + +new alv_sndr, alv_str2[26], alv_str4[101]; +new msg[200]; + +public plugin_init() { + register_plugin(PLUGIN, VERSION, AUTHOR); + + register_clcmd("say", "cmdSayChat", _, "@[@|@|@][w|r|g|b|y|m|c] - displays hud message"); + register_clcmd("say_team", "cmdSayAdmin", _, "@ - displays message to admins"); + register_concmd("amx_chat", "cmdChat", _, " - sends message to admins"); + + register_message(get_user_msgid("SayText"), "col_changer"); + register_message(get_user_msgid("ShowMenu"), "message_show_menu"); + register_message(get_user_msgid("VGUIMenu"), "message_vgui_menu"); + register_dictionary("common.txt"); +} + +public cmdSayChat(id, level, cid) { + if(!cmd_access(id, ADMIN_CHAT, cid, 2,false)) + return PLUGIN_CONTINUE; + + new said[6], i = 0; + read_argv(1, said, charsmax(said)); + + while (said[i] == '@') + i++ + + if(!i || i > 3) + return PLUGIN_CONTINUE; + + new message[192], a = 0; + read_args(message, charsmax(message)); + remove_quotes(message); + + switch(said[i]) { + case 'r': a = 1; + case 'g': a = 2; + case 'b': a = 3; + case 'y': a = 4; + case 'm': a = 5; + case 'c': a = 6; + case 'o': a = 7; + } + + new n, s = i; + if(a) { + n++; + s++; + } + while(said[s] && isspace(said[s])) { + n++; + s++; + } + + new name[32]; + get_user_name(id, name, charsmax(name)); + + if(++g_msgChannel > 6 || g_msgChannel < 3) + g_msgChannel = 3; + + new Float:verpos = g_Pos[i][1] + float(g_msgChannel) / 35.0; + set_hudmessage(g_Values[a][0], g_Values[a][1], g_Values[a][2], g_Pos[i][0], verpos, 0, 6.0, 6.0, 0.5, 0.15, -1); + show_hudmessage(0, "%s : %s", name, message[i + n]); + + return PLUGIN_HANDLED; +} + +public cmdSayAdmin(id) { + new said[2]; + read_argv(1, said, charsmax(said)); + + if(said[0] != '@') + return PLUGIN_CONTINUE; + + new message[192], name[32]; + new players[32], inum, pl; + + read_args(message, charsmax(message)); + remove_quotes(message); + + get_user_name(id, name, charsmax(name)); + + if(is_user_admin(id)) + format(message, charsmax(message), "^1[^4ADMINs^1/^4VIPs^1] ^3%s^1 : %s", name, message[1]); + else + format(message, charsmax(message), "^1(USER) %s : %s", name, message[1]); + + get_players(players, inum, "ch"); + + for(new i = 0; i < inum; ++i) { + pl = players[i]; + if(pl == id || get_user_flags(pl) & ADMIN_CHAT) + ColorChat(id, RED, "%s", message); + } + + return PLUGIN_HANDLED; +} + +public cmdChat(id) { + if(!access(id, ADMIN_CHAT)) + return PLUGIN_HANDLED; + + new message[192]; + + read_args(message, charsmax(message)); + remove_quotes(message); + + if(!message[0]) + return PLUGIN_HANDLED; + + new name[32], players[32], inum, authid[32], pl; //, userid; + + get_user_authid(id, authid, charsmax(authid)); + get_user_name(id, name, charsmax(name)); + //userid = get_user_userid(id); + get_players(players, inum, "ch"); + + log_amx("Chat: ^"%s [%s]^" chat ^"%s^"", name, authid, message); + log_message("^"%s [%s]^" triggered ^"amx_chat^" (text ^"%s^")", name, authid, message); + + format(message, charsmax(message), "(ADMINS) %s : %s", name, message); + console_print(id, "%s", message); + + for(new i = 0; i < inum; ++i) { + pl = players[i]; + if(access(pl, ADMIN_CHAT)) + client_print(pl, print_chat, "%s", message); + } + + return PLUGIN_HANDLED; +} +/////////////////////////// ALL CHAT ///////////////////////////////// + +public col_changer(msg_id, msg_dest, rcvr) { + new str2[26]; + get_msg_arg_string(2, str2, 25); + if(equal(str2, "#Cstrike_Chat", 13)) { + new str3[22]; + get_msg_arg_string(3, str3, 21); + + if(!strlen(str3)) { + new str4[101], reshetka; + get_msg_arg_string(4, str4, charsmax(str4)); + if(containi(str4, "#") != -1) { + for(new i = 0; i <= strlen(str4); i++) + if(str4[i] == '#') reshetka++; + if(reshetka >= 5) + return PLUGIN_CONTINUE; + } + + new sndr = get_msg_arg_int(1); + new bool:is_team_msg = !bool:equal(str2, "#Cstrike_Chat_All", 17); + + new sndr_team = get_user_team(sndr); + new bool:is_sndr_spec = !bool:(0 < sndr_team < 3); + new bool:same_as_last = bool:(alv_sndr == sndr && equal(alv_str2, str2) && equal(alv_str4, str4)); + + if(!same_as_last) { + if(!(is_team_msg && (is_sndr_spec || is_team_msg))) { + new flags[5], team[10]; + if(is_user_alive(sndr)) + flags = "bch"; + else + flags = "ach"; + + if(is_team_msg) { + add(flags[strlen(flags)], 4, "e"); + if(sndr_team == 1) + team = "TERRORIST"; + else + team = "CT" + } + + new players[32], num; + get_players(players, num, flags, team); + + if(get_user_flags(sndr) & ADMIN_CFG) + buildmsg(sndr, is_sndr_spec, is_team_msg, sndr_team, 0, 1, str4); + else + buildmsg(sndr, is_sndr_spec, is_team_msg, sndr_team, 0, 2, str4); + + for(new i=0; i < num; i++) { + message_begin(MSG_ONE, get_user_msgid("SayText"), _, players[i]); + write_byte(sndr); + write_string(msg); + message_end(); + } + } + + alv_sndr = sndr; + alv_str2 = str2; + alv_str4 = str4; + if(task_exists(411)) + remove_task(411); + set_task(0.1, "task_clear_antiloop_vars", 411); + } + + if(get_user_flags(sndr) & ADMIN_CFG) { + if(!same_as_last) + buildmsg(sndr, is_sndr_spec, is_team_msg, sndr_team, 0, 1, str4); + + set_msg_arg_string(2, msg); + set_msg_arg_string(4, ""); + } + } + } + + return PLUGIN_CONTINUE; +} + +public buildmsg(sndr, is_sndr_spec, is_team_msg, sndr_team, namecol, msgcol, str4[]) { + new sndr_name[33]; + get_user_name(sndr, sndr_name, 32); + + new prefix[30] = "^x01"; + + if(is_sndr_spec) + prefix = "^x01[SPEC] "; + else if(!is_user_alive(sndr)) + prefix = "^x01[DEAD] "; + + if(is_team_msg) { + if(is_sndr_spec) + prefix = "^x01[Spectator] "; + else if(sndr_team == 1) + add(prefix[strlen(prefix)-1], 29, "[Terrorist] "); + else if(sndr_team == 2) + add(prefix[strlen(prefix)-1], 29, "[Counter-Terrorist] "); + } + + format(msg, 199, "%s%s%s : %s%s", strlen(prefix) > 1 ? prefix : "", COLCHAR[namecol], sndr_name, COLCHAR[msgcol], str4); + return PLUGIN_HANDLED; +} + +public task_clear_antiloop_vars() { + alv_sndr = 0; + alv_str2 = ""; + alv_str4 = ""; + return PLUGIN_HANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Auto Join CT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public message_show_menu(msgid, dest, id) { + if(!should_autojoin(id)) + return PLUGIN_CONTINUE; + + static team_select[] = "#Team_Select"; + static menu_text_code[sizeof team_select]; + get_msg_arg_string(4, menu_text_code, sizeof menu_text_code - 1); + if(!equal(menu_text_code, team_select)) + return PLUGIN_CONTINUE; + + set_force_team_join_task(id, msgid); + + return PLUGIN_HANDLED; +} + +public message_vgui_menu(msgid, dest, id) { + if(get_msg_arg_int(1) != 2 || !should_autojoin(id)) + return PLUGIN_CONTINUE; + + set_force_team_join_task(id, msgid); + + return PLUGIN_HANDLED; +} + +bool:should_autojoin(id) { + return (2 && !get_user_team(id) && !task_exists(id)); +} + +set_force_team_join_task(id, menu_msgid) { + static param_menu_msgid[2]; + param_menu_msgid[0] = menu_msgid; + set_task(0.1, "task_force_team_join", id, param_menu_msgid, sizeof param_menu_msgid); +} + +public task_force_team_join(menu_msgid[], id) { + if(get_user_team(id)) + return; + + force_team_join(id, menu_msgid[0]); +} + +stock force_team_join(id, menu_msgid, const team[] = "2", const class[] = "1") { + static jointeam[] = "jointeam"; + if(class[0] == '0') { + engclient_cmd(id, jointeam, team); + return; + } + + static msg_block, joinclass[] = "joinclass"; + msg_block = get_msg_block(menu_msgid); + set_msg_block(menu_msgid, BLOCK_SET); + engclient_cmd(id, jointeam, team); + engclient_cmd(id, joinclass, class) + set_msg_block(menu_msgid, msg_block); +} diff --git a/amxmodx/scripting/KZ_Engine.sma b/amxmodx/scripting/KZ_Engine.sma new file mode 100644 index 0000000..1faf113 --- /dev/null +++ b/amxmodx/scripting/KZ_Engine.sma @@ -0,0 +1,3177 @@ +/* Todo: + * add weapon tops + * cleanup sqltables + * (menu) kz_showblocks <0/1> + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PLUGIN "KZ[L]MOD" +#define VERSION "1.02" +#define AUTHOR "`L. / Flummi" + +#define pgL_sql_files "https://cs.f0.gg/" +#define ALLMAPS "addons/amxmodx/configs/allmaps.txt" +#define KZ_LEVEL_1 ADMIN_CFG + +#define SCOREATTRIB_NONE 0 +#define SCOREATTRIB_DEAD (1 << 0) +#define SCOREATTRIB_BOMB (1 << 1) +#define SCOREATTRIB_VIP (1 << 2) +// drop weapon +#define WBOX "models/w_weaponbox.mdl" +#define BOMB "models/w_backpack.mdl" +#define SHLD "models/w_shield.mdl" +// spec list +#define UPDATEINTERVAL 0.1 +#define SR 0 +#define SG 50 +#define SB 255 +// screen fade pause +#define PAUSE_RED 176 +#define PAUSE_GREEN 226 +#define PAUSE_BLUE 255 +// remove flashlight +#define HUD_HIDE_FLASH (1<<1) +// remove radar, hp, armor +#define HUD_HIDE_RHA (1<<3) +// remove timer +#define HUD_HIDE_TIMER (1<<4) +// remove money +#define HUD_HIDE_MONEY (1<<5) +// maximum number of cached CPs +#define MAX_CPS 10 + +#pragma tabsize 0 + +new const FL_ONGROUND2 = (FL_ONGROUND | FL_PARTIALGROUND | FL_INWATER | FL_CONVEYOR | FL_FLOAT); + +new kz_authid[33][35]; +new kz_ip[33][16]; + +#define IsOnLadder(%1) (pev(%1, pev_movetype) == MOVETYPE_FLY) +new Float:Checkpoints[33][MAX_CPS][3]; +new Float:SaveStarts[33][2][3]; +new Float:g_pausetime[33]; +new Float:SpecLoc[33][3]; +new Float:NoclipPos[33][3]; +new Float:PauseOrigin[33][3]; +new Float:SavedStart[33][3]; +new Float:DefaultStartPos[3]; +new Float:DefaultFinishPos[3]; +new bool:g_bStart[33]; +new bool:g_bCpAlternate[33]; +new bool:timer_started[33]; +new bool:IsPaused[33]; +new bool:WasPaused[33]; +new bool:firstspawn[33]; + +// check tips bool +new bool:mapIsSlide; +new bool:mapIsGravity; + +#define KZ_R 0 +#define KZ_G 150 +#define KZ_B 0 +// noclip +new bool:canusenoclip[33]; +// hook +new bool:canusehook[33]; +new bool:ishooked[33]; +new hookorigin[33][3]; +new Float:antihookcheat[33]; +// teleport player +new g_teleportPosition[33]; +new g_teleportPlayers[33][32]; +new g_teleportPlayersNum[33]; +new g_teleportOption[33]; +new g_teleportSettings[33]; +new GodModeOn[33]; +new g_iPlayers[32], g_iNum, g_iPlayer; +new maxplayers; +#define DISTANCE 500.0 +#define UPDATE_FREQ 0.1 +#define ENTITY_MAX 2048 +new const invis_class[][] = { + "func_water" +}; + +new bool:theWaterInvis; +new bool:invis_entity[ENTITY_MAX]; +new bool:specInvis_U[33]; +new bool:specInvis_W[33]; +new bool:Screen_fade[33]; + +new bool:NightVisionUse[33]; +new bool:Default_SF[2]; +new bool:AutoStart[33]; + +new Trie:g_tStarts; +new Trie:g_tStops; +// hp booster +new g_bHealsOnMap; +new g_nHP[33]; + +new g_msgHideWeapon; +new bool:gIsUserConnected[33]; +new bool:g_bFlashLight[33]; +new g_iFlashBattery[33]; +new Float:g_flFlashLightTime[33]; +new g_iColor[33][3]; +new g_iTeamColor[2][3]; +new g_msgidFlashlight; +new g_bEnabled = true; +new g_iRadius = 9; +new g_iAttenuation = 1; +new g_iDistanceMax = 2000; +new Float:g_flDrain = 1.2; +new Float:g_flCharge = 0.2; + +// nightvision +new g_nightvision[33]; +new g_default_map_light[32]; +new g_fwLightStyle; +new g_msgScreenFade; + +enum _:ScoreInfo_Args { + PlayerID = 1, + Frags, + Deaths, + ClassID, + TeamID +}; +// speed +new Float:speedshowing[33]; +new movetype[33]; +new bool:show_speed[33]; +new checknumbers[33]; +new gochecknumbers[33]; +new sz_HP[33]; +new chatorhud[33]; +new DATADIR[128]; + +new g_MsgStatusText; +new SyncHudTimer; +new SyncHudSpeed; +new hud_message; +new Sbeam = 0; +new g_entid[33]; +new g_maxents; +new spec_wpn[33][33]; +// fps +new g_iPlayerFps[33]; +new g_iServerFps; +// measure +#define TASK_BEAM 45896 +new Float:g_vFirstLoc[33][3]; +new Float:g_vSecondLoc[33][3]; +new bool:g_bReturnFloat[33]; +new bool:g_bShowBeams[33]; +new bool:g_bDetailedResults[33]; +new bool:g_bAutoSetting[33]; +#define DIST_R 0 +#define DIST_G 87 +#define DIST_B 65 +new g_flBeam; +new g_pCvarMapsSpawns; + +enum { + Red, + Green, + Blue +}; + +new const other_weapons[8] = { + CSW_P90, CSW_FAMAS, CSW_SG552, CSW_AWP, + CSW_M4A1, CSW_M249, CSW_AK47, CSW_AWP +}; + +new const g_block_commands[][] = { + "buy", "buyammo1", "buyammo2", "buyequip", + "cl_autobuy", "cl_rebuy", "cl_setautobuy", "cl_setrebuy" +}; + +new const g_remove_ent[][] = { + "func_bomb_target", "info_bomb_target", "hostage_entity", "func_breakable", + "monster_scientist", "func_hostage_rescue", "info_hostage_rescue", + "info_vip_start", "func_vip_safetyzone", "func_escapezone", + "armoury_entity", "game_player_equip", "player_weaponstrip", + "info_deathmatch_start" +}; + +#include + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INITIAL PLUGIN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public plugin_init() { + register_plugin(PLUGIN, VERSION, AUTHOR); + get_mapname(gMapName, charsmax(gMapName)); + if(get_cvar_float("kz_uptime") == 0.0) { + register_cvar("kz_uptime", "0.000001"); + set_task(0.5, "ChangeRandom"); + return PLUGIN_HANDLED; + } + + SyncHudTimer = CreateHudSyncObj(); + SyncHudSpeed = CreateHudSyncObj(); + hud_message = CreateHudSyncObj(); + + kz_register_saycmd("fps", "cmdFps", 0); + kz_register_saycmd("noclip","noclip",0); + kz_register_saycmd("nc","noclip",0); + register_clcmd("+hook","hook_on"); + register_clcmd("-hook","hook_off"); + // CheckPoint && TP Checkpoint + register_clcmd("/cp","CheckPoint"); + register_clcmd("/tp", "goto_checkpoint"); + register_clcmd("/gc", "goto_checkpoint"); + register_clcmd("say", "goto_checkpoint_say"); + kz_register_saycmd("cp","CheckPoint",0); + kz_register_saycmd("tp", "goto_checkpoint",0); + kz_register_saycmd("stuck", "goto_stuck", 0); + kz_register_saycmd("reset", "reset_checkpoints", 0); + // Default keys block + register_clcmd("drop", "BlockDrop"); + register_clcmd("kill", "client_kill"); + register_clcmd("radio1", "BlockRadio"); + register_clcmd("radio2", "BlockRadio"); + register_clcmd("radio3", "BlockRadio"); + // Block Vote + register_clcmd("vote","vote_block"); + register_clcmd("votekick","vote_block"); + register_clcmd("voteban","vote_block"); + register_clcmd("votemap","vote_block"); + // Native commands + register_clcmd("chooseteam", "kz_menu"); + kz_register_saycmd("pause", "Pause", 0); + kz_register_saycmd("teleport","cmdTeleportMenu",0); + kz_register_saycmd("speed", "cmdShow_speed",0); + // Weapons + kz_register_saycmd("knife", "give_usp_and_knife", 0); + kz_register_saycmd("usp", "give_usp_and_knife", 0); + kz_register_saycmd("weapons", "weapons", 0); + kz_register_saycmd("guns", "weapons", 0); + // Info Msg + kz_register_saycmd("help", "jumphelp", 0); + kz_register_saycmd("uptime", "cmdUptime",0); + // Spec List + kz_register_saycmd("spec", "ct",0); + kz_register_saycmd("ct", "ct",0); + register_clcmd("/ct", "ct"); + kz_register_saycmd("speclist", "cmdSpeclist", 0); + kz_register_saycmd("specadm", "cmdSpeclistAdm", 0); + // Start Command + register_clcmd("/start","goStart"); + kz_register_saycmd("start", "goStart", 0); + kz_register_saycmd("respawn", "goStart", 0); + kz_register_saycmd("savestart","SaveStart",0); + kz_register_saycmd("setstart", "setStart", KZ_LEVEL_1); + kz_register_saycmd("finish", "loadFinish", 0); + // ConfigMenu + kz_register_saycmd("invis", "invisibleMenu", 0); + // Top 15 + kz_register_saycmd("kz", "kz_menu", 0); + kz_register_saycmd("menu", "kz_menu", 0); + kz_register_saycmd("noob10", "stats_show", 0); + kz_register_saycmd("noob15", "stats_show", 0); + kz_register_saycmd("nub15", "stats_show", 0); + kz_register_saycmd("pro15", "stats_show", 0); + kz_register_saycmd("top15", "top15menu", 0); + kz_register_saycmd("top", "top15menu", 0); + kz_register_saycmd("top10", "top15menu", 0); + // Measure + kz_register_saycmd("measure", "cmdMeasure", 0); + kz_register_saycmd("distance", "cmdMeasure", 0); + register_menucmd(register_menuid("\wMeasure Menu^n^n"), 1023, "menuAction"); + register_event("CurWeapon", "curweapon", "be", "1=1"); + register_event("Damage", "Event_Damage", "b", "1=0", "2>0", "3=0", "4=0", "5=0", "6=0"); + register_forward(FM_PlayerPreThink, "fwdPlayerPreThink", 0); + register_message(get_user_msgid("StatusIcon"), "msgStatusIcon"); + register_event("ResetHUD", "resethud", "be"); + RegisterHam(Ham_Touch, "weapon_scout", "Ham_HookScout", false); + RegisterHam (Ham_TakeDamage, "player", "UserBeforeDamage", 0); + register_forward(FM_Touch, "fwdTouch"); + register_forward(FM_GetGameDescription, "fwGetGameDescription"); + register_forward(FM_SetModel, "forward_set_model"); + g_maxents = get_global_int(GL_maxEntities); + register_message(get_user_msgid("Health") , "msgHealth"); + maxplayers = get_maxplayers(); + register_forward(FM_AddToFullPack, "addToFullPack", 1); + register_forward(FM_PlayerPreThink, "semiclip_preThink"); + register_forward(FM_PlayerPostThink, "semiclip_postThink"); + build_entitymap(); + g_msgHideWeapon = get_user_msgid("HideWeapon"); + register_event("ResetHUD", "onResetHUD", "b"); + register_message(g_msgHideWeapon, "msgHideWeapon"); + set_task(UPDATEINTERVAL, "tskShowSpec", 123094, "", 0, "b", 0); + register_forward(FM_StartFrame, "fw_StartFrame"); + register_impulse(100, "Impulse_100"); + register_event("DeathMsg", "Event_DeathMsg", "a"); + g_iTeamColor[1] = {SR,SG,SB}; + g_iTeamColor[0] = {SR,SG,SB}; + g_msgidFlashlight = get_user_msgid("Flashlight"); + // Nightvision + unregister_forward(FM_LightStyle, g_fwLightStyle); + g_msgScreenFade = get_user_msgid("ScreenFade"); + register_message(g_msgScreenFade, "message_screenfade"); + register_message(get_user_msgid("NVGToggle"), "message_nvgtoggle"); + RegisterHam(Ham_Use, "func_button", "fwdUse", 0); + RegisterHam(Ham_Killed, "player", "Ham_beforekill", 0); + RegisterHam(Ham_Killed, "player", "Ham_afterkill", 1); + RegisterHam(Ham_Touch, "weaponbox", "FwdSpawnWeaponbox"); + RegisterHam(Ham_Spawn, "player", "FwdHamPlayerSpawn", 1); + RegisterHam(Ham_Touch, "weaponbox", "GroundWeapon_Touch"); + register_menucmd(register_menuid("Teleport Menu"), 1023, "actionTeleportMenu"); + g_MsgStatusText = get_user_msgid("StatusText"); + register_message(get_user_msgid("ScoreAttrib"), "MessageScoreAttrib"); + new iTimer = create_entity("info_target"); + entity_set_float(iTimer, EV_FL_nextthink, get_gametime() + 0.05); + entity_set_string(iTimer, EV_SZ_classname, "hud_update"); + register_think("hud_update", "timer_task"); + for(new i = 0; i < sizeof(g_block_commands) ; i++) + register_clcmd(g_block_commands[i], "BlockBuy"); + + g_tStarts = TrieCreate(); + g_tStops = TrieCreate(); + + new const szStarts[][] = { + "counter_start", "clockstartbutton", "firsttimerelay", "but_start", "counter_start_button", + "multi_start", "timer_startbutton", "start_timer_emi", "gogogo" + }; + new const szStops[][] = { + "counter_off", "clockstopbutton", "clockstop", "but_stop", "counter_stop_button", + "multi_stop", "stop_counter", "m_counter_end_emi" + }; + + for(new i = 0; i < sizeof szStarts; i++) + TrieSetCell(g_tStarts, szStarts[ i ], 1); + + for(new i = 0; i < sizeof szStops; i++) + TrieSetCell(g_tStops, szStops[ i ], 1); + + // SQL Connect + g_SqlTuple = SQL_MakeStdTuple(); + plugin_sql(); + // KZ ADD SPAWNS + new iEnt = FM_NULLENT, iCount; + while((iEnt = engfunc(EngFunc_FindEntityByString, iEnt, "classname", "info_player_deathmatch"))) + ++iCount; + + new szCvarValue[19]; + get_pcvar_string(g_pCvarMapsSpawns, szCvarValue, charsmax(szCvarValue)); + format(szCvarValue, charsmax(szCvarValue), "%s T:0(%d)", szCvarValue, iCount); + set_pcvar_string(g_pCvarMapsSpawns, szCvarValue); + + SQL_MapID(); + + return PLUGIN_CONTINUE; +} + +public plugin_cfg() { + // global path to /addons/amxmodx/data + get_localinfo("amxx_datadir", DATADIR, charsmax(DATADIR)); + // getting information on server config + sv_airaccelerate = get_cvar_pointer("sv_airaccelerate"); + sv_gravity = get_cvar_pointer("sv_gravity"); + + server_print("[KZ] Airaccelerate = %d", get_pcvar_num(sv_airaccelerate)); + server_print("[KZ] Gravity = %d", get_pcvar_num(sv_gravity)); +} + +public plugin_end() { + new Float:totalup = get_cvar_float("kz_uptime") + halflife_time(); + set_cvar_float("kz_uptime", totalup); +} + +public ChangeRandom() { + if(file_exists(ALLMAPS)) { + new mapname[64], txtsize, line = random_num(0, file_size(ALLMAPS, 1) - 2); + read_file(ALLMAPS, line, mapname, 63, txtsize); + server_cmd("changelevel %s", mapname); + } +} + +public detect_cheat(id, reason[]) { + if(timer_started[id]) { + txtTimerReset(id); + timer_started[id] = false; + if(IsPaused[id]) { + set_pev(id, pev_flags, pev(id, pev_flags) & ~FL_FROZEN); + IsPaused[id] = false; + } + client_print_color(id, print_chat, "%s^x01 Timer stoped. ^3%s^1 detected.", prefix, reason); + } +} + +public fwGetGameDescription() { + forward_return(FMV_STRING, "f0.gg"); + return FMRES_SUPERCEDE; +} + +public cmdUptime(id) { + new timeunit_seconds = floatround(get_cvar_float("kz_uptime") + halflife_time(), floatround_floor); + new timeunit_minutes; + new timeunit_hours; + new timeunit_days; + + if((timeunit_seconds / 60.0) >= 1) { + timeunit_days = floatround(timeunit_seconds / 86400.0, floatround_floor); + timeunit_seconds -= timeunit_days * 86400; + + timeunit_hours = floatround(timeunit_seconds / 3600.0, floatround_floor); + timeunit_seconds -= timeunit_hours * 3600; + + timeunit_minutes = floatround(timeunit_seconds / 60.0, floatround_floor); + timeunit_seconds -= timeunit_minutes * 60; + } + + if(timeunit_days > 0) + client_print_color(id, print_chat, "^x01%s^x03 Server uptime is %d day%s and %s%d:%s%d:%s%d second%s", prefix, timeunit_days, timeunit_days > 1 ? "s" : "", timeunit_hours < 10 ? "0" : "", timeunit_hours, timeunit_minutes < 10 ? "0" : "", timeunit_minutes, timeunit_seconds < 10 ? "0" : "", timeunit_seconds, timeunit_seconds > 1 ? "s" : ""); + else if(timeunit_hours > 0) + client_print_color(id, print_chat, "^x01%s^x03 Server uptime is %s%d:%s%d:%s%d second%s", prefix, timeunit_hours < 10 ? "0" : "", timeunit_hours, timeunit_minutes < 10 ? "0" : "", timeunit_minutes, timeunit_seconds < 10 ? "0" : "", timeunit_seconds, timeunit_seconds > 1 ? "s" : ""); + else if(timeunit_minutes > 0) + client_print_color(id, print_chat, "^x01%s^x03 Server uptime is %s%d:%s%d second%s", prefix, timeunit_minutes < 10 ? "0" : "", timeunit_minutes, timeunit_seconds < 10 ? "0" : "", timeunit_seconds, timeunit_seconds > 1 ? "s" : ""); + else + client_print_color(id, print_chat, "^x01%s^x03 Server uptime is %d second%s", prefix, timeunit_seconds, timeunit_seconds > 1 ? "s" : ""); + + return PLUGIN_CONTINUE; +} + +public plugin_precache() { + kz_add_spawn(); + g_fwLightStyle = register_forward(FM_LightStyle, "fw_LightStyle"); + RegisterHam(Ham_Spawn, "func_door", "Ham_DoorSpawn_P", true); + Sbeam = precache_model("sprites/laserbeam.spr"); + precache_sound("give_hook.wav"); + precache_sound("misc/woohoo.wav"); + g_flBeam = precache_model("sprites/zbeam4.spr"); +} + +kz_add_spawn() { + enum _:SpawnsDatas { + m_szAngles[64], + m_szOrigins[64] + }; + new Array:aSpawns = ArrayCreate(SpawnsDatas); + new mTempDatas[SpawnsDatas]; + + enum { + iAngles, + iOrigins, + iClassName + }; + new Trie:tKeyType = TrieCreate(); + TrieSetCell(tKeyType, "angles", iAngles); + TrieSetCell(tKeyType, "origin", iOrigins); + TrieSetCell(tKeyType, "classname", iClassName); + + new szMapFile[64]; + get_mapname(szMapFile, charsmax(szMapFile)); + format(szMapFile, charsmax(szMapFile), "maps/%s.bsp", szMapFile); + + new szBuffer[64], szKey[16], szValue[32], iType; + new bool:bInEntityDatas, bool:bIsInfoPlayerStartEntity; + new fp = fopen(szMapFile, "rb"); + + new iOffset, iLength, iMaxPos; + fseek(fp, 4, SEEK_SET); + fread(fp, iOffset, BLOCK_INT); + fread(fp, iLength, BLOCK_INT); + iMaxPos = iOffset + iLength; + fseek(fp, iOffset, SEEK_SET); + + while(ftell(fp) < iMaxPos) { + fgets(fp, szBuffer, charsmax(szBuffer)); + trim(szBuffer); + + if(bInEntityDatas) { + if(szBuffer[0] == '}') { + bInEntityDatas = false; + if(bIsInfoPlayerStartEntity) + ArrayPushArray(aSpawns, mTempDatas); + } + else { + parse(szBuffer, szKey, charsmax(szKey), szValue, charsmax(szValue)); + if(TrieGetCell(tKeyType, szKey, iType)) { + switch(iType) { + case iAngles: { + copy(mTempDatas[m_szAngles], charsmax(mTempDatas[m_szAngles]), szValue); + } + case iOrigins: { + copy(mTempDatas[m_szOrigins], charsmax(mTempDatas[m_szOrigins]), szValue); + } + case iClassName: { + if(equal(szValue, "info_player_start")) + bIsInfoPlayerStartEntity = true; + } + } + } + } + } + else if(szBuffer[0] == '{') { + bInEntityDatas = true; + bIsInfoPlayerStartEntity = false; + } + } + fclose(fp); + + new iSpawnsNum = ArraySize(aSpawns); + new iNeededSpawns = max(get_maxplayers() - iSpawnsNum, 0); + + new szCvarValue[19]; + formatex(szCvarValue, charsmax(szCvarValue), "CT:%d(%d)", iSpawnsNum + iNeededSpawns, iSpawnsNum); + g_pCvarMapsSpawns = register_cvar("map_spawns", "", FCVAR_SERVER); + set_pcvar_string(g_pCvarMapsSpawns, szCvarValue); + + if(iSpawnsNum > 0 && iNeededSpawns > 0) { + new iFactor = (iNeededSpawns / iSpawnsNum) + _:!!(iNeededSpawns % iSpawnsNum); + new iszClassName = engfunc(EngFunc_AllocString, "info_player_start"); + + set_kvd(0, KV_ClassName, "info_player_start"); + set_kvd(0, KV_fHandled, 0); + for(new i, j, iEnt; i= g_teleportPlayersNum[id]) + start = pos = g_teleportPosition[id] = 0; + + new len = format(menuBody,511,"\yTeleport Menu\R%d/%d^n\r^n",pos + 1,(g_teleportPlayersNum[id] / 7 + ((g_teleportPlayersNum[id] % 7) ? 1 : 0))); + new end = start + 7; + new keys = MENU_KEY_0; + + if(end > g_teleportPlayersNum[id]) + end = g_teleportPlayersNum[id]; + + new userTime = get_user_time(id); + + if(userTime < 60) + len += format(menuBody[len],511-len,"You can't use teleport in 1 minute af` joined the game^nPlease wait %d seconds...^n^n",(60-userTime)); + + for (new a = start; a < end; ++a) { + i = g_teleportPlayers[id][a]; + get_user_name(i,name,31); + + if(userTime < 60 || noTeleport[i] || cs_get_user_team(i) == CS_TEAM_SPECTATOR) { + ++b; + + if(is_user_admin(i)) + len += format(menuBody[len],511-len,"\d%d. %s \r*^n",b,name); + else + len += format(menuBody[len],511-len,"\d%d. %s^n\r",b,name); + } + else { + keys |= (1< 2.0) { + txtTimerReset(Alive[i]); + timer_started[Alive[i]] = false; + if(IsPaused[Alive[i]]) { + set_pev(Alive[i], pev_flags, pev(Alive[i], pev_flags) & ~FL_FROZEN); + IsPaused[Alive[i]] = false; + } + } + new imin = floatround(kreedztime / 60.0, floatround_floor); + new isec = floatround(kreedztime - imin * 60, floatround_floor); + new mili = floatround((kreedztime - (imin * 60 + isec)) * 100, floatround_floor); + + if(ShowTime[Alive[i]] == 1) { + client_cmd(Alive[i], ";^"hud_centerid^" 0"); + show_status(Alive[i], "[ %02i:%02i.%02i | %d/%d | HP: %s %s ]",imin, isec, mili, checknumbers[Alive[i]], gochecknumbers[Alive[i]], g_nHP, IsPaused[Alive[i]] ? "| *Paused*" : ""); + } + else if(ShowTime[Alive[i]] == 2) { + set_hudmessage(255, 255, 255, -1.0, 0.3, 0, 0.0, 1.0, 0.0, 0.0, 1); + ShowSyncHudMsg(Alive[i], SyncHudTimer, "[ %02i:%02i.%02i | %d/%d | HP: %s %s ]",imin, isec, mili, checknumbers[Alive[i]], gochecknumbers[Alive[i]], g_nHP, IsPaused[Alive[i]] ? "| *Paused*" : ""); + } + } + else + show_status(Alive[i], "[ OFF | %d/%d | HP: %s ]", checknumbers[Alive[i]], gochecknumbers[Alive[i]], g_nHP); + + if(show_speed[Alive[i]]) { + set_hudmessage(255, 255, 255, -1.0, 0.83, 0, 0.0, 0.2, 0.0, 0.0, 1); + ShowSyncHudMsg(Alive[i], SyncHudSpeed, "%.2f units/sec", speedshowing[Alive[i]]); + } + } + for(new i=0;i 0) { + if(_targetname[0]) { + pev(ent, _pev, targetname, 31); + if(containi(targetname, _targetname) != -1) + engfunc(EngFunc_RemoveEntity, ent); + } + else + engfunc(EngFunc_RemoveEntity, ent); + ent = engfunc(EngFunc_FindEntityByString, ent, type, classname); + } +} + +public BlockRadio(id) { + return PLUGIN_HANDLED; +} + +public BlockDrop(id) { + return PLUGIN_HANDLED; +} + +public BlockBuy(id) { + return PLUGIN_CONTINUE; +} + +public client_kill(id) { + console_print(id,"[KZ] You can't kill yourself. This is blocked!"); + return PLUGIN_HANDLED; +} + +public fwdTouch(pToucher,pTouched) { + if(!pev_valid(pToucher)||!pev_valid(pTouched)) + return FMRES_IGNORED; + if(!is_user_connected(pTouched)) + return FMRES_IGNORED; + + new cl[32]; + pev(pToucher,pev_classname,cl,31); + if(equal(cl,"weaponbox")||equal(cl,"armoury_entity")||equal(cl,"weapon_shield")) + return FMRES_SUPERCEDE; + return FMRES_IGNORED; +} + +public FwdSpawnWeaponbox(iEntity) { + set_pev(iEntity, pev_flags, FL_KILLME); + dllfunc(DLLFunc_Think, iEntity); + + return HAM_IGNORED; +} + +public GroundWeapon_Touch(iWeapon, id) { + if(is_user_alive(id) && timer_started[id]) + return HAM_SUPERCEDE; + + return HAM_IGNORED; +} + +public MessageTextMsg() { + new szArg2[32]; + + get_msg_arg_string(2, szArg2, 31); + + if(!equal(szArg2, "#Game_unknown_command")) + return PLUGIN_CONTINUE; + + return PLUGIN_HANDLED; +} + +public msgStatusIcon(msgid, msgdest, id) { + static szIcon[8]; + get_msg_arg_string(2, szIcon, 7); + + if(equal(szIcon, "buyzone")) { + set_pdata_int(id, 235, get_pdata_int(id, 235) & ~(1<<0)); + return PLUGIN_HANDLED; + } + + return PLUGIN_CONTINUE; +} + +public Ham_HookScout(ent, id) { + ExecuteHamB(Ham_Item_Kill, ent); +} + +public vote_block(id) { + console_print(id,"[KZ] Command blocked.!"); + return PLUGIN_HANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Weapons ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public curweapon(id) { + static last_weapon[33]; + static weapon_active, weapon_num; + weapon_active = read_data(1); + weapon_num = read_data(2); + + if((weapon_num != last_weapon[id]) && weapon_active) { + last_weapon[id] = weapon_num; + + static Float:maxspeed; + pev(id, pev_maxspeed, maxspeed); + + if(maxspeed < 0.0) + maxspeed = 250.0; + + kz_hud_message(id, "Speed of this weapon %d", floatround(maxspeed, floatround_floor)); + } + return PLUGIN_HANDLED; +} + +public weapons(id) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + + if(get_user_noclip(id)) { + client_print_color(id, print_chat, "^x01%s^x03 You can not use mode Noclip", prefix); + return PLUGIN_HANDLED; + } + + detect_cheat(id, "Weapons"); + + for(new i = 0; i < 8; i++) { + if(!user_has_weapon(id, other_weapons[i])) { + new item; + item = give_item(id, other_weapons_name[i]); + cs_set_weapon_ammo(item, 0); + } + } + + return PLUGIN_HANDLED; +} + +public give_wpn(id) { + strip_user_weapons(id); + + if(equali(spec_wpn[id], "weapon_knife") || equali(spec_wpn[id], "weapon_usp")) + give_usp_and_knife(id); + else + give_item(id,spec_wpn[id]); + + format(spec_wpn[id], 32, "wpn"); + + return PLUGIN_HANDLED; +} + + +public give_usp_and_knife(id) { + new clip, ammo, wpn_num, wpn[32]; + wpn_num = get_user_weapon(id, clip, ammo); + + if(wpn_num) + get_weaponname(wpn_num, wpn, 31); + else + format(wpn, 31, "weapon_knife"); + + strip_user_weapons(id); + give_item(id, wpn); + + if(equali(wpn, "weapon_knife") || equali(wpn, "weapon_usp")) { + give_item(id,"weapon_knife"); + give_item(id,"weapon_usp"); + cs_set_user_bpammo(id, CSW_USP, 250); + } + + return PLUGIN_HANDLED; +} + +// ========================== Start location ================= +public SaveStart(id) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + if(!(pev(id, pev_flags) & FL_ONGROUND2)) { + kz_chat(id, "You can not do checkpoints in flight."); + return PLUGIN_HANDLED; + } + + if(IsPaused[id]) { + kz_chat(id, "You can't teleport to pause."); + return PLUGIN_HANDLED; + } + timer_started[id] = false; + pev(id, pev_origin, SaveStarts[id][g_bStart[id] ? 1 : 0]); + g_bStart[id] = !g_bStart[id]; + client_print_color(id, print_chat, "^x01%s^x03 Set point. CLICK button to confirm", prefix); + + return PLUGIN_HANDLED; +} + +public goStart(id) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + + if(IsPaused[id]) { + kz_chat(id, "You can't teleport to pause."); + return PLUGIN_HANDLED; + } + if(g_bStart[id]) { + timer_started[id] = false; + set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 0.0 }); + set_pev(id, pev_view_ofs, Float:{ 0.0, 0.0, 12.0 }); + set_pev(id, pev_flags, pev(id, pev_flags) | FL_DUCKING); + set_pev(id, pev_fuser2, 0.0); + engfunc(EngFunc_SetSize, id, { -16.0, -16.0, -18.0 }, { 16.0, 16.0, 32.0 }); + set_pev(id, pev_origin, SaveStarts[id][!g_bStart[id]]); + } + else if(AutoStart[id]) { + set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 0.0 }); + set_pev(id, pev_flags, pev(id, pev_flags) | FL_DUCKING); + set_pev(id, pev_origin, SavedStart[id]); + } + else if(Default_SF[0]) { + set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 0.0 }); + set_pev(id, pev_origin, DefaultStartPos); + } + else + CmdRespawn(id); + return PLUGIN_HANDLED; +} + +public loadFinish(id) { + if(!is_user_connected(id)) + return PLUGIN_HANDLED; + + if(cs_get_user_team(id) == CS_TEAM_UNASSIGNED || cs_get_user_team(id) == CS_TEAM_SPECTATOR || IsPaused[id] == true) { + client_print_color(id, print_chat, "^x01%s^x03 You can not currently use the command", prefix); + return PLUGIN_HANDLED; + } + + if(Default_SF[1] == false) { + client_print_color(id, print_chat, "^x01%s^x03 The finish position is unknown.", prefix); + return PLUGIN_HANDLED; + } + reset_checkpoints(id); + + set_pev(id, pev_origin, DefaultFinishPos); + entity_set_vector(id, EV_VEC_velocity, Float:{ 0.0,0.0,0.0 }); + + client_print_color(id, print_chat, "%s^1 Moved to finish position", prefix); + + return PLUGIN_HANDLED; +} + +public setStart(id) { + if((get_user_flags(id) & KZ_LEVEL_1)) { + new Float:origin[3]; + pev(id, pev_origin, origin); + DefaultStartPos = origin; + SQL_StartFinish(true, origin); + AutoStart[id] = false; + client_print_color(id, print_chat, "%s^x01 Established the starting position on the map.", prefix); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USER KILLED ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public Ham_beforekill(id) { + new clip, ammo, wpn_num; + wpn_num = get_user_weapon(id, clip, ammo); + + if(wpn_num) + get_weaponname(wpn_num, spec_wpn[id], 32); + else + format(spec_wpn[id], 32, "weapon_knife"); + + if(!(cs_get_user_team(id) == CS_TEAM_SPECTATOR)) { + if(cs_get_user_team(id) == CS_TEAM_T) + cs_set_user_team(id, CS_TEAM_CT); + else + cs_set_user_team(id, CS_TEAM_CT); + } +} + +public Ham_afterkill(id) { + set_pev(id, pev_deadflag, DEAD_RESPAWNABLE); + + if(containi(spec_wpn[id], "weapon_") == -1) + format(spec_wpn[id], 32, "weapon_knife"); + + new MyDeaths[32]; + MyDeaths[id] = cs_get_user_deaths(id); + cs_set_user_deaths(id, MyDeaths[id] - 1); + + set_task(0.1, "goStart", id); + set_task(0.1, "give_wpn", id); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USER TAKE DMG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public UserBeforeDamage(victim, weapon, attacker, Float:damage, damagebits) { + if(damagebits & DMG_FALL) + return PLUGIN_HANDLED + else { + if(get_user_team(attacker) != get_user_team(victim)) + return HAM_SUPERCEDE; + } + return HAM_IGNORED; +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NightVision ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public fw_LightStyle(style, const val[]) { + if(!style) + copy(g_default_map_light, charsmax(g_default_map_light), val); +} + +public message_screenfade(msg_id, msg_dest, msg_entity) { + if(!g_nightvision[msg_entity]) + return PLUGIN_CONTINUE; + + if(get_msg_arg_int(4) != 255 || get_msg_arg_int(5) != 255 || get_msg_arg_int(6) != 255 || get_msg_arg_int(7) < 200) + return PLUGIN_CONTINUE; + + remove_task(msg_entity); + set_task(get_msg_arg_int(1) / 4096.0, "task_restore_screenfade", msg_entity); + + return PLUGIN_CONTINUE; +} + +public message_nvgtoggle(msg_id, msg_dest, msg_entity) { + static flag; + flag = get_msg_arg_int(1); + + message_begin(MSG_ONE_UNRELIABLE, SVC_LIGHTSTYLE, _, msg_entity); + write_byte(0); + + if(flag) + write_string("#"); + else + write_string(g_default_map_light); + + message_end(); + + if(!task_exists(msg_entity)) { + message_begin(MSG_ONE, g_msgScreenFade, _, msg_entity); + write_short((1<<12)); + write_short(0); + write_short(0x0004); + + if(flag) { + write_byte(255); + write_byte(255); + write_byte(255); + write_byte(1); + } + else { + write_byte(0); + write_byte(0); + write_byte(0); + write_byte(0); + } + + message_end(); + } + + g_nightvision[msg_entity] = flag; + + return PLUGIN_HANDLED; +} + +public task_restore_screenfade(id) { + if(!g_nightvision[id]) + return; + + message_begin(MSG_ONE, g_msgScreenFade, _, id); + write_short((1<<12)); + write_short(0); + write_short(0x0004); + write_byte(255); + write_byte(255); + write_byte(255); + write_byte(1); + message_end(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ProKreedzHook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public hook_on(id) { + if(!is_user_connected(id)) + return PLUGIN_HANDLED; + + if((cs_get_user_team(id) != CS_TEAM_CT) && (cs_get_user_team(id) != CS_TEAM_T)) + return PLUGIN_HANDLED; + + if(!is_user_alive(id)) + return PLUGIN_HANDLED; + + if(!canusehook[id] && !(get_user_flags(id) & KZ_LEVEL_1)) { + client_print_color(id, print_chat, "%s^1 Go through the map to get the Hook.", prefix); + return PLUGIN_HANDLED; + } + + get_user_origin(id, hookorigin[id], 3); + + antihookcheat[id] = get_gametime(); + detect_cheat(id, "Hook"); + + ishooked[id] = true; + + set_task(0.1,"hook_task",id,"",0,"ab"); + hook_task(id); + + return PLUGIN_HANDLED; +} + +public is_hooked(id) { + return ishooked[id]; +} + +public hook_off(id) { + if(!is_user_connected(id)) + return PLUGIN_HANDLED; + + if(((cs_get_user_team(id) != CS_TEAM_CT) && (cs_get_user_team(id) != CS_TEAM_T)) || !ishooked[id]) + return PLUGIN_HANDLED; + + remove_hook(id); + return PLUGIN_HANDLED; +} + +public hook_task(id) { + if(!is_user_connected(id) || !is_user_alive(id)) + remove_hook(id); + + new origin[3], Float:velocity[3]; + get_user_origin(id, origin); + + new distance = get_distance(hookorigin[id], origin); + if(distance > 50) { + Create_TE_BEAMENTPOINT(id, hookorigin[id]); + + set_rendering(id, kRenderFxGlowShell, random_num(1,255), random_num(1,255), random_num(1,255), kRenderNormal, 16); + + velocity[0] = (hookorigin[id][0] - origin[0]) * (700.0 / distance); + velocity[1] = (hookorigin[id][1] - origin[1]) * (700.0 / distance); + velocity[2] = (hookorigin[id][2] - origin[2]) * (700.0 / distance); + + entity_set_vector(id,EV_VEC_velocity,velocity); + entity_set_int(id, EV_INT_gaitsequence, 6); + } + else { + entity_set_vector(id,EV_VEC_velocity,Float:{0.0,0.0,0.0}); + remove_hook(id); + } +} + +stock Create_TE_BEAMENTPOINT(id, origin[3]) { + message_begin(MSG_BROADCAST, SVC_TEMPENTITY); + write_byte(TE_BEAMENTPOINT); + write_short(id); + write_coord(origin[0]); + write_coord(origin[1]); + write_coord(origin[2]); + write_short(Sbeam); + write_byte(0); + write_byte(0); + write_byte(1); + write_byte(30); + write_byte(0); + write_byte(random_num(1,255)); + write_byte(random_num(1,255)); + write_byte(random_num(1,255)); + write_byte(75); + write_byte(0); + message_end(); + + message_begin(MSG_BROADCAST, SVC_TEMPENTITY); + write_byte(TE_BEAMENTPOINT); + write_short(id); + write_coord(origin[0]); + write_coord(origin[1]); + write_coord(origin[2]); + write_short(Sbeam); + write_byte(0); + write_byte(0); + write_byte(1); + write_byte(10); + write_byte(0); + write_byte(random_num(1,255)); + write_byte(random_num(1,255)); + write_byte(random_num(1,255)); + write_byte(150); + write_byte(0); + message_end(); +} + +stock Create_TE_SPRITETRAIL(id, start[3], end[3]) { + message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, .player = id); + write_byte(TE_SPRITETRAIL); + write_coord(start[0]); // start position (X) + write_coord(start[1]); // start position (Y) + write_coord(start[2]); // start position (Z) + write_coord(end[0]); // end position (X) + write_coord(end[1]); // end position (Y) + write_coord(end[2]); // end position (Z) + write_short(g_sShadow); // sprite index + write_byte(50); // count + write_byte(15); // life in 0.1's + write_byte(1); // scale in 0.1's + write_byte(2); // velocity along vector in 10's + write_byte(6); // randomness of velocity in 10's + message_end(); +} + +public remove_hook(id) { + if(task_exists(id)) + remove_task(id); + + message_begin(MSG_BROADCAST, SVC_TEMPENTITY); + write_byte(TE_KILLBEAM); + write_short(id); + message_end(); + + set_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderNormal, 0); + + ishooked[id] = false; +} + +public remove_hook_2(id) { + if(task_exists(id)) + remove_task(id); + + ishooked[id] = false; +} + +public give_hook_finish(id) { + if(access(id,KZ_LEVEL_1)) + return PLUGIN_HANDLED; + + canusehook[id] = true; + + set_hudmessage(KZ_R, KZ_G, KZ_B, -0.2, 0.1, 0, 0.0, 10.0, 0.4, 0.4, 4); + show_hudmessage(id, "Rewards:^n- Hook (Just bind '+hook' on a key)"); + + client_cmd(id, "speak give_hook"); + + return PLUGIN_HANDLED; +} + +public remove_hook_complete(id) { + if(task_exists(id)) + remove_task(id); + + ishooked[id] = false; + canusehook[id] = false; + remove_hook(id); +} + +public resethud(id) { + if(GodModeOn[id] == 1) + set_user_godmode(id, 1); + else + set_user_godmode(id, 0); +} + +public noclip(id) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + + if(timer_started[id] && !IsPaused[id]) + Pause(id); + + new noclip = !get_user_noclip(id); + + if(IsPaused[id]) { + set_user_noclip(id, noclip); + antihookcheat[id] = get_gametime(); + + if(noclip) { + pev(id, pev_origin, NoclipPos[id]); + set_pev(id, pev_flags, pev(id, pev_flags) & ~FL_FROZEN); + } + else { + set_pev(id, pev_origin, NoclipPos[id]); + set_pev(id, pev_flags, pev(id, pev_flags) | FL_FROZEN); + } + + kz_chat(id, "Noclip %s", noclip ? "ON" : "OFF"); + } + else + client_print_color(id, print_chat, "^x01%s^x03 Noclip can not be activated now!", prefix); + + return PLUGIN_HANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cursor view stats ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public fwdPlayerPreThink(id) { + if(!is_user_connected(id) || is_user_bot(id)) + return; + + if((cs_get_user_team(id) == CS_TEAM_SPECTATOR) || (cs_get_user_team(id) == CS_TEAM_UNASSIGNED)) + if(is_user_alive(id)) + user_kill(id); + + if(pev(id, pev_deadflag) == DEAD_DYING) + set_pev(id, pev_framerate, 2000.0); + + new bool:alive = true; + new player, body; + get_user_aiming(id, player, body); + + if(!is_user_alive(id) || !is_user_alive(player)) + alive = false; + + if(!InvisUser[id]) { + if(alive) { + new name[32]; + get_user_name(player, name, 31); + set_hudmessage(KZ_R, KZ_G, KZ_B, -1.0, 0.60, 0, 0.01, 0.1, 0.01, 0.01, 4); + + if(IsPaused[player] == true) + show_hudmessage(id, "%s^n[ PAUSED | %d/%d ]", name, checknumbers[player], gochecknumbers[player]); + else if(timer_started[player]) { + new Float:playersec = halflife_time() - timer_time[player], playermin; + + if((playersec / 60.000000) >= 1) { + playermin = floatround(playersec / 60.000000,floatround_floor); + playersec -= (floatround(playersec / 60.000000,floatround_floor) * 60); + } + + show_hudmessage(id, "%s^n[ %s%d:%s%.1f | %d/%d ]", name, playermin >= 10 ? "" : "0", playermin, playersec >= 10 ? "" : "0", playersec, checknumbers[player], gochecknumbers[player]); + } + else + show_hudmessage(id, "%s^n[ OFF | %d/%d ]", name, checknumbers[player], gochecknumbers[player]); + } + } + + if(cs_get_user_team(id) == CS_TEAM_SPECTATOR) { + new target = pev(id, pev_iuser2); + + if(full_Invisible[target]) { + if(!Screen_fade[id]) + Screen(id, true); + } + else { + if(Screen_fade[id]) + Screen(id, false); + } + } + + if(is_user_alive(id)) { + if(g_bFlashLight[id]) + Make_FlashLight(id); + + // Speed + new Float:velocity[3], Float:speed; + pev(id, pev_velocity, velocity); + movetype[id] = pev(id, pev_movetype); + + if(velocity[2] != 0) + velocity[2] -= velocity[2]; + + speed = vector_length(velocity); + speedshowing[id] = speed; + + if(!mapIsGravity && is_user_alive(id) && get_user_gravity(id) != 1.0) { + detect_cheat(id, "Gravity"); + set_user_gravity(id); + } + } + + if(get_user_flags(id) & ADMIN_IMMUNITY && is_user_connected(id) && cs_get_user_team(id) != CS_TEAM_SPECTATOR && cs_get_user_team(id) != CS_TEAM_UNASSIGNED) + cs_set_user_team(id, CS_TEAM_T, CS_CT_URBAN); + + static Float:last_check[33], Float:game_time; + static frames[33]; + + game_time = get_gametime(); + + if(game_time - last_check[id] > 1.0) { + g_iPlayerFps[id] = frames[id]; + frames[id] = 0; + last_check[id] = game_time; + } + frames[id]++; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckPoint ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public CheckPoint(id) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + + if(!(pev(id, pev_flags) & FL_ONGROUND2) && !IsOnLadder(id)) { + kz_chat(id, "You can not do checkpoints in flight."); + return PLUGIN_HANDLED; + } + + if(IsPaused[id]) { + kz_chat(id, "Checkpoint is not possible because of the pause."); + return PLUGIN_HANDLED; + } + new entclassname[33]; + pev(pev(id, pev_groundentity), pev_classname, entclassname, 32); + + if(equal(entclassname, "func_door")) { + kz_chat(id, "You can not do checkpoints on bhop block."); + return PLUGIN_HANDLED; + } + + for(new i=MAX_CPS-1;i>0;i--) { + Checkpoints[id][i][0] = Checkpoints[id][i-1][0]; + Checkpoints[id][i][1] = Checkpoints[id][i-1][1]; + Checkpoints[id][i][2] = Checkpoints[id][i-1][2]; + } + + new Float:origin[3]; + pev(id, pev_origin, origin); + + Checkpoints[id][0][0] = origin[0]; + Checkpoints[id][0][1] = origin[1]; + Checkpoints[id][0][2] = origin[2]; + + pev(id, pev_origin, Checkpoints[id][g_bCpAlternate[id] ? 1 : 0]); + g_bCpAlternate[id] = !g_bCpAlternate[id]; + checknumbers[id]++; + + return PLUGIN_HANDLED; +} + +public goto_checkpoint(id) { + if(IsPaused[id] || !is_user_alive(id)) { + kz_chat(id, "You can't teleport to pause."); + return PLUGIN_HANDLED; + } + + if(checknumbers[id] > 0) { + if(read_argc() == 2) { + new szcp[8], cpnum; + + read_argv(1,szcp,8); + cpnum = str_to_num(szcp) - 1; + + if(cpnum >= 0 && cpnum < MAX_CPS) { + if(cpnum < checknumbers[id]) + GoCheck(id,cpnum); + else + client_print_color(id, print_chat, "^x01%s^x03 You have not created as many checkpoints!", prefix); + } + else + GoCheck(id, 0); + } + else + GoCheck(id, 0); + } + else + client_print_color(id, print_chat, "^x01%s^x03 You have no checkpoints!", prefix); + + return PLUGIN_HANDLED; +} + +public GoCheck(id,cp) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + + if(checknumbers[id] == 0) { + kz_chat(id, "You don't have enough checkpoints."); + return PLUGIN_HANDLED; + } + + if(IsPaused[id]) { + kz_chat(id, "You can't teleport to pause."); + return PLUGIN_HANDLED; + } + + engfunc(EngFunc_SetOrigin, id, Checkpoints[id][cp]); + set_pev(id, pev_velocity, Float:{ 0.0, 0.0, 0.0 }); + set_pev(id, pev_flags, pev(id, pev_flags) | FL_DUCKING); + + gochecknumbers[id]++; + return PLUGIN_HANDLED; +} + +public goto_checkpoint_say(id) { + if(read_argc() == 2) { + new szarg1[32], args1[16], args2[16]; + read_argv(1,szarg1,32); + copyc(args1,16,szarg1,32); + copy(args2,16,szarg1[strlen(args1)+1]); + if(equal(args1,".tp") || equal(args1,"/tp") || equal(args1,"/gc") || equal(args1,".gc") || equal(args1,".gocheck") || equal(args1,"/gocheck")) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + if(IsPaused[id]) { + kz_chat(id, "You can't teleport to pause."); + return PLUGIN_HANDLED; + } + + if(checknumbers[id] > 0) { + new cpnum = str_to_num(args2) - 1; + if(cpnum >= 0 && cpnum < MAX_CPS) { + if(cpnum < checknumbers[id]) + GoCheck(id,cpnum); + else + client_print_color(id, print_chat, "^x01%s^x03 You have not created as many checkpoints!", prefix); + } + else + GoCheck(id,0); + } + else + client_print_color(id, print_chat, "^x01%s^x03 You have no checkpoints!", prefix); + + return PLUGIN_HANDLED; + } + } + + return PLUGIN_CONTINUE; +} + +public goto_stuck(id) { + if(is_user_alive(id)) { + if(checknumbers[id] > 1) + GoCheck(id,1); + else + client_print_color(id, print_chat, "^x01%s^x03 You have no checkpoints!", prefix); + } + return PLUGIN_HANDLED; +} + +public reset_checkpoints(id) { + if(!is_user_alive(id)) { + kz_chat(id, "You have to be alive."); + return PLUGIN_HANDLED; + } + + if(IsPaused[id]) { + kz_chat(id, "You can't teleport to pause."); + return PLUGIN_HANDLED; + } + + checknumbers[id] = 0; + gochecknumbers[id] = 0; + timer_started[id] = false; + timer_time[id] = 0.0; + message_begin(MSG_ONE_UNRELIABLE, g_MsgStatusText, _, id); + write_byte(0); + message_end(); + + give_item(id,"weapon_knife"); + give_item(id,"weapon_usp"); + cs_set_user_bpammo(id, CSW_USP, 250); + + if(IsPaused[id]) { + set_pev(id, pev_flags, pev(id, pev_flags) & ~FL_FROZEN); + IsPaused[id] = false; + } + + return PLUGIN_HANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Semiclip & Invis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +build_entitymap() { + new ent, classname[32], j; + + for(ent = maxplayers + 1; ent < ENTITY_MAX; ent++) { + if(!pev_valid(ent)) + continue; + + pev(ent, pev_classname, classname, 31); + for(j=0; j < sizeof invis_class; j++) { + if(equal(classname, invis_class[j], strlen(classname))) { + invis_entity[ent] = true; + theWaterInvis = true; + } + } + } +} + +public addToFullPack(es, e, ent, host, hostflags, player, pSet) { + if(!is_user_connected(host)) + return; + + if(NightVisionUse[host]) // ?? + if(1 <= host <= 32 && get_orig_retval()) + if(player) + if(host == ent) + set_es(es, ES_Effects, (get_es(es, ES_Effects)|EF_BRIGHTLIGHT)); + + if(InvisWater[host]) { + if(invis_entity[ent]) { + set_es(es, ES_Effects, EF_NODRAW); + return + } + } + + if(player) { + if(host != ent && get_orig_retval() && is_user_alive(host)) { + set_es(es, ES_Solid, SOLID_NOT); + set_es(es, ES_RenderMode, kRenderTransAdd); + set_es(es, ES_RenderAmt, 50); + } + + if(InvisUser[host]) { + set_es(es, ES_RenderMode, kRenderTransTexture); + set_es(es, ES_RenderAmt, 0); + set_es(es, ES_Origin, { 999999999.0, 999999999.0, 999999999.0 }); + } + + if(full_Invisible[ent]) { + set_es(es, ES_Effects, EF_NODRAW); + set_es(es, ES_Origin, {-10000.0, -10000.0, -10000.0}); + return; + } + } +} + +public semiclip_preThink(id) { + if(!is_user_alive(id)) + return; + + get_players(g_iPlayers, g_iNum, "a"); + + for(new i = 0; i 0) + GoCheck(id, 0); + else + client_print_color(id, print_chat, "^x01%s^x03 You have no checkpoints!", prefix); + ClimbMenu(id); + } + case 2: { + goto_stuck(id); + ClimbMenu(id); + } + case 3: { + goStart(id); + ClimbMenu(id); + } + case 4: { + SaveStart(id); + ClimbMenu(id); + } + case 5: { + Pause(id); + ClimbMenu(id); + } + case 6: { + ct(id); + ClimbMenu(id); + } + case 7: { + GodMode(id); + ClimbMenu(id, 1); + } + case 8: { + kz_top_menu(id); + } + case 9: { + cmdTeleportMenu(id); + } + case 10: { + client_cmd(id, "say /measure"); + } + case 11: { + invisibleMenu(id); + } + case 12: { + ShowTimer_Menu(id); + } + case 13: { + SQL_ConfigSave(id); + ClimbMenu(id, 1); + } + } + return PLUGIN_HANDLED; +} + +public invisibleMenu(id) { + new menu = menu_create("\yInvisible Menu\w", "invisibleMenuHandler"); + new msginvis[64], msgwaterinvis[64], msgfull[64]; + + formatex(msginvis, 63, "Invisible Players - %s", InvisUser[id] ? "\yON" : "\rOFF"); + if(theWaterInvis) + formatex(msgwaterinvis, 63, "Invisible Water - %s", InvisWater[id] ? "\yON" : "\rOFF"); + else + formatex(msgwaterinvis, 63, "\dInvisible Water - %s", InvisWater[id] ? "\yON" : "\rOFF"); + formatex(msgfull, 63, "Full Invisible - %s^n", full_Invisible[id] ? "\yON" : "\rOFF"); + + menu_additem(menu, msginvis, "1"); + menu_additem(menu, msgwaterinvis, "2"); + menu_additem(menu, msgfull, "3"); + + menu_display(id, menu, 0); + + return PLUGIN_HANDLED; +} +public invisibleMenuHandler(id, menu, item) { + if(item == MENU_EXIT) { + ClimbMenu(id, 1); + return PLUGIN_HANDLED; + } + + switch(item) { + case 0: { + Invis_User(id); + invisibleMenu(id); + } + case 1: { + Invis_Water(id); + invisibleMenu(id); + } + case 2: { + Invis_Full(id); + invisibleMenu(id); + } + } + return PLUGIN_HANDLED; +} + +public kz_top_menu(id) { + new menu = menu_create("\wKZ Tops Menu\w", "kz_top_menuHandler"); + + menu_additem(menu, "KreedZ Top Menu", "1"); + menu_additem(menu, "LongJump Top Menu", "2"); + + menu_display(id, menu, 0); + return PLUGIN_HANDLED; +} + +public kz_top_menuHandler (id, menu, item) { + if(item == MENU_EXIT) { + ClimbMenu(id); + return PLUGIN_HANDLED; + } + + switch(item) { + case 0: { + top15menu(id); + } + case 1: { + client_cmd(id, "say /ljtop"); + } + } + return PLUGIN_HANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Top 15 Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public top15menu(id) { + new szTimerPro[14], szTimerNub[14]; + StringTimer(kz_my_protime[id], szTimerPro, sizeof(szTimerPro) - 1); + StringTimer(kz_my_nubtime[id], szTimerNub, sizeof(szTimerNub) - 1); + + new title[512]; + formatex(title, 500, "\dMap: \y%s\d^n^n\dMy Pro time: \w%s^n\dMy Nub time: \w%s", gMapName, szTimerPro, szTimerNub); + + new menu = menu_create(title, "top15handler"); + + menu_additem(menu, "\rPRO\d/\yNUB \wMap Top", "1", 0); + menu_additem(menu, "\wPlayers Top15^n","2"); + + menu_display(id, menu, 0); +} + +public top15handler(id, menu, item) { + if(item == MENU_EXIT) { + menu_destroy(menu); + return PLUGIN_HANDLED; + } + switch(item) { + case 0: { + stats_show(id); + } + case 1: { + kz_showhtml_motd(id, PLAYERS_RANKING); + } + } + + return PLUGIN_HANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Timer Funct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public fwdUse(ent, id) { + if(!ent || id > 32) + return HAM_IGNORED; + + if(!is_user_alive(id) || get_user_noclip(id) || ishooked[id]) + return HAM_IGNORED; + + if(!g_bHealsOnMap) + set_pev(id, pev_health, 100.0); + + new szTarget[32]; + pev(ent, pev_target, szTarget, 31); + + if(TrieKeyExists(g_tStarts, szTarget)) { + if(get_gametime() - antihookcheat[id] < 3.0) { + kz_hud_message(id, "Wait 3 seconds after using the hook."); + return PLUGIN_HANDLED; + } + + if(!mapIsSlide && !g_bHealsOnMap && GodModeOn[id]) { + client_print_color(id, print_chat, "^x01%s^x03 Start impossible because enabled GodMode!", prefix); + return PLUGIN_HANDLED; + } + + if(reset_checkpoints(id) && !timer_started[id]) { + start_climb(id); + + new clip, ammo, wpn_num, wpn[32]; + wpn_num = get_user_weapon(id, clip, ammo); + if(wpn_num) + get_weaponname(wpn_num, wpn, 31); + else + format(wpn, 31, "weapon_knife"); + strip_user_weapons(id); + give_item(id, wpn); + + if(equali(wpn, "weapon_knife") || equali(wpn, "weapon_usp")) { + give_usp_and_knife(id); + engclient_cmd(id, wpn); + } + + pev(id, pev_origin, SavedStart[id]); + AutoStart[id] = true; + + if(!Default_SF[0]) { + SQL_StartFinish(true, SavedStart[id]); + client_print_color(id, print_chat, "%s^x01 Established the starting position on the map.", prefix); + } + remove_hook(id); + } + } + + if(TrieKeyExists(g_tStops, szTarget)) { + if(timer_started[id]) { + if(get_user_noclip(id)) + return PLUGIN_HANDLED; + + if(!Default_SF[1]) { + pev(id, pev_origin, DefaultFinishPos); + SQL_StartFinish(false, DefaultFinishPos); + client_print_color(id, print_chat, "%s^x01 Established the position of the finish on the map.", prefix); + } + + finish_climb(id); + give_hook_finish(id); + canusenoclip[id] = true; + canusehook[id] = true; + } + else + kz_hud_message(id, "The timer is not running."); + } + return HAM_IGNORED; +} + +public start_climb(id) { + set_pev(id, pev_gravity, 1.0); + set_pev(id, pev_movetype, MOVETYPE_WALK); + reset_checkpoints(id); + IsPaused[id] = false; + timer_started[id] = true; + timer_time[id] = get_gametime(); +} + +public finish_climb(id) { + if(!is_user_alive(id) || is_user_bot(id)) + return; + + new Float: time, wpn; + time = get_gametime() - timer_time[id]; + + if(time < 0.0) { + client_print_color(id, print_chat, "%s ^3 CRITICAL ERROR: The timer has a negative time", prefix); + return; + } + Update_timer[id] = time; + show_finish_message(id, time, true, false); + timer_started[id] = false; + + wpn = get_user_weapon(id); + + new cData[5], createinto[1001]; + cData[0] = id; + cData[3] = checknumbers[id]; + cData[4] = gochecknumbers[id]; + new bool:user_weapon = false; + new weapon = get_user_weapon(id); + get_weaponname(weapon, weapon_name, charsmax(weapon_name)); + + for(new i = 0; i < 8; i++) + if(equali(other_weapons_name[i], weapon_name)) + user_weapon = true; + + if(gochecknumbers[id] == 0) + cData[1] = PRO_TOP; + else + cData[1] = NUB_TOP; + + if(user_weapon && get_pcvar_num(sv_airaccelerate) == 10) { + formatex(createinto, sizeof createinto - 1, "SELECT time FROM `%s` WHERE map_id=%d AND authid='%s' AND weapon='%s'", gochecknumbers[id] == 0 ? "kz_weapon_pro" : "kz_weapon_nub", kz_mapID, kz_authid[id], g_weaponsnames[wpn]); + SQL_ThreadQuery(g_SqlTuple, "SQL_StatsAdd", createinto, cData, 6); + } + else { + formatex(createinto, sizeof createinto - 1, "SELECT time FROM `%s` WHERE map_id=%d AND authid='%s'", gochecknumbers[id] == 0 ? "kz_pro15" : "kz_nub15", kz_mapID, kz_authid[id]); + SQL_ThreadQuery(g_SqlTuple, "SQL_StatsAdd", createinto, cData, 6); + } +} + +public show_finish_message(id, Float:kreedztime, bool:szfinish, bool:record) { + new name[32], szTime[14]; + new wpn = get_user_weapon(id); + new speed = str_to_num(g_weaponsnames[wpn]); + get_user_name(id, name, 31); + StringTimer(kreedztime, szTime, sizeof(szTime) - 1); + if(szfinish) + client_print_color(0, print_chat, "^x01%s^x03 %s^x01 finished the map in^x03 %s ^x01(CPs: ^x03%d^x01 | TPs: ^x03%d^x01 | Weapon: ^x03%s^x01)", prefix, name, szTime, checknumbers[id], gochecknumbers[id], Weapon_Converter(speed)); + else { + if(record) + client_print_color(id, print_chat, "^x01%s^x03 You have improved your time by^x04 %s^x03 in the ^x04%s", prefix, szTime, gochecknumbers[id] == 0 ? "Professional Top" : "General Top"); + else + client_print_color(id, print_chat, "^x01%s^x03 You missed your best time by^x04 %s^x03 in the ^x04%s", prefix, szTime, gochecknumbers[id] == 0 ? "Professional Top" : "General Top"); + } +} + +public jumphelp(id) { + kz_showhtml_motd(id, HELP); + return PLUGIN_CONTINUE; +} + +public stats_show(id) { + kz_showhtml_motd(id, STATS_TOP); + return PLUGIN_HANDLED; +} + +stock kz_showhtml_motd(id, type) { + new buffer[1001], namebuffer[64]; + + switch(type) { + case STATS_TOP: { + formatex(namebuffer, 63, "Stats of %s", gMapName); + formatex(buffer, 1000, "

LOADING...

", pgL_sql_files, gMapName, kz_authid[id]); + } + case PLAYERS_RANKING: { + formatex(namebuffer, 63, "KZ Top15"); + formatex(buffer, 1000, "

LOADING...

", pgL_sql_files); + } + case HELP: { + formatex(namebuffer, 63, "Server Info / Help"); + formatex(buffer, 1000, "

LOADING...

", pgL_sql_files); + } + } + + show_motd(id, buffer, namebuffer); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SPEC INFO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public tskShowSpec() { + static szHud[1102]; + static szName[34]; + static bool:send; + + for(new alive = 1; alive <= 32; alive++) { + new bool:sendTo[33]; + send = false; + + if(!is_user_alive(alive)) + continue; + + sendTo[alive] = true; + + get_user_name(alive, szName, 32); + format(szHud, 45, "Spectating %s:^n", szName); + + for(new dead = 1; dead <= 32; dead++) { + if(is_user_connected(dead)) { + if(is_user_alive(dead)) + continue; + + if(pev(dead, pev_iuser2) == alive) { + if(full_Invisible[alive] && !is_user_bot(alive)) { + if(cs_get_user_team(dead) == CS_TEAM_SPECTATOR) { + if(!(get_user_flags(dead) & ADMIN_IMMUNITY) || !(get_user_flags(dead) & ACCESS_3)) { + set_hudmessage(255, 0, 0, -1.0, 0.3, 1, 0.2, 0.1, 0.1, 0.1, -1); + show_hudmessage(dead, "It has enabled the user FULL INVISIBLE"); + } + } + } + + if(!SpecAdmImm[dead]) { + get_user_name(dead, szName, 32); + add(szName, 33, "^n", 0); + add(szHud, 1101, szName, 0); + send = true; + } + sendTo[dead] = true; + } + } + } + + if(send == true) { + for(new i = 1; i <= 32; i++) { + if(sendTo[i] == true && SpecList[i] == 1) { + set_hudmessage(SR, SG, SB, 0.85, 0.15, 0, 0.0, UPDATEINTERVAL, 0.2, 0.2, 4); + show_hudmessage(i, szHud); + } + } + } + } + + return PLUGIN_CONTINUE; +} + +public Screen(id, bool:fade) { + if(is_user_connected(id)) { + message_begin(MSG_ONE_UNRELIABLE, 98, _, id); + write_short(1<<0); + write_short(1<<0); + if(fade) + write_short(1<<2); + else + write_short(1<<1); + write_byte(0); + write_byte(0); + write_byte(0); + if(fade) + write_byte(255); + else + write_byte(0); + message_end(); + + if(fade) + Screen_fade[id] = true; + else + Screen_fade[id] = false; + } +} + +public cmdSpeclist(id) { + if(!SpecList[id]) { + SpecList[id] = true; + client_print_color(id, print_chat, "^x01%s^x03 Speclist has been enabled!", prefix); + } + else { + SpecList[id] = false; + client_print_color(id, print_chat, "^x01%s^x03 Speclist has been disabled!", prefix); + } + return PLUGIN_CONTINUE; +} + +public cmdSpeclistAdm(id) { + if(!(get_user_flags(id) & KZ_LEVEL_1)) { + client_print_color(id, print_chat, "^x01%s^x03 No access", prefix); + return PLUGIN_HANDLED; + } + + if(!SpecAdmImm[id]) { + SpecAdmImm[id] = true; + client_print_color(id, print_chat, "^x01%s^x03 You not be displayed in the Speclist!", prefix); + } + else { + SpecAdmImm[id] = false; + client_print_color(id, print_chat, "^x01%s^x03 You displays in a Speclist!", prefix); + } + return PLUGIN_CONTINUE; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Reset HUD (armor,hp,radar) ~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public onResetHUD(id) { + new iHideFlags = GetHudHideFlags(); + if(iHideFlags) { + message_begin(MSG_ONE, g_msgHideWeapon, _, id); + write_byte(iHideFlags); + message_end(); + } +} + +public msgHideWeapon() { + new iHideFlags = GetHudHideFlags(); + if(iHideFlags) + set_msg_arg_int(1, ARG_BYTE, get_msg_arg_int(1) | iHideFlags); +} + +GetHudHideFlags() { + new iFlags; + iFlags |= HUD_HIDE_FLASH; + iFlags |= HUD_HIDE_RHA; + iFlags |= HUD_HIDE_TIMER; + iFlags |= HUD_HIDE_MONEY; + return iFlags; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FLASHLIGHT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public Event_DeathMsg() { + flashlight_reset(read_data(2)); +} + +flashlight_reset(id) { + if(1 <= id <= maxplayers) { + g_iFlashBattery[id] = 100; + g_bFlashLight[id] = false; + g_flFlashLightTime[id] = 0.0; + } +} + +public Impulse_100(id) { + if(g_bEnabled) { + if(is_user_alive(id)) { + if(g_bFlashLight[id]) + FlashlightTurnOff(id); + else + FlashlightTurnOn(id); + } + return PLUGIN_HANDLED_MAIN; + } + return PLUGIN_CONTINUE; +} + +Make_FlashLight(id) { + static iOrigin[3], iAim[3], iDist; + get_user_origin(id, iOrigin, 1); + get_user_origin(id, iAim, 3); + + iDist = get_distance(iOrigin, iAim); + + if(iDist > g_iDistanceMax) + return; + + static iDecay, iAttn; + + iDecay = iDist * 255 / g_iDistanceMax; + iAttn = 256 + iDecay * g_iAttenuation; + + message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, id); + write_byte(TE_DLIGHT); + write_coord(iAim[0]); + write_coord(iAim[1]); + write_coord(iAim[2]); + write_byte(g_iRadius); + write_byte((g_iColor[id][Red]<<8) / iAttn); + write_byte((g_iColor[id][Green]<<8) / iAttn); + write_byte((g_iColor[id][Blue]<<8) / iAttn); + write_byte(1); + write_byte(iDecay); + message_end(); +} + +FlashlightTurnOff(id) { + g_bFlashLight[id] = false; + FlashlightHudDraw(id, 0); + g_flFlashLightTime[id] = g_flCharge + get_gametime(); +} + +FlashlightTurnOn(id) { + g_bFlashLight[id] = true; + FlashlightHudDraw(id, 1); + g_iColor[id] = g_iTeamColor[2-get_user_team(id)]; + g_flFlashLightTime[id] = g_flDrain + get_gametime(); +} + +FlashlightHudDraw(id, iFlag) { + message_begin(MSG_ONE_UNRELIABLE, g_msgidFlashlight, _, id); + write_byte(iFlag); + write_byte(g_iFlashBattery[id]); + message_end(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ScoreBoard ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public MessageScoreAttrib(iMsgID, iDest, iReceiver) { + new iPlayer = get_msg_arg_int(1); + if(is_user_alive(iPlayer) && (get_user_flags(iPlayer) & KZ_LEVEL_1)) + set_msg_arg_int(2, ARG_BYTE, SCOREATTRIB_VIP); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FPS CHECK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public get_fps(id) { + if(id > 32) + return -1; + if(!id) + return g_iServerFps; + return g_iPlayerFps[id]; +} + +public cmdFps(id) { + static Players[32], PlayersNum, Name[32]; + static HudBuffer[1024], TempBuffer[64]; + + set_hudmessage(0, 255, 100, 0.02, 0.20, 0, 1.0, 8.0, 1.0, 1.0, 3); + + format(TempBuffer, sizeof(TempBuffer) - 1, "Server FPS: %d^n^n", get_fps(0)); + add(HudBuffer, sizeof(HudBuffer) - 1, TempBuffer); + + get_players(Players, PlayersNum); + + for(new i = 0; i < PlayersNum; i++) { + get_user_info(Players[i], "name", Name, sizeof(Name) - 1); + + format(TempBuffer, sizeof(TempBuffer) - 1, "%s (%d fps)^n", Name, get_fps(Players[i])); + add(HudBuffer, sizeof(HudBuffer) - 1, TempBuffer); + } + show_hudmessage(id, HudBuffer); + format(TempBuffer, sizeof(TempBuffer) - 1, ""); + format(HudBuffer, sizeof(HudBuffer) - 1, ""); + + return PLUGIN_CONTINUE; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MEASURE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +public cmdMeasure(plr) { + pev(plr, pev_origin, g_vFirstLoc[plr]); + g_vFirstLoc[plr][2] -= is_user_ducking(plr) ? 18 : 36; + g_vSecondLoc[plr] = g_vFirstLoc[plr]; + + if(g_bShowBeams[plr] && !task_exists(plr + TASK_BEAM)) + set_task(0.1, "tskBeam", plr + TASK_BEAM, _, _, "ab"); + + menuDisplay(plr); +} + +public menuDisplay(plr) { + static menu[2048]; + new len = format(menu, 2047, "\wMeasure Menu^n^n"); + + if(g_bReturnFloat[plr]) { + len += format(menu[len], 2047 - len, "\d[\r1\d]\w \wSet Loc #1 \d< %.03f | %.03f | %.03f >^n", g_vFirstLoc[plr][0], g_vFirstLoc[plr][1], g_vFirstLoc[plr][2]); + len += format(menu[len], 2047 - len, "\d[\r2\d]\w \wSet Loc #2 \d< %.03f | %.03f | %.03f >^n^n", g_vSecondLoc[plr][0], g_vSecondLoc[plr][1], g_vSecondLoc[plr][2]); + len += format(menu[len], 2047 - len, "\d[\r3\d]\w \wAutomatical setting of the other Loc: \d%s^n^n", g_bAutoSetting[plr] ? "on" : "off"); + len += format(menu[len], 2047 - len, "\d[\r4\d]\w \wDetailed results: \d%s^n", g_bDetailedResults[plr] ? "on" : "off"); + len += format(menu[len], 2047 - len, "\d[\r5\d]\w \wReturned values: \ddecimal^n^n"); + len += format(menu[len], 2047 - len, "\r \wResults:^n"); + + if(g_bDetailedResults[plr]) { + len += format(menu[len], 2047 - len, "\r \wX-Distance: \d%f^n", floatabs(g_vFirstLoc[plr][0] - g_vSecondLoc[plr][0])); + len += format(menu[len], 2047 - len, "\r \wY-Distance: \d%f^n", floatabs(g_vFirstLoc[plr][1] - g_vSecondLoc[plr][1])); + } + + len += format(menu[len], 2047 - len, "\r \wHeight difference: \d%f^n", floatabs(g_vFirstLoc[plr][2] - g_vSecondLoc[plr][2])); + len += format(menu[len], 2047 - len, "\r \wReal distance: \d%f^n^n", get_distance_f(g_vFirstLoc[plr], g_vSecondLoc[plr])); + } + else { + len += format(menu[len], 2047 - len, "\d[\r1\d]\w \wSet Loc #1 \d< %i | %i | %i >^n", floatround(g_vFirstLoc[plr][0], floatround_round), floatround(g_vFirstLoc[plr][1], floatround_round), floatround(g_vFirstLoc[plr][2], floatround_round)); + len += format(menu[len], 2047 - len, "\d[\r2\d]\w \wSet Loc #2 \d< %i | %i | %i >^n^n", floatround(g_vSecondLoc[plr][0], floatround_round), floatround(g_vSecondLoc[plr][1], floatround_round), floatround(g_vSecondLoc[plr][2], floatround_round)); + len += format(menu[len], 2047 - len, "\d[\r3\d]\w \wAutomatical setting of the other Loc: \d%s^n^n", g_bAutoSetting[plr] ? "on" : "off"); + len += format(menu[len], 2047 - len, "\d[\r4\d]\w \wDetailed results: \d%s^n", g_bDetailedResults[plr] ? "on" : "off"); + len += format(menu[len], 2047 - len, "\d[\r5\d]\w \wReturned values: \drounded^n^n"); + len += format(menu[len], 2047 - len, "\r \wResults:^n"); + if(g_bDetailedResults[plr]) { + len += format(menu[len], 2047 - len, "\r \wX-Distance: \d%i^n", floatround(floatabs(g_vFirstLoc[plr][0] - g_vSecondLoc[plr][0]), floatround_round)); + len += format(menu[len], 2047 - len, "\r \wY-Distance: \d%i^n", floatround(floatabs(g_vFirstLoc[plr][1] - g_vSecondLoc[plr][1]), floatround_round)); + } + len += format(menu[len], 2047 - len, "\r \wHeight difference: \d%i^n", floatround(floatabs(g_vFirstLoc[plr][2] - g_vSecondLoc[plr][2]), floatround_round)); + len += format(menu[len], 2047 - len, "\r \wReal distance: \d%i^n^n", floatround(get_distance_f(g_vFirstLoc[plr], g_vSecondLoc[plr]), floatround_round)); + } + + len += format(menu[len], 2047 - len, "\d[\r6\d]\w \wShow beams: \d%s^n^n", g_bShowBeams[plr] ? "on" : "off"); + len += format(menu[len], 2047 - len, "\d[\r0\d]\w \wExit"); + + show_menu(plr, (1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<9), menu, -1); +} + +public menuAction(plr, key) { + switch(key) { + case 0: { + fm_get_aim_origin(plr, g_vFirstLoc[plr]); + if(g_bAutoSetting[plr]) { + get_tr2(0, TR_vecPlaneNormal, g_vSecondLoc[plr]); + kz_vecotr_mul_scalar(g_vSecondLoc[plr], 9999.0, g_vSecondLoc[plr]); + kz_vector_add(g_vFirstLoc[plr], g_vSecondLoc[plr], g_vSecondLoc[plr]); + fm_trace_line(plr, g_vFirstLoc[plr], g_vSecondLoc[plr], g_vSecondLoc[plr]); + } + menuDisplay(plr); + } + case 1: { + fm_get_aim_origin(plr, g_vSecondLoc[plr]); + if(g_bAutoSetting[plr]) { + get_tr2(0, TR_vecPlaneNormal, g_vFirstLoc[plr]); + kz_vecotr_mul_scalar(g_vFirstLoc[plr], 9999.0, g_vFirstLoc[plr]); + kz_vector_add(g_vFirstLoc[plr], g_vSecondLoc[plr], g_vFirstLoc[plr]); + fm_trace_line(plr, g_vSecondLoc[plr], g_vFirstLoc[plr], g_vFirstLoc[plr]); + } + menuDisplay(plr); + } + case 2: { + g_bAutoSetting[plr] = !g_bAutoSetting[plr]; + menuDisplay(plr); + } + case 3: { + g_bDetailedResults[plr] = !g_bDetailedResults[plr]; + menuDisplay(plr); + } + case 4: { + g_bReturnFloat[plr] = !g_bReturnFloat[plr]; + menuDisplay(plr); + } + case 5: { + g_bShowBeams[plr] = !g_bShowBeams[plr]; + if(!g_bShowBeams[plr] && task_exists(plr + TASK_BEAM)) + remove_task(plr + TASK_BEAM); + else + set_task(0.1, "tskBeam", plr + TASK_BEAM, _, _, "ab"); + menuDisplay(plr); + } + case 9: { + remove_task(plr + TASK_BEAM); + show_menu(plr, 0, ""); + } + } +} + +public tskBeam(plr) { + plr -= TASK_BEAM; + draw_beam(plr, g_vFirstLoc[plr], g_vSecondLoc[plr], DIST_R, DIST_G, DIST_B); + + if(floatabs(g_vFirstLoc[plr][2] - g_vSecondLoc[plr][2]) >= 2) { + static Float:temp[3]; + temp[0] = g_vSecondLoc[plr][0]; + temp[1] = g_vSecondLoc[plr][1]; + temp[2] = g_vFirstLoc[plr][2]; + draw_beam(plr, g_vFirstLoc[plr], temp, DIST_R, DIST_G, DIST_B); + draw_beam(plr, temp, g_vSecondLoc[plr], DIST_R, DIST_G, DIST_B); + } +} + +public draw_beam(plr, Float:aorigin[3], Float:borigin[3], r, g, b) { + message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, { 0.0, 0.0, 0.0 }, plr); + write_byte(TE_BEAMPOINTS); + engfunc(EngFunc_WriteCoord, aorigin[0]); + engfunc(EngFunc_WriteCoord, aorigin[1]); + engfunc(EngFunc_WriteCoord, aorigin[2]); + engfunc(EngFunc_WriteCoord, borigin[0]); + engfunc(EngFunc_WriteCoord, borigin[1]); + engfunc(EngFunc_WriteCoord, borigin[2]); + write_short(g_flBeam); + write_byte(0); + write_byte(0); + write_byte(2); + write_byte(20); + write_byte(0); + write_byte(r); + write_byte(g); + write_byte(b); + write_byte(150); + write_byte(0); + message_end(); +} + +is_user_ducking(plr) { + if(!pev_valid(plr)) + return 0; + + new Float:abs_min[3], Float:abs_max[3]; + pev(plr, pev_absmin, abs_min); + pev(plr, pev_absmax, abs_max); + + abs_min[2] += 64.0; + if(abs_min[2] < abs_max[2]) + return 0; + return 1; +} + +fm_get_aim_origin(plr, Float:origin[3]) { + new Float:start[3], Float:view_ofs[3]; + pev(plr, pev_origin, start); + pev(plr, pev_view_ofs, view_ofs); + kz_vector_add(start, view_ofs, start); + new Float:dest[3]; + pev(plr, pev_v_angle, dest); + engfunc(EngFunc_MakeVectors, dest); + global_get(glb_v_forward, dest); + kz_vecotr_mul_scalar(dest, 9999.0, dest); + kz_vector_add(start, dest, dest); + engfunc(EngFunc_TraceLine, start, dest, 0, plr, 0); + get_tr2(0, TR_vecEndPos, origin); + return 1; +} + +fm_trace_line(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) { + engfunc(EngFunc_TraceLine, start, end, ignoreent == -1 ? 1 : 0, ignoreent, 0); + new ent = get_tr2(0, TR_pHit); + get_tr2(0, TR_vecEndPos, ret); + return pev_valid(ent) ? ent : 0; +} diff --git a/amxmodx/scripting/admin_sql.sma b/amxmodx/scripting/admin_sql.sma new file mode 100755 index 0000000..23ef34b --- /dev/null +++ b/amxmodx/scripting/admin_sql.sma @@ -0,0 +1,635 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Admin Base Plugin +// + +#include +#include +#include + +new AdminCount; + +new PLUGINNAME[] = "AMX Mod X" + +#define ADMIN_LOOKUP (1<<0) +#define ADMIN_NORMAL (1<<1) +#define ADMIN_STEAM (1<<2) +#define ADMIN_IPADDR (1<<3) +#define ADMIN_NAME (1<<4) + +new bool:g_CaseSensitiveName[MAX_PLAYERS + 1]; + +// pcvars +new amx_mode; +new amx_password_field; +new amx_default_access; + +public plugin_init() { + register_plugin("Admin Base (SQL)", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("admin.txt") + register_dictionary("common.txt") + amx_mode=register_cvar("amx_mode", "1", FCVAR_PROTECTED) + amx_password_field=register_cvar("amx_password_field", "_pw", FCVAR_PROTECTED) + amx_default_access=register_cvar("amx_default_access", "", FCVAR_PROTECTED) + + register_cvar("amx_vote_ratio", "0.02") + register_cvar("amx_vote_time", "10") + register_cvar("amx_vote_answers", "1") + register_cvar("amx_vote_delay", "60") + register_cvar("amx_last_voting", "0") + register_cvar("amx_show_activity", "2", FCVAR_PROTECTED) + register_cvar("amx_votekick_ratio", "0.40") + register_cvar("amx_voteban_ratio", "0.40") + register_cvar("amx_votemap_ratio", "0.40") + + set_cvar_float("amx_last_voting", 0.0) + + register_srvcmd("amx_sqladmins", "adminSql") + register_cvar("amx_sql_table", "admins", FCVAR_PROTECTED) + register_cvar("amx_sql_host", "127.0.0.1", FCVAR_PROTECTED) + register_cvar("amx_sql_user", "root", FCVAR_PROTECTED) + register_cvar("amx_sql_pass", "", FCVAR_PROTECTED) + register_cvar("amx_sql_db", "amx", FCVAR_PROTECTED) + register_cvar("amx_sql_type", "mysql", FCVAR_PROTECTED) + register_cvar("amx_sql_timeout", "60", FCVAR_PROTECTED) + + register_concmd("amx_reloadadmins", "cmdReload", ADMIN_CFG) + register_concmd("amx_addadmin", "addadminfn", ADMIN_RCON, " [password] [authtype] - add specified player as an admin to users.ini") + + remove_user_flags(0, read_flags("z")) // Remove 'user' flag from server rights + + new configsDir[64] + get_configsdir(configsDir, charsmax(configsDir)) + + server_cmd("exec %s/sql.cfg", configsDir) + + // Create a vector of 5 cells to store the info. + //AdminList=vector_create(5); + + + server_cmd("amx_sqladmins") +} +public client_connect(id) { + g_CaseSensitiveName[id] = false; +} +public addadminfn(id, level, cid) { + if (!cmd_access(id, level, cid, 3)) + return PLUGIN_HANDLED + + new idtype = ADMIN_STEAM | ADMIN_LOOKUP + + if (read_argc() >= 5) { + new t_arg[16] + read_argv(4, t_arg, charsmax(t_arg)) + + if (equali(t_arg, "steam") || equali(t_arg, "steamid") || equali(t_arg, "auth")) + idtype = ADMIN_STEAM + else if (equali(t_arg, "ip")) + idtype = ADMIN_IPADDR + else if (equali(t_arg, "name") || equali(t_arg, "nick")) { + idtype = ADMIN_NAME + if (equali(t_arg, "name")) + idtype |= ADMIN_LOOKUP + } + else { + console_print(id, "[%s] Unknown id type ^"%s^", use one of: steamid, ip, name", PLUGINNAME, t_arg) + return PLUGIN_HANDLED + } + } + + new arg[33] + read_argv(1, arg, charsmax(arg)) + new player = -1 + + if (idtype & ADMIN_STEAM) { + if (containi(arg, "STEAM_0:") == -1) { + idtype |= ADMIN_LOOKUP + player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF | CMDTARGET_NO_BOTS) + } + else { + new _steamid[44] + static _players[MAX_PLAYERS], _num, _pv + get_players(_players, _num) + for (new _i=0; _i<_num; _i++) { + _pv = _players[_i] + get_user_authid(_pv, _steamid, charsmax(_steamid)) + if (!_steamid[0]) + continue + if (equal(_steamid, arg)) { + player = _pv + break + } + } + if (player < 1) + idtype &= ~ADMIN_LOOKUP + } + } + else if (idtype & ADMIN_NAME) { + player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF | CMDTARGET_NO_BOTS) + if (player) + idtype |= ADMIN_LOOKUP + else + idtype &= ~ADMIN_LOOKUP + } + else if (idtype & ADMIN_IPADDR) { + new len = strlen(arg) + new dots, chars + + for (new i = 0; i < len; i++) { + if (arg[i] == '.') { + if (!chars || chars > 3) + break + + if (++dots > 3) + break + + chars = 0 + } + else + chars++ + + if (dots != 3 || !chars || chars > 3) { + idtype |= ADMIN_LOOKUP + player = find_player("dh", arg) + } + } + } + + if (idtype & ADMIN_LOOKUP && !player) { + console_print(id, "%L", id, "CL_NOT_FOUND") + return PLUGIN_HANDLED + } + + new flags[64] + read_argv(2, flags, charsmax(flags)) + + new password[64] + if (read_argc() >= 4) + read_argv(3, password, charsmax(password)) + + new auth[33] + new Comment[MAX_NAME_LENGTH]; // name of player to pass to comment field + if (idtype & ADMIN_LOOKUP) { + get_user_name(player, Comment, charsmax(Comment)) + if (idtype & ADMIN_STEAM) + get_user_authid(player, auth, charsmax(auth)) + else if (idtype & ADMIN_IPADDR) + get_user_ip(player, auth, charsmax(auth), 1) + else if (idtype & ADMIN_NAME) + get_user_name(player, auth, charsmax(auth)) + } else + copy(auth, charsmax(auth), arg) + + new type[16], len + + if (idtype & ADMIN_STEAM) + len += format(type[len], charsmax(type) - len, "c") + else if (idtype & ADMIN_IPADDR) + len += format(type[len], charsmax(type) - len, "d") + + if (strlen(password) > 0) + len += format(type[len], charsmax(type) - len, "a") + else + len += format(type[len], charsmax(type) - len, "e") + + AddAdmin(id, auth, flags, password, type, Comment) + cmdReload(id, ADMIN_CFG, 0) + + if (player > 0) { + new name[MAX_NAME_LENGTH] + get_user_info(player, "name", name, charsmax(name)) + accessUser(player, name) + } + + return PLUGIN_HANDLED +} + +AddAdmin(id, auth[], accessflags[], password[], flags[], comment[]="") { + new error[128], errno + + new Handle:info = SQL_MakeStdTuple() + new Handle:sql = SQL_Connect(info, errno, error, charsmax(error)) + + if (sql == Empty_Handle) { + server_print("[AMXX] %L", LANG_SERVER, "SQL_CANT_CON", error) + //backup to users.ini + // Make sure that the users.ini file exists. + new configsDir[64] + get_configsdir(configsDir, charsmax(configsDir)) + format(configsDir, charsmax(configsDir), "%s/users.ini", configsDir) + + if (!file_exists(configsDir)) { + console_print(id, "[%s] File ^"%s^" doesn't exist.", PLUGINNAME, configsDir) + return + } + + // Make sure steamid isn't already in file. + new line = 0, textline[256], len + const SIZE = 63 + new line_steamid[SIZE + 1], line_password[SIZE + 1], line_accessflags[SIZE + 1], line_flags[SIZE + 1], parsedParams + + // + while ((line = read_file(configsDir, line, textline, charsmax(textline), len))) { + if (len == 0 || equal(textline, ";", 1)) + continue // comment line + + parsedParams = parse(textline, line_steamid, SIZE, line_password, SIZE, line_accessflags, SIZE, line_flags, SIZE) + + if (parsedParams != 4) + continue // Send warning/error? + + if (containi(line_flags, flags) != -1 && equal(line_steamid, auth)) { + console_print(id, "[%s] %s already exists!", PLUGINNAME, auth) + return + } + } + + // If we came here, steamid doesn't exist in users.ini. Add it. + new linetoadd[512] + + if (comment[0]==0) + formatex(linetoadd, charsmax(linetoadd), "^r^n^"%s^" ^"%s^" ^"%s^" ^"%s^"", auth, password, accessflags, flags) + else + formatex(linetoadd, charsmax(linetoadd), "^r^n^"%s^" ^"%s^" ^"%s^" ^"%s^" ; %s", auth, password, accessflags, flags, comment) + console_print(id, "Adding:^n%s", linetoadd) + + if (!write_file(configsDir, linetoadd)) + console_print(id, "[%s] Failed writing to %s!", PLUGINNAME, configsDir) + } + + new table[32] + + get_cvar_string("amx_sql_table", table, charsmax(table)) + + new Handle:query = SQL_PrepareQuery(sql, "SELECT * FROM `%s` WHERE (`auth` = '%s')", table, auth) + + if (!SQL_Execute(query)) { + SQL_QueryError(query, error, charsmax(error)) + server_print("[AMXX] %L", LANG_SERVER, "SQL_CANT_LOAD_ADMINS", error) + console_print(id, "[AMXX] %L", LANG_SERVER, "SQL_CANT_LOAD_ADMINS", error) + } + else if (SQL_NumResults(query)) + console_print(id, "[%s] %s already exists!", PLUGINNAME, auth) + else { + console_print(id, "Adding to database:^n^"%s^" ^"%s^" ^"%s^" ^"%s^"", auth, password, accessflags, flags) + SQL_QueryAndIgnore(sql, "REPLACE INTO `%s` (`auth`, `password`, `access`, `flags`) VALUES ('%s', '%s', '%s', '%s')", table, auth, password, accessflags, flags) + } + + SQL_FreeHandle(query) + SQL_FreeHandle(sql) + SQL_FreeHandle(info) +} + +loadSettings(szFilename[]) { + new File=fopen(szFilename,"r"); + + if (File) { + new Text[512]; + new Flags[32]; + new Access[32] + new AuthData[44]; + new Password[32]; + + while (!feof(File)) { + fgets(File, Text, charsmax(Text)); + + trim(Text); + + // comment + if (Text[0]==';') + continue; + + Flags[0]=0; + Access[0]=0; + AuthData[0]=0; + Password[0]=0; + + // not enough parameters + if (parse(Text,AuthData,charsmax(AuthData),Password,charsmax(Password),Access,charsmax(Access),Flags,charsmax(Flags)) < 2) + continue; + + admins_push(AuthData,Password,read_flags(Access),read_flags(Flags)); + + AdminCount++; + } + + fclose(File); + } + + if (AdminCount == 1) + server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMIN"); + else + server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", AdminCount); + + return 1; +} + +public adminSql() { + new table[32], error[128], type[12], errno + + new Handle:info = SQL_MakeStdTuple() + new Handle:sql = SQL_Connect(info, errno, error, charsmax(error)) + + get_cvar_string("amx_sql_table", table, charsmax(table)) + + SQL_GetAffinity(type, charsmax(type)) + + if (sql == Empty_Handle) { + server_print("[AMXX] %L", LANG_SERVER, "SQL_CANT_CON", error) + + //backup to users.ini + new configsDir[64] + + get_configsdir(configsDir, charsmax(configsDir)) + format(configsDir, charsmax(configsDir), "%s/users.ini", configsDir) + loadSettings(configsDir) // Load admins accounts + + return PLUGIN_HANDLED + } + + new Handle:query + + if (equali(type, "sqlite")) { + if (!sqlite_TableExists(sql, table)) + SQL_QueryAndIgnore(sql, "CREATE TABLE %s ( auth TEXT NOT NULL DEFAULT '', password TEXT NOT NULL DEFAULT '', access TEXT NOT NULL DEFAULT '', flags TEXT NOT NULL DEFAULT '' )", table) + + query = SQL_PrepareQuery(sql, "SELECT auth, password, access, flags FROM %s", table) + } else { + SQL_QueryAndIgnore(sql, "CREATE TABLE IF NOT EXISTS `%s` ( `auth` VARCHAR( 32 ) NOT NULL, `password` VARCHAR( 32 ) NOT NULL, `access` VARCHAR( 32 ) NOT NULL, `flags` VARCHAR( 32 ) NOT NULL ) COMMENT = 'AMX Mod X Admins'", table) + query = SQL_PrepareQuery(sql,"SELECT `auth`,`password`,`access`,`flags` FROM `%s`", table) + } + + if (!SQL_Execute(query)) { + SQL_QueryError(query, error, charsmax(error)) + server_print("[AMXX] %L", LANG_SERVER, "SQL_CANT_LOAD_ADMINS", error) + } + else if (!SQL_NumResults(query)) + server_print("[AMXX] %L", LANG_SERVER, "NO_ADMINS") + else { + + AdminCount = 0 + + /** do this incase people change the query order and forget to modify below */ + new qcolAuth = SQL_FieldNameToNum(query, "auth") + new qcolPass = SQL_FieldNameToNum(query, "password") + new qcolAccess = SQL_FieldNameToNum(query, "access") + new qcolFlags = SQL_FieldNameToNum(query, "flags") + + new AuthData[44]; + new Password[44]; + new Access[32]; + new Flags[32]; + + while (SQL_MoreResults(query)) { + SQL_ReadResult(query, qcolAuth, AuthData, charsmax(AuthData)); + SQL_ReadResult(query, qcolPass, Password, charsmax(Password)); + SQL_ReadResult(query, qcolAccess, Access, charsmax(Access)); + SQL_ReadResult(query, qcolFlags, Flags, charsmax(Flags)); + + if(strlen(Flags) > 0) { + admins_push(AuthData,Password,read_flags(Access),read_flags(Flags)); + ++AdminCount; + } + SQL_NextRow(query) + } + + if (AdminCount == 1) + server_print("[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMIN") + else + server_print("[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMINS", AdminCount) + + SQL_FreeHandle(query) + SQL_FreeHandle(sql) + SQL_FreeHandle(info) + } + + return PLUGIN_HANDLED +} + +public cmdReload(id, level, cid) { + if (!cmd_access(id, level, cid, 1)) + return PLUGIN_HANDLED + + //strip original flags (patch submitted by mrhunt) + remove_user_flags(0, read_flags("z")) + + admins_flush(); + + AdminCount = 0 + adminSql() + + if (id != 0) { + if (AdminCount == 1) + console_print(id, "[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMIN") + else + console_print(id, "[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMINS", AdminCount) + } + + new players[MAX_PLAYERS], num, pv + new name[MAX_NAME_LENGTH] + get_players(players, num) + for (new i=0; i<%s><>^" became an admin (account ^"%s^") (access ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, AuthData, sflags, ip) + } + else { + + admins_lookup(index,AdminProp_Password,Password,charsmax(Password)); + + if (equal(password, Password)) { + result |= 12 + set_user_flags(id, Access) + + new sflags[32] + get_flags(Access, sflags, charsmax(sflags)) + + log_amx("Login: ^"%s<%d><%s><>^" became an admin (account ^"%s^") (access ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, AuthData, sflags, ip) + } + else { + result |= 1 + + if (Flags & FLAG_KICK) { + result |= 2 + log_amx("Login: ^"%s<%d><%s><>^" kicked due to invalid password (account ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, AuthData, ip) + } + } + } + } + else if (get_pcvar_float(amx_mode) == 2.0) + result |= 2 + else { + new defaccess[32] + + get_pcvar_string(amx_default_access, defaccess, charsmax(defaccess)) + + if (!strlen(defaccess)) + copy(defaccess, charsmax(defaccess), "z") + + new idefaccess = read_flags(defaccess) + + if (idefaccess) + result |= 8 + set_user_flags(id, idefaccess) + } + + return result +} + +accessUser(id, name[] = "") { + remove_user_flags(id) + + new userip[32], userauthid[32], password[32], passfield[32], username[MAX_NAME_LENGTH] + + get_user_ip(id, userip, charsmax(userip), 1) + get_user_authid(id, userauthid, charsmax(userauthid)) + + if (name[0]) + copy(username, charsmax(username), name) + else + get_user_name(id, username, charsmax(username)) + + get_pcvar_string(amx_password_field, passfield, charsmax(passfield)) + get_user_info(id, passfield, password, charsmax(password)) + + new result = getAccess(id, username, userauthid, userip, password) + + if (result & 1) + engclient_print(id, engprint_console, "* %L", id, "INV_PAS") + + if (result & 2) { + server_cmd("kick #%d ^"%L^"", get_user_userid(id), id, "NO_ENTRY") + return PLUGIN_HANDLED + } + + if (result & 4) { + engclient_print(id, engprint_console, "* %L", id, "PAS_ACC") + } + + if (result & 8) { + engclient_print(id, engprint_console, "* %L", id, "PRIV_SET") + } + + return PLUGIN_CONTINUE +} + +public client_infochanged(id) { + if (!is_user_connected(id) || !get_pcvar_num(amx_mode)) + return PLUGIN_CONTINUE + + new newname[MAX_NAME_LENGTH], oldname[MAX_NAME_LENGTH] + + get_user_name(id, oldname, charsmax(oldname)) + get_user_info(id, "name", newname, charsmax(newname)) + + if (g_CaseSensitiveName[id]) { + if (!equal(newname, oldname)) + accessUser(id, newname) + } + else { + if (!equali(newname, oldname)) + accessUser(id, newname) + } + return PLUGIN_CONTINUE +} + +public client_authorized(id) + return get_pcvar_num(amx_mode) ? accessUser(id) : PLUGIN_CONTINUE + +public client_putinserver(id) { + if (!is_dedicated_server() && id == 1) + return get_pcvar_num(amx_mode) ? accessUser(id) : PLUGIN_CONTINUE + + return PLUGIN_CONTINUE +} diff --git a/amxmodx/scripting/adminchat.sma b/amxmodx/scripting/adminchat.sma new file mode 100755 index 0000000..d5a7e62 --- /dev/null +++ b/amxmodx/scripting/adminchat.sma @@ -0,0 +1,424 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Admin Chat Plugin +// + +#include +#include + +new g_msgChannel + +#define MAX_CLR 10 + +new g_Colors[MAX_CLR][] = {"COL_WHITE", "COL_RED", "COL_GREEN", "COL_BLUE", "COL_YELLOW", "COL_MAGENTA", "COL_CYAN", "COL_ORANGE", "COL_OCEAN", "COL_MAROON"} +new g_Values[MAX_CLR][] = {{255, 255, 255}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}, {227, 96, 8}, {45, 89, 116}, {103, 44, 38}} +new Float:g_Pos[4][] = {{0.0, 0.0}, {0.05, 0.55}, {-1.0, 0.2}, {-1.0, 0.7}} + +new amx_show_activity; +new amx_flood_time; +new g_AdminChatFlag = ADMIN_CHAT; + +new Float:g_Flooding[MAX_PLAYERS + 1] = {0.0, ...} +new g_Flood[MAX_PLAYERS + 1] = {0, ...} + +public plugin_init() +{ + new admin_chat_id + + register_plugin("Admin Chat", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("adminchat.txt") + register_dictionary("common.txt") + register_dictionary("antiflood.txt") + register_clcmd("say", "cmdSayChat", ADMIN_CHAT, "@[@|@|@][w|r|g|b|y|m|c] - displays hud message", 1) // forces FlagManager as it is a say command + register_clcmd("say_team", "cmdSayAdmin", 0, "@ - displays message to admins") + register_concmd("amx_say", "cmdSay", ADMIN_CHAT, " - sends message to all players") + admin_chat_id = register_concmd("amx_chat", "cmdChat", ADMIN_CHAT, " - sends message to admins") + register_concmd("amx_psay", "cmdPsay", ADMIN_CHAT, " - sends private message") + register_concmd("amx_tsay", "cmdTsay", ADMIN_CHAT, " - sends left side hud message to all players") + register_concmd("amx_csay", "cmdTsay", ADMIN_CHAT, " - sends center hud message to all players") + + amx_show_activity = get_cvar_pointer("amx_show_activity"); + + if (amx_show_activity == 0) + { + amx_show_activity = register_cvar("amx_show_activity", "2", FCVAR_PROTECTED); + } + + new str[1] + get_concmd(admin_chat_id, str, 0, g_AdminChatFlag, str, 0, -1) +} + +public plugin_cfg() +{ + // check if cvar amx_flood_time exists (created by antiflood plugin) + + amx_flood_time = get_cvar_pointer("amx_flood_time"); + + if( !amx_flood_time ) + { + // else create it + amx_flood_time = register_cvar("amx_flood_time", "0.75"); + } +} + +public cmdSayChat(id, level) +{ + if (!access(id, level)) + { + return PLUGIN_CONTINUE + } + + new said[6], i = 0 + read_argv(1, said, charsmax(said)) + + while (said[i] == '@') + { + i++ + } + + if (!i || i > 3) + { + return PLUGIN_CONTINUE + } + + new message[192], a = 0 + read_args(message, charsmax(message)) + remove_quotes(message) + + switch (said[i]) + { + case 'r': a = 1 + case 'g': a = 2 + case 'b': a = 3 + case 'y': a = 4 + case 'm': a = 5 + case 'c': a = 6 + case 'o': a = 7 + } + + new n, s = i + if (a) + { + n++ + s++ + } + while (said[s] && isspace(said[s])) + { + n++ + s++ + } + + + new name[MAX_NAME_LENGTH], authid[32], userid + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + userid = get_user_userid(id) + + log_amx("Chat: ^"%s<%d><%s><>^" tsay ^"%s^"", name, userid, authid, message[i + n]) + log_message("^"%s<%d><%s><>^" triggered ^"amx_tsay^" (text ^"%s^") (color ^"%L^")", name, userid, authid, message[i + n], "en", g_Colors[a]) + + if (++g_msgChannel > 6 || g_msgChannel < 3) + { + g_msgChannel = 3 + } + + new Float:verpos = g_Pos[i][1] + float(g_msgChannel) / 35.0 + + set_hudmessage(g_Values[a][0], g_Values[a][1], g_Values[a][2], g_Pos[i][0], verpos, 0, 6.0, 6.0, 0.5, 0.15, -1) + + switch (get_pcvar_num(amx_show_activity)) + { + case 3, 4: + { + new players[MAX_PLAYERS], plrsnum, pl + get_players(players, plrsnum, "ch") + for(new j; j nexTime) + { + if (g_Flood[id] >= 3) + { + client_print(id, print_notify, "** %L **", id, "STOP_FLOOD") + g_Flooding[id] = nexTime + maxChat + 3.0 + return PLUGIN_HANDLED + } + g_Flood[id]++ + } + else if (g_Flood[id]) + { + g_Flood[id]-- + } + + g_Flooding[id] = nexTime + maxChat + } + + new message[192], name[MAX_NAME_LENGTH], authid[32], userid + new players[MAX_PLAYERS], inum, pl + + read_args(message, charsmax(message)) + remove_quotes(message) + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + userid = get_user_userid(id) + + log_amx("Chat: ^"%s<%d><%s><>^" chat ^"%s^"", name, userid, authid, message[1]) + log_message("^"%s<%d><%s><>^" triggered ^"amx_chat^" (text ^"%s^")", name, userid, authid, message[1]) + + get_players(players, inum, "ch") + + for (new bool:is_sender_admin = is_user_admin(id) != 0, i = 0; i < inum; ++i) + { + pl = players[i] + + if (pl == id || get_user_flags(pl) & g_AdminChatFlag) + { + client_print(pl, print_chat, "(%l) %s : %s", is_sender_admin ? "ADMIN" : "PLAYER", name, message[1]) + } + } + + return PLUGIN_HANDLED +} + +public cmdChat(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new message[192] + + read_args(message, charsmax(message)) + remove_quotes(message) + + if (!message[0]) + return PLUGIN_HANDLED + + new name[MAX_NAME_LENGTH], players[MAX_PLAYERS], inum, authid[32], userid, pl + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + userid = get_user_userid(id) + get_players(players, inum, "ch") + + log_amx("Chat: ^"%s<%d><%s><>^" chat ^"%s^"", name, userid, authid, message) + log_message("^"%s<%d><%s><>^" triggered ^"amx_chat^" (text ^"%s^")", name, userid, authid, message) + + format(message, charsmax(message), "(ADMINS) %s : %s", name, message) + console_print(id, "%s", message) + + for (new i = 0; i < inum; ++i) + { + pl = players[i] + if (access(pl, g_AdminChatFlag)) + client_print(pl, print_chat, "%s", message) + } + + return PLUGIN_HANDLED +} + +public cmdSay(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new message[192], name[MAX_NAME_LENGTH], authid[32], userid + + read_args(message, charsmax(message)) + remove_quotes(message) + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + userid = get_user_userid(id) + client_print(0, print_chat, "%L", LANG_PLAYER, "PRINT_ALL", name, message) + console_print(id, "%L", LANG_PLAYER, "PRINT_ALL", name, message) + + log_amx("Chat: ^"%s<%d><%s><>^" say ^"%s^"", name, userid, authid, message) + log_message("^"%s<%d><%s><>^" triggered ^"amx_say^" (text ^"%s^")", name, userid, authid, message) + + return PLUGIN_HANDLED +} + +public cmdPsay(id, level, cid) +{ + if (!cmd_access(id, level, cid, 3)) + return PLUGIN_HANDLED + + new name[MAX_NAME_LENGTH] + read_argv(1, name, charsmax(name)) + new priv = cmd_target(id, name, 0) + + if (!priv) + return PLUGIN_HANDLED + + new length = strlen(name) + 1 + + new message[192], name2[MAX_NAME_LENGTH], authid[32], authid2[32], userid, userid2 + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name2, charsmax(name2)) + userid = get_user_userid(id) + read_args(message, charsmax(message)) + + if (message[0] == '"' && message[length] == '"') // HLSW fix + { + message[0] = ' ' + message[length] = ' ' + length += 2 + } + + remove_quotes(message[length]) + get_user_name(priv, name, charsmax(name)) + + if (id && id != priv) + client_print(id, print_chat, "(%s) %s : %s", name, name2, message[length]) + + client_print(priv, print_chat, "(%s) %s : %s", name, name2, message[length]) + console_print(id, "(%s) %s : %s", name, name2, message[length]) + get_user_authid(priv, authid2, charsmax(authid2)) + userid2 = get_user_userid(priv) + + log_amx("Chat: ^"%s<%d><%s><>^" psay ^"%s<%d><%s><>^" ^"%s^"", name2, userid, authid, name, userid2, authid2, message[length]) + log_message("^"%s<%d><%s><>^" triggered ^"amx_psay^" against ^"%s<%d><%s><>^" (text ^"%s^")", name2, userid, authid, name, userid2, authid2, message[length]) + + return PLUGIN_HANDLED +} + +public cmdTsay(id, level, cid) +{ + if (!cmd_access(id, level, cid, 3)) + return PLUGIN_HANDLED + + new cmd[16], color[16], color2[16], message[192], name[MAX_NAME_LENGTH], authid[32], userid = 0 + + read_argv(0, cmd, charsmax(cmd)) + new bool:tsay = (tolower(cmd[4]) == 't') + + read_args(message, charsmax(message)) + remove_quotes(message) + parse(message, color, charsmax(color)) + + new found = 0, a = 0 + new lang[3], langnum = get_langsnum() + + for (new i = 0; i < MAX_CLR; ++i) + { + for (new j = 0; j < langnum; j++) + { + get_lang(j, lang) + formatex(color2, charsmax(color2), "%L", lang, g_Colors[i]) + + if (equali(color, color2)) + { + a = i + found = 1 + break + } + } + if (found == 1) + break + } + + new length = found ? (strlen(color) + 1) : 0 + + if (++g_msgChannel > 6 || g_msgChannel < 3) + g_msgChannel = 3 + + new Float:verpos = (tsay ? 0.55 : 0.1) + float(g_msgChannel) / 35.0 + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + userid = get_user_userid(id) + set_hudmessage(g_Values[a][0], g_Values[a][1], g_Values[a][2], tsay ? 0.05 : -1.0, verpos, 0, 6.0, 6.0, 0.5, 0.15, -1) + + switch (get_pcvar_num(amx_show_activity)) + { + case 3, 4: + { + new players[MAX_PLAYERS], plrsnum, pl + get_players(players, plrsnum, "ch") + for(new i; i<%s><>^" %s ^"%s^"", name, userid, authid, cmd[4], message[length]) + log_message("^"%s<%d><%s><>^" triggered ^"%s^" (text ^"%s^") (color ^"%s^")", name, userid, authid, cmd, message[length], color2) + + return PLUGIN_HANDLED +} diff --git a/amxmodx/scripting/admincmd.sma b/amxmodx/scripting/admincmd.sma new file mode 100755 index 0000000..6df9d2a --- /dev/null +++ b/amxmodx/scripting/admincmd.sma @@ -0,0 +1,1377 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Admin Commands Plugin +// + +#include +#include + +// This is not a dynamic array because it would be bad for 24/7 map servers. +#define OLD_CONNECTION_QUEUE 10 + +new g_pauseCon +new Float:g_pausAble +new bool:g_Paused +new bool:g_PauseAllowed = false + +new pausable; +new rcon_password; +new timelimit; +new p_amx_tempban_maxtime; + +// Old connection queue +new g_Names[OLD_CONNECTION_QUEUE][MAX_NAME_LENGTH]; +new g_SteamIDs[OLD_CONNECTION_QUEUE][32]; +new g_IPs[OLD_CONNECTION_QUEUE][32]; +new g_Access[OLD_CONNECTION_QUEUE]; +new g_Tracker; +new g_Size; + +public Trie:g_tempBans +new Trie:g_tXvarsFlags; + +stock InsertInfo(id) +{ + + // Scan to see if this entry is the last entry in the list + // If it is, then update the name and access + // If it is not, then insert it again. + + if (g_Size > 0) + { + new ip[32] + new auth[32]; + + get_user_authid(id, auth, charsmax(auth)); + get_user_ip(id, ip, charsmax(ip), 1/*no port*/); + + new last = 0; + + if (g_Size < sizeof(g_SteamIDs)) + { + last = g_Size - 1; + } + else + { + last = g_Tracker - 1; + + if (last < 0) + { + last = g_Size - 1; + } + } + + if (equal(auth, g_SteamIDs[last]) && + equal(ip, g_IPs[last])) // need to check ip too, or all the nosteams will while it doesn't work with their illegitimate server + { + get_user_name(id, g_Names[last], charsmax(g_Names[])); + g_Access[last] = get_user_flags(id); + + return; + } + } + + // Need to insert the entry + + new target = 0; // the slot to save the info at + + // Queue is not yet full + if (g_Size < sizeof(g_SteamIDs)) + { + target = g_Size; + + ++g_Size; + + } + else + { + target = g_Tracker; + + ++g_Tracker; + // If we reached the end of the array, then move to the front + if (g_Tracker == sizeof(g_SteamIDs)) + { + g_Tracker = 0; + } + } + + get_user_authid(id, g_SteamIDs[target], charsmax(g_SteamIDs[])); + get_user_name(id, g_Names[target], charsmax(g_Names[])); + get_user_ip(id, g_IPs[target], charsmax(g_IPs[]), 1/*no port*/); + + g_Access[target] = get_user_flags(id); + +} +stock GetInfo(i, name[], namesize, auth[], authsize, ip[], ipsize, &access) +{ + if (i >= g_Size) + { + abort(AMX_ERR_NATIVE, "GetInfo: Out of bounds (%d:%d)", i, g_Size); + } + + new target = (g_Tracker + i) % sizeof(g_SteamIDs); + + copy(name, namesize, g_Names[target]); + copy(auth, authsize, g_SteamIDs[target]); + copy(ip, ipsize, g_IPs[target]); + access = g_Access[target]; + +} +public client_disconnected(id) +{ + if (!is_user_bot(id)) + { + InsertInfo(id); + } +} + +public plugin_init() +{ + register_plugin("Admin Commands", AMXX_VERSION_STR, "AMXX Dev Team") + + register_dictionary("admincmd.txt") + register_dictionary("common.txt") + register_dictionary("adminhelp.txt") + + register_concmd("amx_kick", "cmdKick", ADMIN_KICK, " [reason]") + register_concmd("amx_ban", "cmdBan", ADMIN_BAN|ADMIN_BAN_TEMP, " [reason]") + register_concmd("amx_banip", "cmdBanIP", ADMIN_BAN|ADMIN_BAN_TEMP, " [reason]") + register_concmd("amx_addban", "cmdAddBan", ADMIN_BAN, "<^"authid^" or ip> [reason]") + register_concmd("amx_unban", "cmdUnban", ADMIN_BAN|ADMIN_BAN_TEMP, "<^"authid^" or ip>") + register_concmd("amx_slay", "cmdSlay", ADMIN_SLAY, "") + register_concmd("amx_slap", "cmdSlap", ADMIN_SLAY, " [power]") + register_concmd("amx_leave", "cmdLeave", ADMIN_KICK, " [tag] [tag] [tag]") + register_concmd("amx_pause", "cmdPause", ADMIN_CVAR, "- pause or unpause the game") + register_concmd("amx_who", "cmdWho", ADMIN_ADMIN, "- displays who is on server") + register_concmd("amx_cvar", "cmdCvar", ADMIN_CVAR, " [value]") + register_concmd("amx_xvar_float", "cmdXvar", ADMIN_CVAR, " [value]") + register_concmd("amx_xvar_int", "cmdXvar", ADMIN_CVAR, " [value]") + register_concmd("amx_plugins", "cmdPlugins", ADMIN_ADMIN) + register_concmd("amx_modules", "cmdModules", ADMIN_ADMIN) + register_concmd("amx_map", "cmdMap", ADMIN_MAP, "") + register_concmd("amx_extendmap", "cmdExtendMap", ADMIN_MAP, " - extend map") + register_concmd("amx_cfg", "cmdCfg", ADMIN_CFG, "") + register_concmd("amx_nick", "cmdNick", ADMIN_SLAY, " ") + register_concmd("amx_last", "cmdLast", ADMIN_BAN, "- list the last few disconnected clients info"); + register_clcmd("amx_rcon", "cmdRcon", ADMIN_RCON, "") + register_clcmd("amx_showrcon", "cmdShowRcon", ADMIN_RCON, "") + register_clcmd("pauseAck", "cmdLBack") + + rcon_password=get_cvar_pointer("rcon_password"); + pausable=get_cvar_pointer("pausable"); + timelimit=get_cvar_pointer( "mp_timelimit" ); + p_amx_tempban_maxtime = register_cvar("amx_tempban_maxtime", "4320", FCVAR_PROTECTED); + + g_tempBans = TrieCreate(); + + new flags = get_pcvar_flags(rcon_password); + + if (!(flags & FCVAR_PROTECTED)) + { + set_pcvar_flags(rcon_password, flags | FCVAR_PROTECTED); + } +} + +public cmdKick(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32] + read_argv(1, arg, charsmax(arg)) + new player = cmd_target(id, arg, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_ALLOW_SELF) + + if (!player) + return PLUGIN_HANDLED + + new authid[32], authid2[32], name2[MAX_NAME_LENGTH], name[MAX_NAME_LENGTH], userid2, reason[32] + + get_user_authid(id, authid, charsmax(authid)) + get_user_authid(player, authid2, charsmax(authid2)) + get_user_name(player, name2, charsmax(name2)) + get_user_name(id, name, charsmax(name)) + userid2 = get_user_userid(player) + read_argv(2, reason, charsmax(reason)) + remove_quotes(reason) + + log_amx("Kick: ^"%s<%d><%s><>^" kick ^"%s<%d><%s><>^" (reason ^"%s^")", name, get_user_userid(id), authid, name2, userid2, authid2, reason) + + show_activity_key("ADMIN_KICK_1", "ADMIN_KICK_2", name, name2); + + if (is_user_bot(player)) + server_cmd("kick #%d", userid2) + else + { + if (reason[0]) + server_cmd("kick #%d ^"%s^"", userid2, reason) + else + server_cmd("kick #%d", userid2) + } + + console_print(id, "[AMXX] Client ^"%s^" kicked", name2) + + return PLUGIN_HANDLED +} + +/** + * ';' and '^n' are command delimiters. If a command arg contains these 2 + * it is not safe to be passed to server_cmd() as it may be trying to execute + * a command. + */ +isCommandArgSafe(const arg[]) +{ + return contain(arg, ";") == -1 && contain(arg, "^n") == -1; +} + +public cmdUnban(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32], authid[32], name[MAX_NAME_LENGTH] + + read_argv(1, arg, charsmax(arg)) + + get_user_authid(id, authid, charsmax(authid)) + + if( !(get_user_flags(id) & ( ADMIN_BAN | ADMIN_RCON )) ) + { + new storedAdminAuth[32] + if( !TrieGetString(g_tempBans, arg, storedAdminAuth, charsmax(storedAdminAuth)) || !equal(storedAdminAuth, authid) ) + { + console_print(id, "%L", id, "ADMIN_MUST_TEMPUNBAN"); + return PLUGIN_HANDLED; + } + } + + if (contain(arg, ".") != -1) + { + server_cmd("removeip ^"%s^";writeip", arg) + console_print(id, "[AMXX] %L", id, "IP_REMOVED", arg) + } else { + if(!isCommandArgSafe(arg)) + { + console_print(id, "%l", "CL_NOT_FOUND"); + return PLUGIN_HANDLED; + } + + server_cmd("removeid %s;writeid", arg) + console_print(id, "[AMXX] %L", id, "AUTHID_REMOVED", arg) + } + + get_user_name(id, name, charsmax(name)) + + show_activity_key("ADMIN_UNBAN_1", "ADMIN_UNBAN_2", name, arg); + + log_amx("Cmd: ^"%s<%d><%s><>^" unban ^"%s^"", name, get_user_userid(id), authid, arg) + + return PLUGIN_HANDLED +} + +/* amx_addban is a special command now. + * If a user with rcon uses it, it bans the user. No questions asked. + * If a user without rcon but with ADMIN_BAN uses it, it will scan the old + * connection queue, and if it finds the info for a player in it, it will + * check their old access. If they have immunity, it will not ban. + * If they do not have immunity, it will ban. If the user is not found, + * it will refuse to ban the target. + */ + +public cmdAddBan(id, level, cid) +{ + if (!cmd_access(id, level, cid, 3, true)) // check for ADMIN_BAN access + { + if (get_user_flags(id) & level) // Getting here means they didn't input enough args + { + return PLUGIN_HANDLED; + } + if (!cmd_access(id, ADMIN_RCON, cid, 3)) // If somehow they have ADMIN_RCON without ADMIN_BAN, continue + { + return PLUGIN_HANDLED; + } + } + + new arg[32], authid[32], name[MAX_NAME_LENGTH], minutes[32], reason[32] + + read_argv(1, arg, charsmax(arg)) + read_argv(2, minutes, charsmax(minutes)) + read_argv(3, reason, charsmax(reason)) + + trim(arg); + + if (!(get_user_flags(id) & ADMIN_RCON)) + { + new bool:canban = false; + new bool:isip = false; + // Limited access to this command + if (equali(arg, "STEAM_ID_PENDING") || + equali(arg, "STEAM_ID_LAN") || + equali(arg, "HLTV") || + equali(arg, "4294967295") || + equali(arg, "VALVE_ID_LAN") || + equali(arg, "VALVE_ID_PENDING")) + { + // Hopefully we never get here, so ML shouldn't be needed + console_print(id, "Cannot ban %s", arg); + return PLUGIN_HANDLED; + } + + if (contain(arg, ".") != -1) + { + isip = true; + } + + // Scan the disconnection queue + if (isip) + { + new IP[32]; + new Name[MAX_NAME_LENGTH]; + new dummy[1]; + new Access; + for (new i = 0; i < g_Size; i++) + { + GetInfo(i, Name, charsmax(Name), dummy, 0, IP, charsmax(IP), Access); + + if (equal(IP, arg)) + { + if (Access & ADMIN_IMMUNITY) + { + console_print(id, "[AMXX] %s : %L", IP, id, "CLIENT_IMM", Name); + + return PLUGIN_HANDLED; + } + // User did not have immunity + canban = true; + } + } + } + else + { + new Auth[32]; + new Name[MAX_NAME_LENGTH]; + new dummy[1]; + new Access; + for (new i = 0; i < g_Size; i++) + { + GetInfo(i, Name, charsmax(Name), Auth, charsmax(Auth), dummy, 0, Access); + + if (equal(Auth, arg)) + { + if (Access & ADMIN_IMMUNITY) + { + console_print(id, "[AMXX] %s : %L", Auth, id, "CLIENT_IMM", Name); + + return PLUGIN_HANDLED; + } + // User did not have immunity + canban = true; + } + } + } + + if (!canban) + { + console_print(id, "[AMXX] You may only ban recently disconnected clients. Use ^"amx_last^" to view."); + + return PLUGIN_HANDLED; + } + + } + + // User has access to ban their target + if (contain(arg, ".") != -1) + { + server_cmd("addip ^"%s^" ^"%s^";wait;writeip", minutes, arg) + console_print(id, "[AMXX] Ip ^"%s^" added to ban list", arg) + } else { + if(!isCommandArgSafe(arg)) + { + console_print(id, "%l", "CL_NOT_FOUND"); + return PLUGIN_HANDLED; + } + + server_cmd("banid ^"%s^" %s;wait;writeid", minutes, arg) + console_print(id, "[AMXX] Authid ^"%s^" added to ban list", arg) + } + + get_user_name(id, name, charsmax(name)) + + show_activity_key("ADMIN_ADDBAN_1", "ADMIN_ADDBAN_2", name, arg); + + get_user_authid(id, authid, charsmax(authid)) + TrieSetString(g_tempBans, arg, authid) + log_amx("Cmd: ^"%s<%d><%s><>^" ban ^"%s^" (minutes ^"%s^") (reason ^"%s^")", name, get_user_userid(id), authid, arg, minutes, reason) + + return PLUGIN_HANDLED +} + +public cmdBan(id, level, cid) +{ + if (!cmd_access(id, level, cid, 3)) + return PLUGIN_HANDLED + + new target[32], minutes[8], reason[64] + + read_argv(1, target, charsmax(target)) + read_argv(2, minutes, charsmax(minutes)) + read_argv(3, reason, charsmax(reason)) + + new player = cmd_target(id, target, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_NO_BOTS | CMDTARGET_ALLOW_SELF) + + if (!player) + return PLUGIN_HANDLED + + new nNum = str_to_num(minutes) + new const tempBanMaxTime = get_pcvar_num(p_amx_tempban_maxtime); + if( nNum < 0 ) // since negative values result in permanent bans + { + nNum = 0; + minutes = "0"; + } + if( !(get_user_flags(id) & ( ADMIN_BAN | ADMIN_RCON )) && (nNum <= 0 || nNum > tempBanMaxTime) ) + { + console_print(id, "%L", id, "ADMIN_MUST_TEMPBAN", tempBanMaxTime); + return PLUGIN_HANDLED + } + + new authid[32], name2[MAX_NAME_LENGTH], authid2[32], name[MAX_NAME_LENGTH] + new userid2 = get_user_userid(player) + + get_user_authid(player, authid2, charsmax(authid2)) + get_user_authid(id, authid, charsmax(authid)) + get_user_name(player, name2, charsmax(name2)) + get_user_name(id, name, charsmax(name)) + + log_amx("Ban: ^"%s<%d><%s><>^" ban and kick ^"%s<%d><%s><>^" (minutes ^"%s^") (reason ^"%s^")", name, get_user_userid(id), authid, name2, userid2, authid2, minutes, reason) + + TrieSetString(g_tempBans, authid2, authid); // store all bans in case a permanent ban would override a temporary one. + + new temp[64], banned[16] + if (nNum) + formatex(temp, charsmax(temp), "%L", player, "FOR_MIN", minutes) + else + formatex(temp, charsmax(temp), "%L", player, "PERM") + + formatex(banned, charsmax(banned), "%L", player, "BANNED") + + if (reason[0]) + server_cmd("kick #%d ^"%s (%s %s)^";wait;banid %s %s;wait;writeid", userid2, reason, banned, temp, minutes, authid2) + else + server_cmd("kick #%d ^"%s %s^";wait;banid %s %s;wait;writeid", userid2, banned, temp, minutes, authid2) + + + // Display the message to all clients + + new msg[256]; + new len; + new players[MAX_PLAYERS], pnum, plr + get_players(players, pnum, "ch") + for (new i; i 0) + { + formatex(msg[len], charsmax(msg) - len, " (%L: %s)", plr, "REASON", reason); + } + show_activity_id(plr, id, name, msg); + } + + console_print(id, "[AMXX] %L", id, "CLIENT_BANNED", name2) + + return PLUGIN_HANDLED +} + +public cmdBanIP(id, level, cid) +{ + if (!cmd_access(id, level, cid, 3)) + return PLUGIN_HANDLED + + new target[32], minutes[8], reason[64] + + read_argv(1, target, charsmax(target)) + read_argv(2, minutes, charsmax(minutes)) + read_argv(3, reason, charsmax(reason)) + + new player = cmd_target(id, target, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_NO_BOTS | CMDTARGET_ALLOW_SELF) + + if (!player) + return PLUGIN_HANDLED + + new nNum = str_to_num(minutes) + new const tempBanMaxTime = get_pcvar_num(p_amx_tempban_maxtime); + if( nNum < 0 ) // since negative values result in permanent bans + { + nNum = 0; + minutes = "0"; + } + if( !(get_user_flags(id) & ( ADMIN_BAN | ADMIN_RCON )) && (nNum <= 0 || nNum > tempBanMaxTime) ) + { + console_print(id, "%L", id, "ADMIN_MUST_TEMPBAN", tempBanMaxTime); + return PLUGIN_HANDLED + } + + new authid[32], name2[MAX_NAME_LENGTH], authid2[32], name[MAX_NAME_LENGTH] + new userid2 = get_user_userid(player) + + get_user_authid(player, authid2, charsmax(authid2)) + get_user_authid(id, authid, charsmax(authid)) + get_user_name(player, name2, charsmax(name2)) + get_user_name(id, name, charsmax(name)) + + log_amx("Ban: ^"%s<%d><%s><>^" ban and kick ^"%s<%d><%s><>^" (minutes ^"%s^") (reason ^"%s^")", name, get_user_userid(id), authid, name2, userid2, authid2, minutes, reason) + + TrieSetString(g_tempBans, authid2, authid); + + new temp[64], banned[16] + if (nNum) + formatex(temp, charsmax(temp), "%L", player, "FOR_MIN", minutes) + else + formatex(temp, charsmax(temp), "%L", player, "PERM") + format(banned, 15, "%L", player, "BANNED") + + new address[32] + get_user_ip(player, address, charsmax(address), 1) + + if (reason[0]) + server_cmd("kick #%d ^"%s (%s %s)^";wait;addip ^"%s^" ^"%s^";wait;writeip", userid2, reason, banned, temp, minutes, address) + else + server_cmd("kick #%d ^"%s %s^";wait;addip ^"%s^" ^"%s^";wait;writeip", userid2, banned, temp, minutes, address) + + // Display the message to all clients + + new msg[256]; + new len; + new players[MAX_PLAYERS], pnum, plr + get_players(players, pnum, "ch") + for (new i; i 0) + { + formatex(msg[len], charsmax(msg) - len, " (%L: %s)", plr, "REASON", reason); + } + show_activity_id(plr, id, name, msg); + } + + console_print(id, "[AMXX] %L", id, "CLIENT_BANNED", name2) + + return PLUGIN_HANDLED +} + +public cmdSlay(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32] + + read_argv(1, arg, charsmax(arg)) + + new player = cmd_target(id, arg, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_ALLOW_SELF | CMDTARGET_ONLY_ALIVE) + + if (!player) + return PLUGIN_HANDLED + + user_kill(player) + + new authid[32], name2[MAX_NAME_LENGTH], authid2[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + get_user_authid(player, authid2, charsmax(authid2)) + get_user_name(player, name2, charsmax(name2)) + + log_amx("Cmd: ^"%s<%d><%s><>^" slay ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, name2, get_user_userid(player), authid2) + + show_activity_key("ADMIN_SLAY_1", "ADMIN_SLAY_2", name, name2); + + console_print(id, "[AMXX] %L", id, "CLIENT_SLAYED", name2) + + return PLUGIN_HANDLED +} + +public cmdSlap(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32] + + read_argv(1, arg, charsmax(arg)) + new player = cmd_target(id, arg, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_ALLOW_SELF | CMDTARGET_ONLY_ALIVE) + + if (!player) + return PLUGIN_HANDLED + + new spower[32], authid[32], name2[MAX_NAME_LENGTH], authid2[32], name[MAX_NAME_LENGTH] + + read_argv(2, spower, charsmax(spower)) + + new damage = clamp( str_to_num(spower), 0) + + user_slap(player, damage) + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + get_user_authid(player, authid2, charsmax(authid2)) + get_user_name(player, name2, charsmax(name2)) + + log_amx("Cmd: ^"%s<%d><%s><>^" slap with %d damage ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, damage, name2, get_user_userid(player), authid2) + + show_activity_key("ADMIN_SLAP_1", "ADMIN_SLAP_2", name, name2, damage); + + console_print(id, "[AMXX] %L", id, "CLIENT_SLAPED", name2, damage) + + return PLUGIN_HANDLED +} + +public chMap(map[]) +{ + engine_changelevel(map); +} + +public cmdMap(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32] + new arglen = read_argv(1, arg, charsmax(arg)) + + if (!is_map_valid(arg) || contain(arg, "..") != -1) + { + console_print(id, "[AMXX] %L", id, "MAP_NOT_FOUND") + return PLUGIN_HANDLED + } + + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + + show_activity_key("ADMIN_MAP_1", "ADMIN_MAP_2", name, arg); + + log_amx("Cmd: ^"%s<%d><%s><>^" changelevel ^"%s^"", name, get_user_userid(id), authid, arg) + + new _modName[10] + get_modname(_modName, charsmax(_modName)) + + if (!equal(_modName, "zp")) + { + message_begin(MSG_ALL, SVC_INTERMISSION) + message_end() + } + + set_task(2.0, "chMap", 0, arg, arglen + 1) + + return PLUGIN_HANDLED +} + +public cmdExtendMap(id, level, cid) +{ + if(!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32] + read_argv(1, arg, charsmax(arg)) + new mns = str_to_num(arg) + + if(mns <= 0) + return PLUGIN_HANDLED + + new mapname[32] + get_mapname(mapname, charsmax(mapname)) + set_pcvar_num( timelimit , get_pcvar_num( timelimit ) + mns) + + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + + show_activity_key("ADMIN_EXTEND_1", "ADMIN_EXTEND_2", name, mns) + + log_amx("ExtendMap: ^"%s<%d><%s><>^" extended map ^"%s^" for %d minutes.", name, get_user_userid(id), authid, mapname, mns) + console_print(id, "%L", id, "MAP_EXTENDED", mapname, mns) + + return PLUGIN_HANDLED +} + +stock bool:onlyRcon(const name[]) +{ + new ptr=get_cvar_pointer(name); + if (ptr && get_pcvar_flags(ptr) & FCVAR_PROTECTED) + { + return true; + } + return false; +} + +public cmdCvar(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new arg[32], arg2[64] + + read_argv(1, arg, charsmax(arg)) + read_argv(2, arg2, charsmax(arg2)) + + new pointer; + + if (equal(arg, "add") && (get_user_flags(id) & ADMIN_RCON)) + { + if ((pointer=get_cvar_pointer(arg2))!=0) + { + new flags=get_pcvar_flags(pointer); + + if (!(flags & FCVAR_PROTECTED)) + { + set_pcvar_flags(pointer,flags | FCVAR_PROTECTED); + } + } + return PLUGIN_HANDLED + } + + trim(arg); + + if ((pointer=get_cvar_pointer(arg))==0) + { + console_print(id, "[AMXX] %L", id, "UNKNOWN_CVAR", arg) + return PLUGIN_HANDLED + } + + if (onlyRcon(arg) && !(get_user_flags(id) & ADMIN_RCON)) + { + // Exception for the new onlyRcon rules: + // sv_password is allowed to be modified by ADMIN_PASSWORD + if (!(equali(arg,"sv_password") && (get_user_flags(id) & ADMIN_PASSWORD))) + { + console_print(id, "[AMXX] %L", id, "CVAR_NO_ACC") + return PLUGIN_HANDLED + } + } + + if (read_argc() < 3) + { + get_pcvar_string(pointer, arg2, charsmax(arg2)) + console_print(id, "[AMXX] %L", id, "CVAR_IS", arg, arg2) + return PLUGIN_HANDLED + } + + if (equali(arg, "servercfgfile") || equali(arg, "lservercfgfile") || equali(arg, "mapchangecfgfile")) + { + new pos = contain(arg2, ";") + if (pos != -1) + { + arg2[pos] = '^0' + } + else if ((pos = contain(arg2, "^n")) != -1) + { + arg2[pos] = '^0' + } + } + + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + + log_amx("Cmd: ^"%s<%d><%s><>^" set cvar (name ^"%s^") (value ^"%s^")", name, get_user_userid(id), authid, arg, arg2) + set_pcvar_string(pointer, arg2) + + + // Display the message to all clients + + new cvar_val[64]; + new players[MAX_PLAYERS], pnum, plr + get_players(players, pnum, "ch") + for (new i; i 2 ) + { + read_argv(2, arg2, charsmax(arg2)); + trim(arg2); + + if( equali(arg1, "add") ) + { + if( get_user_flags(id) & ADMIN_RCON && xvar_exists(arg2) ) + { + if( !g_tXvarsFlags ) + { + g_tXvarsFlags = TrieCreate(); + } + TrieSetCell(g_tXvarsFlags, arg2, 1); + } + return PLUGIN_HANDLED; + } + } + + new bFloat = equali(cmd, "amx_xvar_float"); + + new xvar = get_xvar_id( arg1 ); + + if( xvar == -1 ) + { + console_print(id, "[AMXX] %L", id, "UNKNOWN_XVAR", arg1) + return PLUGIN_HANDLED + } + + new any:value; + + if( !arg2[0] ) // get value + { + value = get_xvar_num(xvar); + if( bFloat ) + { + float_to_str(value, arg2, charsmax(arg2)); + } + else + { + num_to_str(value, arg2, charsmax(arg2)); + } + console_print(id, "[AMXX] %L", id, "XVAR_IS", arg1, arg2); + return PLUGIN_HANDLED; + } + + // set value + if( g_tXvarsFlags && TrieKeyExists(g_tXvarsFlags, arg1) && ~get_user_flags(id) & ADMIN_RCON ) + { + console_print(id, "[AMXX] %L", id, "XVAR_NO_ACC"); + return PLUGIN_HANDLED; + } + + new endPos; + if( bFloat ) + { + value = strtof(arg2, endPos); + if( !endPos ) + { + return PLUGIN_HANDLED; + } + } + else + { + value = strtol(arg2, endPos); + if( !endPos ) + { + return PLUGIN_HANDLED; + } + } + + set_xvar_num(xvar, value); + + // convert back value to string so admin can know value has been set correctly + if( bFloat ) + { + float_to_str(value, arg2, charsmax(arg2)); + } + else + { + num_to_str(value, arg2, charsmax(arg2)); + } + + new authid[32], name[MAX_NAME_LENGTH]; + + get_user_authid(id, authid, charsmax(authid)); + get_user_name(id, name, charsmax(name)); + + log_amx("Cmd: ^"%s<%d><%s><>^" set xvar (name ^"%s^") (value ^"%s^")", name, get_user_userid(id), authid, arg1, arg2); + + // Display the message to all clients + new players[MAX_PLAYERS], pnum, plr; + get_players(players, pnum, "ch"); + for (new i; i 1) + { + read_argv(1,Temp,charsmax(Temp)); + StartPLID=str_to_num(Temp)-1; // zero-based + } + + EndPLID=min(StartPLID + 10, num); + + new running = 0 + + console_print(id, "----- %L -----", id, "LOADED_PLUGINS") + console_print(id, "%-18.17s %-11.10s %-17.16s %-16.15s %-9.8s", lName, lVersion, lAuthor, lFile, lStatus) + + new i=StartPLID; + while (i <%s><>^" execute cfg (file ^"%s^")", name, get_user_userid(id), authid, arg) + + console_print(id, "[AMXX] Executing file ^"%s^"", arg) + server_cmd("exec ^"%s^"", arg) + + show_activity_key("ADMIN_CONF_1", "ADMIN_CONF_2", name, arg); + + return PLUGIN_HANDLED +} + +public cmdLBack() +{ + if (!g_PauseAllowed) + return PLUGIN_CONTINUE + + new paused[25] + + format(paused, 24, "%L", g_pauseCon, g_Paused ? "UNPAUSED" : "PAUSED") + set_pcvar_float(pausable, g_pausAble) + console_print(g_pauseCon, "[AMXX] Server %s", paused) + g_PauseAllowed = false + + if (g_Paused) + g_Paused = false + else + g_Paused = true + + return PLUGIN_HANDLED +} + +public cmdPause(id, level, cid) +{ + if (!cmd_access(id, level, cid, 1)) + return PLUGIN_HANDLED + + new authid[32], name[MAX_NAME_LENGTH], slayer = id + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + if (pausable!=0) + { + g_pausAble = get_pcvar_float(pausable) + } + + if (!slayer) + slayer = find_player("h") + + if (!slayer) + { + console_print(id, "[AMXX] %L", id, "UNABLE_PAUSE") + return PLUGIN_HANDLED + } + + set_pcvar_float(pausable, 1.0) + g_PauseAllowed = true + client_cmd(slayer, "pause;pauseAck") + + log_amx("Cmd: ^"%s<%d><%s><>^" %s server", name, get_user_userid(id), authid, g_Paused ? "unpause" : "pause") + + console_print(id, "[AMXX] %L", id, g_Paused ? "UNPAUSING" : "PAUSING") + + // Display the message to all clients + + new players[MAX_PLAYERS], pnum + get_players(players, pnum, "ch") + for (new i; i<%s><>^" server console (cmdline ^"%s^")", name, get_user_userid(id), authid, arg) + + console_print(id, "[AMXX] %L", id, "COM_SENT_SERVER", arg) + server_cmd("%s", arg) + + return PLUGIN_HANDLED +} + +public cmdWho(id, level, cid) +{ + if (!cmd_access(id, level, cid, 1)) + return PLUGIN_HANDLED + + new players[MAX_PLAYERS], inum, cl_on_server[64], authid[32], name[MAX_NAME_LENGTH], flags, sflags[32], plr + new lImm[16], lRes[16], lAccess[16], lYes[16], lNo[16] + + formatex(lImm, charsmax(lImm), "%L", id, "IMMU") + formatex(lRes, charsmax(lRes), "%L", id, "RESERV") + formatex(lAccess, charsmax(lAccess), "%L", id, "ACCESS") + formatex(lYes, charsmax(lYes), "%L", id, "YES") + formatex(lNo, charsmax(lNo), "%L", id, "NO") + + get_players(players, inum) + format(cl_on_server, charsmax(cl_on_server), "%L", id, "CLIENTS_ON_SERVER") + console_print(id, "^n%s:^n # %-16.15s %-20s %-8s %-4.3s %-4.3s %s", cl_on_server, "nick", "authid", "userid", lImm, lRes, lAccess) + + for (new a = 0; a < inum; ++a) + { + plr = players[a] + get_user_authid(plr, authid, charsmax(authid)) + get_user_name(plr, name, charsmax(name)) + flags = get_user_flags(plr) + get_flags(flags, sflags, charsmax(sflags)) + console_print(id, "%2d %-16.15s %-20s %-8d %-6.5s %-6.5s %s", plr, name, authid, + get_user_userid(plr), (flags&ADMIN_IMMUNITY) ? lYes : lNo, (flags&ADMIN_RESERVATION) ? lYes : lNo, sflags) + } + + console_print(id, "%L", id, "TOTAL_NUM", inum) + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + log_amx("Cmd: ^"%s<%d><%s><>^" ask for players list", name, get_user_userid(id), authid) + + return PLUGIN_HANDLED +} + +hasTag(name[], tags[4][32], tagsNum) +{ + for (new a = 0; a < tagsNum; ++a) + if (contain(name, tags[a]) != -1) + return a + return -1 +} + +public cmdLeave(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new argnum = read_argc() + new ltags[4][32] + new ltagsnum = 0 + + for (new a = 1; a < 5; ++a) + { + if (a < argnum) + read_argv(a, ltags[ltagsnum++], charsmax(ltags[])) + else + ltags[ltagsnum++][0] = 0 + } + + new nick[MAX_NAME_LENGTH], ires, pnum = MaxClients, count = 0, lReason[128] + + for (new b = 1; b <= pnum; ++b) + { + if (!is_user_connected(b) && !is_user_connecting(b)) continue + + get_user_name(b, nick, charsmax(nick)) + ires = hasTag(nick, ltags, ltagsnum) + + if (ires != -1) + { + console_print(id, "[AMXX] %L", id, "SKIP_MATCH", nick, ltags[ires]) + continue + } + + if (get_user_flags(b) & ADMIN_IMMUNITY) + { + console_print(id, "[AMXX] %L", id, "SKIP_IMM", nick) + continue + } + + console_print(id, "[AMXX] %L", id, "KICK_PL", nick) + + if (is_user_bot(b)) + server_cmd("kick #%d", get_user_userid(b)) + else + { + formatex(lReason, charsmax(lReason), "%L", b, "YOU_DROPPED") + server_cmd("kick #%d ^"%s^"", get_user_userid(b), lReason) + } + count++ + } + + console_print(id, "[AMXX] %L", id, "KICKED_CLIENTS", count) + + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + log_amx("Kick: ^"%s<%d><%s><>^" leave some group (tag1 ^"%s^") (tag2 ^"%s^") (tag3 ^"%s^") (tag4 ^"%s^")", name, get_user_userid(id), authid, ltags[0], ltags[1], ltags[2], ltags[3]) + + show_activity_key("ADMIN_LEAVE_1", "ADMIN_LEAVE_2", name, ltags[0], ltags[1], ltags[2], ltags[3]); + + return PLUGIN_HANDLED +} + +public cmdNick(id, level, cid) +{ + if (!cmd_access(id, level, cid, 3)) + return PLUGIN_HANDLED + + new arg1[32], arg2[32], authid[32], name[32], authid2[32], name2[32] + + read_argv(1, arg1, charsmax(arg1)) + read_argv(2, arg2, charsmax(arg2)) + + new player = cmd_target(id, arg1, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_ALLOW_SELF) + + if (!player) + return PLUGIN_HANDLED + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + get_user_authid(player, authid2, charsmax(authid2)) + get_user_name(player, name2, charsmax(name2)) + + set_user_info(player, "name", arg2) + + log_amx("Cmd: ^"%s<%d><%s><>^" change nick to ^"%s^" ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, arg2, name2, get_user_userid(player), authid2) + + show_activity_key("ADMIN_NICK_1", "ADMIN_NICK_2", name, name2, arg2); + + console_print(id, "[AMXX] %L", id, "CHANGED_NICK", name2, arg2) + + return PLUGIN_HANDLED +} + +public cmdLast(id, level, cid) +{ + if (!cmd_access(id, level, cid, 1)) + { + return PLUGIN_HANDLED; + } + + new name[MAX_NAME_LENGTH]; + new authid[32]; + new ip[32]; + new flags[32]; + new access; + + + // This alignment is a bit weird (it should grow if the name is larger) + // but otherwise for the more common shorter name, it'll wrap in server console + // Steam client display is all skewed anyway because of the non fixed font. + console_print(id, "%19s %20s %15s %s", "name", "authid", "ip", "access"); + + for (new i = 0; i < g_Size; i++) + { + GetInfo(i, name, charsmax(name), authid, charsmax(authid), ip, charsmax(ip), access); + + get_flags(access, flags, charsmax(flags)); + + console_print(id, "%19s %20s %15s %s", name, authid, ip, flags); + } + + console_print(id, "%d old connections saved.", g_Size); + + return PLUGIN_HANDLED; +} + +public plugin_end() +{ + TrieDestroy(g_tempBans); + TrieDestroy(g_tXvarsFlags); +} diff --git a/amxmodx/scripting/adminhelp.sma b/amxmodx/scripting/adminhelp.sma new file mode 100755 index 0000000..77e78c3 --- /dev/null +++ b/amxmodx/scripting/adminhelp.sma @@ -0,0 +1,198 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Admin Help Plugin +// + +#include + +const MaxMapLength = 32; +const MaxDefaultEntries = 10; +const MaxCommandLength = 32; +const MaxCommandInfoLength = 128; +const DefaultMsgTime = 15; + +new const HelpCommand[] = "amx_help"; +new const SearchCommand[] = "amx_searchcmd"; + +new CvarDisplayClientMessage; +new CvarDisplayMessageTime; +new CvarHelpAmount; + +new CvarNextmap[MaxMapLength]; +new Float:CvarTimeLimit; + +new bool:DisplayClientMessage[MAX_PLAYERS + 1 char]; + +public plugin_init() +{ + register_plugin("Admin Help", AMXX_VERSION_STR, "AMXX Dev Team"); + register_dictionary("adminhelp.txt"); + + register_concmd(HelpCommand , "@ConsoleCommand_Help" , ADMIN_ALL, "HELP_CMD_INFO" , .info_ml = true); + register_concmd(SearchCommand, "@ConsoleCommand_Search", ADMIN_ALL, "SEARCH_CMD_INFO", .info_ml = true); + + bind_pcvar_num(create_cvar("amx_help_display_msg" , "1" , .has_min = true, .min_val = 0.0, .has_max = true, .max_val = 1.0), CvarDisplayClientMessage); + bind_pcvar_num(create_cvar("amx_help_display_msg_time", "15", .has_min = true, .min_val = 0.0), CvarDisplayMessageTime); + bind_pcvar_num(create_cvar("amx_help_amount_per_page" , "10", .has_min = true, .min_val = 0.0), CvarHelpAmount); +} + +public OnConfigsExecuted() +{ + new const pointer = get_cvar_pointer("amx_nextmap"); + + if (pointer) + { + bind_pcvar_string(pointer, CvarNextmap, charsmax(CvarNextmap)); + } + + bind_pcvar_float(get_cvar_pointer("mp_timelimit"), CvarTimeLimit); +} + +public client_putinserver(id) +{ + if (CvarDisplayClientMessage > 0 && !is_user_bot(id)) + { + DisplayClientMessage{id} = true; + + new Float:messageTime = float(CvarDisplayMessageTime <= 0 ? DefaultMsgTime : CvarDisplayMessageTime); + set_task(messageTime, "@Task_DisplayMessage", id); + } +} + +public client_disconnected(id) +{ + if (DisplayClientMessage{id}) + { + DisplayClientMessage{id} = false; + remove_task(id); + } +} + +@ConsoleCommand_Search(id, level, cid) +{ + new entry[MaxCommandLength]; + read_argv(1, entry, charsmax(entry)); + + return ProcessHelp(id, .start_argindex = 2, .do_search = true, .main_command = SearchCommand, .search = entry); +} + +@ConsoleCommand_Help(id, level, cid) +{ + return ProcessHelp(id, .start_argindex = 1, .do_search = false, .main_command = HelpCommand); +} + +ProcessHelp(id, start_argindex, bool:do_search, const main_command[], const search[] = "") +{ + new user_flags = get_user_flags(id); + + // HACK: ADMIN_ADMIN is never set as a user's actual flags, so those types of commands never show + if (user_flags > 0 && !(user_flags & ADMIN_USER)) + { + user_flags |= ADMIN_ADMIN; + } + + new clcmdsnum = get_concmdsnum(user_flags, id); + + if (CvarHelpAmount <= 0) + { + CvarHelpAmount = MaxDefaultEntries; + } + + new start = clamp(read_argv_int(start_argindex), .min = 1, .max = clcmdsnum) - 1; // Zero-based list; + new amount = !id ? read_argv_int(start_argindex + 1) : CvarHelpAmount; + new end = min(start + (amount > 0 ? amount : CvarHelpAmount), clcmdsnum); + + console_print(id, "^n----- %l -----", "HELP_COMS"); + + new info[MaxCommandInfoLength]; + new command[MaxCommandLength]; + new command_flags; + new bool:is_info_ml; + new entries_found; + new total_entries; + new index; + + if (do_search) + { + for (index = 0; index < clcmdsnum; ++index) + { + get_concmd(index, command, charsmax(command), command_flags, info, charsmax(info), user_flags, id, is_info_ml); + + if (containi(command, search) != -1 && ++entries_found > start && (total_entries = entries_found) <= end) + { + if (is_info_ml) + { + LookupLangKey(info, charsmax(info), info, id); + } + + console_print(id, "%3d: %s %s", entries_found, command, info); + } + } + + if (!entries_found || entries_found > total_entries) + { + console_print(id, "%l", "NO_MATCHING_RESULTS"); + return PLUGIN_HANDLED; + } + + index = entries_found; + clcmdsnum = total_entries; + end = min(end, clcmdsnum); + } + else + { + for (index = start; index < end; ++index) + { + get_concmd(index, command, charsmax(command), command_flags, info, charsmax(info), user_flags, id, is_info_ml); + + if (is_info_ml) + { + LookupLangKey(info, charsmax(info), info, id); + } + + console_print(id, "%3d: %s %s", index + 1, command, info); + } + } + + console_print(id, "----- %l -----", "HELP_ENTRIES", start + 1, end, clcmdsnum); + + formatex(command, charsmax(command), "%s%c%s", main_command, do_search ? " " : "", search); + + if (end < clcmdsnum) + { + console_print(id, "----- %l -----", "HELP_USE_MORE", command, end + 1); + } + else if (start || index != clcmdsnum) + { + console_print(id, "----- %l -----", "HELP_USE_BEGIN", command); + } + + return PLUGIN_HANDLED; +} + +@Task_DisplayMessage(id) +{ + client_print(id, print_chat, "%l", "TYPE_HELP", HelpCommand, SearchCommand); + + if (CvarTimeLimit > 0.0) + { + new timeleft = get_timeleft(); + + if (timeleft > 0) + { + client_print(id, print_chat, "%l", "TIME_INFO_1", timeleft / 60, timeleft % 60, CvarNextmap); + } + else if (CvarNextmap[0] != EOS) + { + client_print(id, print_chat, "%l", "TIME_INFO_2", CvarNextmap); + } + } +} diff --git a/amxmodx/scripting/adminslots.sma b/amxmodx/scripting/adminslots.sma new file mode 100755 index 0000000..e73a577 --- /dev/null +++ b/amxmodx/scripting/adminslots.sma @@ -0,0 +1,110 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Slots Reservation Plugin +// + +#include +#include + +new CvarReservation; +new CvarHideSlots; + +new CvarHandleMaxVisiblePlayers; + +public plugin_init() +{ + register_plugin("Slots Reservation", AMXX_VERSION_STR, "AMXX Dev Team"); + + register_dictionary("adminslots.txt"); + register_dictionary("common.txt"); + + hook_cvar_change(create_cvar("amx_reservation", "0", FCVAR_PROTECTED, fmt("%L", LANG_SERVER, "CVAR_RESERVATION"), .has_min = true, .min_val = 0.0, .has_max = true, .max_val = float(MaxClients - 1)), "@OnReservationChange"); + hook_cvar_change(create_cvar("amx_hideslots" , "0", FCVAR_NONE , fmt("%L", LANG_SERVER, "CVAR_HIDESLOTS") , .has_min = true, .min_val = 0.0, .has_max = true, .max_val = 1.0), "@OnHideSlotsChange"); + + CvarHandleMaxVisiblePlayers = get_cvar_pointer("sv_visiblemaxplayers"); +} + +@OnReservationChange(const handle, const oldValue[], const newValue[]) +{ + CvarReservation = strtol(newValue); + + setVisibleSlots(); +} + +@OnHideSlotsChange(const handle, const oldValue[], const newValue[]) +{ + CvarHideSlots = strtol(newValue); + + setVisibleSlots(); +} + +public client_authorized(id) +{ + setVisibleSlots(id); +} + +public client_remove(id) +{ + setVisibleSlots(); +} + +setVisibleSlots(const playerId = 0) +{ + if ((playerId == 0 && !CvarHideSlots) || !CvarReservation) + { + if (get_pcvar_num(CvarHandleMaxVisiblePlayers) > 0) + { + resetVisibleSlots(MaxClients); + } + + return; + } + + new const playersCount = get_playersnum_ex(GetPlayers_IncludeConnecting); + new const freeVisibleSlots = MaxClients - CvarReservation; + + if (playerId != 0) + { + if (playersCount > freeVisibleSlots && !access(playerId, ADMIN_RESERVATION)) + { + server_cmd("kick #%d ^"%L^"", get_user_userid(playerId), playerId, "DROPPED_RES"); + return; + } + + if (!CvarHideSlots) + { + return; + } + } + + new maxVisiblePlayers = playersCount + 1; + + if (playersCount == MaxClients) + { + maxVisiblePlayers = MaxClients; + } + else if (playersCount < freeVisibleSlots) + { + maxVisiblePlayers = freeVisibleSlots; + } + + resetVisibleSlots(maxVisiblePlayers); +} + +resetVisibleSlots(value) +{ + if (value == MaxClients) + { + value = -1; // Default sv_visiblemaxplayers value. + } + + set_pcvar_num(CvarHandleMaxVisiblePlayers, value); +} diff --git a/amxmodx/scripting/adminvote.sma b/amxmodx/scripting/adminvote.sma new file mode 100755 index 0000000..f1d2ebb --- /dev/null +++ b/amxmodx/scripting/adminvote.sma @@ -0,0 +1,549 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Admin Votes Plugin +// + +#include +#include + + +new g_Answer[128] +new g_optionName[4][64] +new g_voteCount[4] +new g_validMaps +new g_yesNoVote +new g_coloredMenus +new g_voteCaller +new g_Execute[256] +new g_execLen + +new bool:g_execResult +new Float:g_voteRatio + +public plugin_init() +{ + register_plugin("Admin Votes", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("adminvote.txt") + register_dictionary("common.txt") + register_dictionary("mapsmenu.txt") + register_menucmd(register_menuid("Change map to "), MENU_KEY_1|MENU_KEY_2, "voteCount") + register_menucmd(register_menuid("Choose map: "), MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4, "voteCount") + register_menucmd(register_menuid("Kick "), MENU_KEY_1|MENU_KEY_2, "voteCount") + register_menucmd(register_menuid("Ban "), MENU_KEY_1|MENU_KEY_2, "voteCount") + register_menucmd(register_menuid("Vote: "), MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4, "voteCount") + register_menucmd(register_menuid("The result: "), MENU_KEY_1|MENU_KEY_2, "actionResult") + register_concmd("amx_votemap", "cmdVoteMap", ADMIN_VOTE, " [map] [map] [map]") + register_concmd("amx_votekick", "cmdVoteKickBan", ADMIN_VOTE, "") + register_concmd("amx_voteban", "cmdVoteKickBan", ADMIN_VOTE, "") + register_concmd("amx_vote", "cmdVote", ADMIN_VOTE, " ") + register_concmd("amx_cancelvote", "cmdCancelVote", ADMIN_VOTE, "- cancels last vote") + + g_coloredMenus = colored_menus() +} + +public cmdCancelVote(id, level, cid) +{ + if (!cmd_access(id, level, cid, 0)) + return PLUGIN_HANDLED + + if (task_exists(99889988, 1)) + { + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + log_amx("Vote: ^"%s<%d><%s><>^" cancel vote session", name, get_user_userid(id), authid) + + new msg[256]; + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i) && !is_user_bot(i)) + { + // HACK: ADMIN_CANC_VOTE_{1,2} keys were designed very poorly. Remove all : and %s in it. + LookupLangKey(msg, charsmax(msg), "ADMIN_CANC_VOTE_1", i); + replace_all(msg, charsmax(msg), "%s", ""); + replace_all(msg, charsmax(msg), ":", ""); + trim(msg); + show_activity_id(i, id, name, msg); + } + } + + console_print(id, "%L", id, "VOTING_CANC") + client_print(0,print_chat,"%L",LANG_PLAYER,"VOTING_CANC") + remove_task(99889988, 1) + set_cvar_float("amx_last_voting", get_gametime()) + } + else + console_print(id, "%L", id, "NO_VOTE_CANC") + + return PLUGIN_HANDLED +} + +public delayedExec(cmd[]) + server_cmd("%s", cmd) + +public autoRefuse() +{ + log_amx("Vote: %L", "en", "RES_REF") + client_print(0, print_chat, "%L", LANG_PLAYER, "RES_REF") +} + +public actionResult(id, key) +{ + remove_task(4545454) + + switch (key) + { + case 0: + { + set_task(2.0, "delayedExec", 0, g_Execute, g_execLen) + log_amx("Vote: %L", "en", "RES_ACCEPTED") + client_print(0, print_chat, "%L", LANG_PLAYER, "RES_ACCEPTED") + } + case 1: autoRefuse() + } + + return PLUGIN_HANDLED +} + +public checkVotes() +{ + new best = 0 + + if (!g_yesNoVote) + { + for (new a = 0; a < 4; ++a) + if (g_voteCount[a] > g_voteCount[best]) + + best = a + } + + new votesNum = g_voteCount[0] + g_voteCount[1] + g_voteCount[2] + g_voteCount[3] + new iRatio = votesNum ? floatround(g_voteRatio * float(votesNum), floatround_ceil) : 1 + new iResult = g_voteCount[best] + new players[MAX_PLAYERS], pnum, i + + get_players(players, pnum, "c") + + if (iResult < iRatio) + { + new lVotingFailed[64] + + for (i = 0; i < pnum; i++) + { + format(lVotingFailed, 63, "%L", players[i], "VOTING_FAILED") + if (g_yesNoVote) + client_print(players[i], print_chat, "%L", players[i], "VOTING_RES_1", lVotingFailed, g_voteCount[0], g_voteCount[1], iRatio) + else + client_print(players[i], print_chat, "%L", players[i], "VOTING_RES_2", lVotingFailed, iResult, iRatio) + } + + format(lVotingFailed, 63, "%L", "en", "VOTING_FAILED") + log_amx("Vote: %s (got ^"%d^") (needed ^"%d^")", lVotingFailed, iResult, iRatio) + + return PLUGIN_CONTINUE + } + + g_execLen = format(g_Execute, charsmax(g_Execute), g_Answer, g_optionName[best]) + 1 + + if (g_execResult) + { + g_execResult = false + + if (is_user_connected(g_voteCaller)) + { + new menuBody[512], lTheResult[32], lYes[16], lNo[16] + + format(lTheResult, charsmax(lTheResult), "%L", g_voteCaller, "THE_RESULT") + format(lYes, charsmax(lYes), "%L", g_voteCaller, "YES") + format(lNo, charsmax(lNo), "%L", g_voteCaller, "NO") + + new len = format(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%s: \w%s^n^n" : "%s: %s^n^n", lTheResult, g_Execute) + + len += format(menuBody[len], charsmax(menuBody) - len, g_coloredMenus ? "\y%L^n\w" : "%L^n", g_voteCaller, "WANT_CONTINUE") + format(menuBody[len], charsmax(menuBody) - len, "^n1. %s^n2. %s", lYes, lNo) + show_menu(g_voteCaller, 0x03, menuBody, 10, "The result: ") + set_task(10.0, "autoRefuse", 4545454) + } + else + set_task(2.0, "delayedExec", 0, g_Execute, g_execLen) + } + + new lVotingSuccess[32] + + for (i = 0; i < pnum; i++) + { + format(lVotingSuccess, charsmax(lVotingSuccess), "%L", players[i], "VOTING_SUCCESS") + client_print(players[i], print_chat, "%L", players[i], "VOTING_RES_3", lVotingSuccess, iResult, iRatio, g_Execute) + } + + format(lVotingSuccess, charsmax(lVotingSuccess), "%L", "en", "VOTING_SUCCESS") + log_amx("Vote: %s (got ^"%d^") (needed ^"%d^") (result ^"%s^")", lVotingSuccess, iResult, iRatio, g_Execute) + + return PLUGIN_CONTINUE +} + +public voteCount(id, key) +{ + if (get_cvar_num("amx_vote_answers")) + { + new name[MAX_NAME_LENGTH] + get_user_name(id, name, charsmax(name)) + + if (g_yesNoVote) + client_print(0, print_chat, "%L", LANG_PLAYER, key ? "VOTED_AGAINST" : "VOTED_FOR", name) + else + client_print(0, print_chat, "%L", LANG_PLAYER, "VOTED_FOR_OPT", name, key + 1) + } + ++g_voteCount[key] + + return PLUGIN_HANDLED +} + +public cmdVoteMap(id, level, cid) +{ + if (!cmd_access(id, level, cid, 2)) + return PLUGIN_HANDLED + + new Float:voting = get_cvar_float("amx_last_voting") + if (voting > get_gametime()) + { + console_print(id, "%L", id, "ALREADY_VOTING") + return PLUGIN_HANDLED + } + + if (voting && voting + get_cvar_float("amx_vote_delay") > get_gametime()) + { + console_print(id, "%L", id, "VOTING_NOT_ALLOW") + return PLUGIN_HANDLED + } + + new argc = read_argc() + if (argc > 5) argc = 5 + + g_validMaps = 0 + g_optionName[0][0] = 0 + g_optionName[1][0] = 0 + g_optionName[2][0] = 0 + g_optionName[3][0] = 0 + + for (new i = 1; i < argc; ++i) + { + read_argv(i, g_optionName[g_validMaps], 31) + + if (contain(g_optionName[g_validMaps], "..") != -1) + continue + + if (is_map_valid(g_optionName[g_validMaps])) + g_validMaps++ + } + + if (g_validMaps == 0) + { + new lMaps[16] + + format(lMaps, charsmax(lMaps), "%L", id, (argc == 2) ? "MAP_IS" : "MAPS_ARE") + console_print(id, "%L", id, "GIVEN_NOT_VALID", lMaps) + return PLUGIN_HANDLED + } + + new menu_msg[256], len = 0 + new keys = 0 + + if (g_validMaps > 1) + { + keys = MENU_KEY_0 + len = format(menu_msg, charsmax(menu_msg), g_coloredMenus ? "\y%L: \w^n^n" : "%L: ^n^n", LANG_SERVER, "CHOOSE_MAP") + new temp[128] + + for (new a = 0; a < g_validMaps; ++a) + { + format(temp, charsmax(temp), "%d. %s^n", a+1, g_optionName[a]) + len += copy(menu_msg[len], charsmax(menu_msg) - len, temp) + keys |= (1<<%s><>^" vote map (map ^"%s^")", name, get_user_userid(id), authid, g_optionName[0]) + else + log_amx("Vote: ^"%s<%d><%s><>^" vote maps (map#1 ^"%s^") (map#2 ^"%s^") (map#3 ^"%s^") (map#4 ^"%s^")", name, get_user_userid(id), authid, g_optionName[0], g_optionName[1], g_optionName[2], g_optionName[3]) + + new msg[256]; + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i) && !is_user_bot(i)) + { + // HACK: ADMIN_VOTE_MAP_{1,2} keys were designed very poorly. Remove all : and %s in it. + LookupLangKey(msg, charsmax(msg), "ADMIN_VOTE_MAP_1", i); + replace_all(msg, charsmax(msg), "%s", ""); + replace_all(msg, charsmax(msg), ":", ""); + trim(msg); + show_activity_id(i, id, name, msg); + } + } + + g_execResult = true + new Float:vote_time = get_cvar_float("amx_vote_time") + 2.0 + + set_cvar_float("amx_last_voting", get_gametime() + vote_time) + g_voteRatio = get_cvar_float("amx_votemap_ratio") + g_Answer = "changelevel %s" + show_menu(0, keys, menu_msg, floatround(vote_time), (g_validMaps > 1) ? "Choose map: " : "Change map to ") + set_task(vote_time, "checkVotes", 99889988) + g_voteCaller = id + console_print(id, "%L", id, "VOTING_STARTED") + g_voteCount = {0, 0, 0, 0} + + return PLUGIN_HANDLED +} + +public cmdVote(id, level, cid) +{ + if (!cmd_access(id, level, cid, 4)) + return PLUGIN_HANDLED + + new Float:voting = get_cvar_float("amx_last_voting") + if (voting > get_gametime()) + { + console_print(id, "%L", id, "ALREADY_VOTING") + return PLUGIN_HANDLED + } + + if (voting && voting + get_cvar_float("amx_vote_delay") > get_gametime()) + { + console_print(id, "%L", id, "VOTING_NOT_ALLOW") + return PLUGIN_HANDLED + } + + new quest[48] + read_argv(1, quest, charsmax(quest)) + + trim(quest); + + if (containi(quest, "sv_password") != -1 || containi(quest, "rcon_password") != -1) + { + console_print(id, "%L", id, "VOTING_FORBIDDEN") + return PLUGIN_HANDLED + } + + new count=read_argc(); + + for (new i=0;i<4 && (i+2)<%s><>^" vote custom (question ^"%s^") (option#1 ^"%s^") (option#2 ^"%s^")", name, get_user_userid(id), authid, quest, g_optionName[0], g_optionName[1]) + + new msg[256]; + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i) && !is_user_bot(i)) + { + // HACK: ADMIN_VOTE_CUS_{1,2} keys were designed very poorly. Remove all : and %s in it. + LookupLangKey(msg, charsmax(msg), "ADMIN_VOTE_CUS_1", i); + replace_all(msg, charsmax(msg), "%s", ""); + replace_all(msg, charsmax(msg), ":", ""); + trim(msg); + show_activity_id(i, id, name, msg); + } + } + + new menu_msg[512], lVote[16] + + format(lVote, charsmax(lVote), "%L", LANG_SERVER, "VOTE") + + count-=2; + if (count>4) + { + count=4; + } + // count now shows how many options were listed + new keys=0; + for (new i=0;i get_gametime()) + { + console_print(id, "%L", id, "ALREADY_VOTING") + return PLUGIN_HANDLED + } + + if (voting && voting + get_cvar_float("amx_vote_delay") > get_gametime()) + { + console_print(id, "%L", id, "VOTING_NOT_ALLOW") + return PLUGIN_HANDLED + } + + new cmd[32] + + read_argv(0, cmd, charsmax(cmd)) + + new voteban = equal(cmd, "amx_voteban") + new arg[32] + read_argv(1, arg, charsmax(arg)) + + new player = cmd_target(id, arg, CMDTARGET_OBEY_IMMUNITY | CMDTARGET_ALLOW_SELF) + + if (!player) + return PLUGIN_HANDLED + + if (voteban && is_user_bot(player)) + { + new imname[MAX_NAME_LENGTH] + + get_user_name(player, imname, charsmax(imname)) + console_print(id, "%L", id, "ACTION_PERFORMED", imname) + return PLUGIN_HANDLED + } + + new keys = MENU_KEY_1|MENU_KEY_2 + new menu_msg[256], lYes[16], lNo[16], lKickBan[16] + + format(lYes, charsmax(lYes), "%L", LANG_SERVER, "YES") + format(lNo, charsmax(lNo), "%L", LANG_SERVER, "NO") + format(lKickBan, charsmax(lKickBan), "%L", LANG_SERVER, voteban ? "BAN" : "KICK") + ucfirst(lKickBan) + get_user_name(player, arg, charsmax(arg)) + format(menu_msg, charsmax(menu_msg), g_coloredMenus ? "\y%s %s?\w^n^n1. %s^n2. %s" : "%s %s?^n^n1. %s^n2. %s", lKickBan, arg, lYes, lNo) + g_yesNoVote = 1 + + new bool:ipban=false; + + if (voteban) + { + get_user_authid(player, g_optionName[0], charsmax(g_optionName[])); + + // Do the same check that's in plmenu to determine if this should be an IP ban instead + if (equal("4294967295", g_optionName[0]) + || equal("HLTV", g_optionName[0]) + || equal("STEAM_ID_LAN", g_optionName[0]) + || equali("VALVE_ID_LAN", g_optionName[0])) + { + get_user_ip(player, g_optionName[0], charsmax(g_optionName[]), 1); + + ipban=true; + } + + } + else + { + num_to_str(get_user_userid(player), g_optionName[0], charsmax(g_optionName[])) + } + + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + log_amx("Vote: ^"%s<%d><%s><>^" vote %s (target ^"%s^")", name, get_user_userid(id), authid, voteban ? "ban" : "kick", arg) + + new msg[256]; + new right[256]; + new dummy[1]; + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i) && !is_user_bot(i)) + { + formatex(lKickBan, charsmax(lKickBan), "%L", i, voteban ? "BAN" : "KICK"); + + // HACK: ADMIN_VOTE_FOR{1,2} keys are really weird. Tokenize and ignore the text before the : + LookupLangKey(msg, charsmax(msg), "ADMIN_VOTE_FOR_1", i); + strtok(msg, dummy, 0, right, charsmax(right), ':'); + trim(right); + show_activity_id(i, id, name, right, lKickBan, arg); + } + } + + g_execResult = true + + new Float:vote_time = get_cvar_float("amx_vote_time") + 2.0 + + set_cvar_float("amx_last_voting", get_gametime() + vote_time) + g_voteRatio = get_cvar_float(voteban ? "amx_voteban_ratio" : "amx_votekick_ratio") + + if (voteban) + { + if (ipban==true) + { + g_Answer = "addip 30.0 %s"; + } + else + { + g_Answer = "banid 30.0 %s kick"; + + } + } + else + { + g_Answer = "kick #%s"; + } + show_menu(0, keys, menu_msg, floatround(vote_time), voteban ? "Ban " : "Kick ") + set_task(vote_time, "checkVotes", 99889988) + g_voteCaller = id + console_print(id, "%L", id, "VOTING_STARTED") + g_voteCount = {0, 0, 0, 0} + + return PLUGIN_HANDLED +} diff --git a/amxmodx/scripting/amxxpc b/amxmodx/scripting/amxxpc new file mode 100755 index 0000000..d579e0b Binary files /dev/null and b/amxmodx/scripting/amxxpc differ diff --git a/amxmodx/scripting/amxxpc32.so b/amxmodx/scripting/amxxpc32.so new file mode 100755 index 0000000..6cf3c5c Binary files /dev/null and b/amxmodx/scripting/amxxpc32.so differ diff --git a/amxmodx/scripting/antiflood.sma b/amxmodx/scripting/antiflood.sma new file mode 100755 index 0000000..f43c8c9 --- /dev/null +++ b/amxmodx/scripting/antiflood.sma @@ -0,0 +1,57 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Anti Flood Plugin +// + +#include + +new Float:g_Flooding[MAX_PLAYERS + 1] = {0.0, ...} +new g_Flood[MAX_PLAYERS + 1] = {0, ...} + +new amx_flood_time; + +public plugin_init() +{ + register_plugin("Anti Flood", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("antiflood.txt") + register_clcmd("say", "chkFlood") + register_clcmd("say_team", "chkFlood") + amx_flood_time=register_cvar("amx_flood_time", "0.75") +} + +public chkFlood(id) +{ + new Float:maxChat = get_pcvar_float(amx_flood_time) + + if (maxChat) + { + new Float:nexTime = get_gametime() + + if (g_Flooding[id] > nexTime) + { + if (g_Flood[id] >= 3) + { + client_print(id, print_notify, "** %L **", id, "STOP_FLOOD") + g_Flooding[id] = nexTime + maxChat + 3.0 + return PLUGIN_HANDLED + } + g_Flood[id]++ + } + else if (g_Flood[id]) + { + g_Flood[id]-- + } + + g_Flooding[id] = nexTime + maxChat + } + + return PLUGIN_CONTINUE +} diff --git a/amxmodx/scripting/cmdmenu.sma b/amxmodx/scripting/cmdmenu.sma new file mode 100755 index 0000000..5a01aa6 --- /dev/null +++ b/amxmodx/scripting/cmdmenu.sma @@ -0,0 +1,560 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Commands Menu Plugin +// + +#include +#include + +// Precache sounds from speech.ini - comment this line to disable +#define PRECACHE_SPEECHINI + +/* Commands Menus */ + +#define MAX_CMDS_LAYERS 3 + +new g_cmdMenuName[MAX_CMDS_LAYERS][] = +{ + "CMD_MENU", + "CONF_MENU", + "SPE_MENU" +}; + +new g_cmdMenuCmd[MAX_CMDS_LAYERS][] = +{ + "amx_cmdmenu", + "amx_cfgmenu", + "amx_speechmenu" +}; + +new g_cmdMenuCfg[MAX_CMDS_LAYERS][] = +{ + "cmds.ini", + "configs.ini", + "speech.ini" +}; + +new g_cmdMenuHelp[MAX_CMDS_LAYERS][] = +{ + "- displays commands menu", + "- displays configs menu", + "- displays speech menu" +}; + +/* End of Commands Menu */ + +#define MAX_CMDS 64 +#define MAX_CVARS 48 + +new g_cmdName[MAX_CMDS*MAX_CMDS_LAYERS][32]; +new g_cmdCmd[MAX_CMDS*MAX_CMDS_LAYERS][64]; +new g_cmdMisc[MAX_CMDS*MAX_CMDS_LAYERS][2]; +new g_cmdNum[MAX_CMDS_LAYERS]; + +new g_cvarNames[MAX_CVARS][32]; +new g_cvarMisc[MAX_CVARS][3]; +new g_cvarCmd[MAX_CVARS*5][32]; +new g_cvarCmdNum; +new g_cvarNum; + +new g_menuPosition[MAX_PLAYERS + 1]; +new g_menuSelect[MAX_PLAYERS + 1][MAX_CMDS]; +new g_menuSelectNum[MAX_PLAYERS + 1]; +new g_menuLayer[MAX_PLAYERS + 1]; + +new g_coloredMenus; + + +public plugin_init() +{ + register_plugin("Commands Menu", AMXX_VERSION_STR, "AMXX Dev Team"); + register_dictionary("cmdmenu.txt"); + register_dictionary("common.txt"); + + new configsDir[64], config[64]; + get_configsdir(configsDir, charsmax(configsDir)); + + for (new a = 0; a < MAX_CMDS_LAYERS; ++a) + { + new MenuName[64]; + + formatex(MenuName, charsmax(MenuName), "%L", "en", g_cmdMenuName[a]); + register_menucmd(register_menuid(MenuName), 1023, "actionCmdMenu"); + register_clcmd(g_cmdMenuCmd[a], "cmdCmdMenu", ADMIN_MENU, g_cmdMenuHelp[a]); + formatex(config, charsmax(config), "%s/%s", configsDir, g_cmdMenuCfg[a]); + loadCmdSettings(config, a); + } + + register_menucmd(register_menuid("Cvars Menu"), 1023, "actionCvarMenu"); + register_clcmd("amx_cvarmenu", "cmdCvarMenu", ADMIN_CVAR, "- displays cvars menu"); + + new cvars_ini_file[64]; + formatex(cvars_ini_file, charsmax(cvars_ini_file), "%s/%s", configsDir, "cvars.ini"); + loadCvarSettings(cvars_ini_file); + + g_coloredMenus = colored_menus(); +} + +#if defined PRECACHE_SPEECHINI +public plugin_precache( ) +{ + new configsDir[64], config[64]; + get_configsdir(configsDir, charsmax(configsDir)); + formatex( config, charsmax(config), "%s/%s", configsDir, "speech.ini" ); + + new fp = fopen( config, "rt" ); // Read file as text + + if ( ! fp ) // File doesn't exists + { + return 0; + } + + new szText[256]; + new line = 0; + new szName[32], szSound[128], sndExt[5]; + new field1[32], field2[64], field3[64]; + new fieldNums = 0; + new const voxIdent[] = "vox", fvoxIdent[] = "fvox", barneyIdent[] = "barney", hgruntIdent[] = "hgrunt"; + + while ( line < MAX_CMDS && ! feof( fp ) ) // Loop till MAX_CMDS or EOF + { + fgets( fp, szText, charsmax(szText) ); // Store line content + + /* Strips newline */ + new len = strlen( szText ); + if ( len != 0 && szText[len-1] == '^n' ) // len != 0 because if the last line of the file is empty, there's no newline + { + szText[--len] = 0; + } + + if ( len == 0 || szText[0] == ';' || szText[0] == '/' ) // Line is empty or a comment + { + continue; + } + + parse( szText, szName, charsmax(szName), szSound, charsmax(szSound) ); + fieldNums = parse( szSound, field1, charsmax(field1), field2, charsmax(field2), field3, charsmax(field3) ); + if ( fieldNums == 2 && field1[0] == 's' ) // .wav (spk) + { + copy( szSound, charsmax(szSound), field2 ); + copy( sndExt, charsmax(sndExt), ".wav" ); + } + else if ( fieldNums == 3 && field1[0] == 'm' && ( field2[0] == 'p' || field2[0] == 'l' ) ) // .mp3 (mp3 play | mp3 loop) + { + copy( szSound, charsmax(szSound), field3 ); + copy( sndExt, charsmax(sndExt), ".mp3" ); + } + else // WTH is this sound, drop it. + continue; + + replace_all( szSound, charsmax(szSound), "\'", "" ); // Strips all ugly (and sometimes useless) \' + + if ( szSound[0] == '/' ) + { + replace( szSound, charsmax(szSound), "/", "" ); // Strip leading slash + } + + if ( sndExt[1] == 'm' || ( ! equali( szSound, voxIdent, charsmax(voxIdent) ) && ! equali( szSound, fvoxIdent, charsmax(fvoxIdent) ) && ! equali( szSound, barneyIdent, charsmax(barneyIdent) ) && ! equali( szSound, hgruntIdent, charsmax(hgruntIdent) ) ) ) + { + // SzSound is a mp3, or a custom wav (not a vox, fvox, or default sound from HL pak) + if ( !equali( szSound[strlen(szSound)-4], sndExt ) ) + { + add( szSound, charsmax(szSound), sndExt ); // Add filetype extension if it isn't already specified + } + if ( sndExt[1] == 'w' ) + { + format( szSound, charsmax(szSound), "sound/%s", szSound ); // spk basedir is $moddir/sound, but mp3 play is $moddir, fix this for the file_exists check + } + if ( file_exists( szSound ) ) + { + if ( sndExt[1] == 'm') + { + precache_generic( szSound ); // mp3 + } + else + { + replace( szSound, charsmax(szSound), "sound/", "" ); // wav, strip the leading sound/ we added for our file_exists check + precache_sound( szSound ); + } + } + } + line++; + } + fclose( fp ); // Close file + return line; +} +#endif + +/* Commands menu */ + +public actionCmdMenu(id, key) +{ + switch (key) + { + case 8: + { + displayCmdMenu(id, ++g_menuPosition[id]); + } + case 9: + { + displayCmdMenu(id, --g_menuPosition[id]); + } + default: + { + new option = g_menuSelect[id][g_menuPosition[id] * 8 + key]; + new flags = g_cmdMisc[option][1]; + + if (flags & 1) + server_cmd("%s", g_cmdCmd[option]) + else if (flags & 2) + client_cmd(id, "%s", g_cmdCmd[option]) + else if (flags & 4) + client_cmd(0, "%s", g_cmdCmd[option]) + + if (flags & 8) + { + displayCmdMenu(id, g_menuPosition[id]); + } + } + } + + return PLUGIN_HANDLED; +} + +displayCmdMenu(id, pos) +{ + if (pos < 0) + { + return; + } + + new menuBody[512]; + new b = 0; + new start = pos * 8; + + if (start >= g_menuSelectNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new limit = (g_menuSelectNum[id] / 8 + ((g_menuSelectNum[id] % 8))); + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, g_cmdMenuName[g_menuLayer[id]], pos + 1, (limit == 0) ? 1 : limit); + new end = start + 8; + new keys = MENU_KEY_0; + + if (end > g_menuSelectNum[id]) + { + end = g_menuSelectNum[id]; + } + + for (new a = start; a < end; ++a) + { + if (g_cmdCmd[g_menuSelect[id][a]][0] == '-') + { + if (g_coloredMenus) + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "\d%s^n\w", g_cmdName[g_menuSelect[id][a]]); + } + else + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "%s^n", g_cmdName[g_menuSelect[id][a]]); + } + ++b; + } + else + { + keys |= (1< 3) + { + while (replace(g_cmdCmd[c], charsmax(g_cmdCmd[]), "\'", "^"")) + { + // do nothing + } + + g_cmdMisc[c][1] = read_flags(szFlags); + g_cmdMisc[c][0] = read_flags(szAccess); + g_cmdNum[level]++; + } + } + + return 1; +} + +/* Cvars menu */ + +public actionCvarMenu(id, key) +{ + switch (key) + { + case 8: + { + displayCvarMenu(id, ++g_menuPosition[id]); + } + case 9: + { + displayCvarMenu(id, --g_menuPosition[id]); + } + default: + { + new option = g_menuSelect[id][g_menuPosition[id] * 8 + key]; + new szValue[32]; + + get_cvar_string(g_cvarNames[option], szValue, charsmax(szValue)); + + new end = g_cvarMisc[option][2]; + new start = g_cvarMisc[option][1]; + + for (new i = start; ; ++i) + { + if (i < end) + { + if (equal(szValue, g_cvarCmd[i])) + { + if (++i >= end) + { + i = start; + } + + set_cvar_string(g_cvarNames[option], g_cvarCmd[i]); + break; + } + } + else + { + set_cvar_string(g_cvarNames[option], g_cvarCmd[start]); + break; + } + } + displayCvarMenu(id, g_menuPosition[id]); + } + } + + return PLUGIN_HANDLED; +} + +displayCvarMenu(id, pos) +{ + if (pos < 0) + { + return; + } + + new menuBody[512]; + new b = 0; + new start = pos * 8; + + if (start >= g_menuSelectNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\yCvars Menu\R%d/%d^n\w^n" : "Cvars Menu %d/%d^n^n", pos + 1, (g_menuSelectNum[id] / 8 + ((g_menuSelectNum[id] % 8) ? 1 : 0))); + + new end = start + 8; + new keys = MENU_KEY_0; + new szValue[64]; + + if (end > g_menuSelectNum[id]) + { + end = g_menuSelectNum[id]; + } + + for (new a = start; a < end; ++a) + { + get_cvar_string(g_cvarNames[g_menuSelect[id][a]], szValue, charsmax(szValue)); + keys |= (1<> temp.txt + echo "done" +done + +less temp.txt +rm temp.txt diff --git a/amxmodx/scripting/csstats.sma b/amxmodx/scripting/csstats.sma new file mode 100755 index 0000000..904b68a --- /dev/null +++ b/amxmodx/scripting/csstats.sma @@ -0,0 +1,37 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Rank Calculation +// + +/* File location: $moddir/addons/amxmodx/data/csstats.amxx */ + +#include + +/* Function calculates position in rank. +* +* Stats: +* 0 - kills +* 1 - deaths +* 2 - headshots +* 3 - teamkills +* 4 - shots +* 5 - hits +* 6 - damage +* 7 - defusions +* 8 - defused +* 9 - plants +* 10 - explosions +* +* Returning cellmin as value in get_score function +* makes that rank won't be saved. */ + +public get_score(stats[11], body[MAX_BODYHITS]) + return stats[STATSX_KILLS] - stats[STATSX_DEATHS] - stats[STATSX_TEAMKILLS] // kills - deaths - teamkills diff --git a/amxmodx/scripting/imessage.sma b/amxmodx/scripting/imessage.sma new file mode 100755 index 0000000..f03c11a --- /dev/null +++ b/amxmodx/scripting/imessage.sma @@ -0,0 +1,123 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Info. Messages Plugin +// + +#include +#include + +#define X_POS -1.0 +#define Y_POS 0.20 +#define HOLD_TIME 12.0 + +new Array:g_Values +new Array:g_Messages +new g_MessagesNum +new g_Current + +new amx_freq_imessage; + +public plugin_init() +{ + g_Messages=ArrayCreate(384); + g_Values=ArrayCreate(3); + register_plugin("Info. Messages", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("imessage.txt") + register_dictionary("common.txt") + register_srvcmd("amx_imessage", "setMessage") + amx_freq_imessage=register_cvar("amx_freq_imessage", "10") + + new lastinfo[8] + get_localinfo("lastinfomsg", lastinfo, charsmax(lastinfo)) + g_Current = str_to_num(lastinfo) + set_localinfo("lastinfomsg", "") +} + +public infoMessage() +{ + if (g_Current >= g_MessagesNum) + g_Current = 0 + + // No messages, just get out of here + if (g_MessagesNum==0) + { + return; + } + + new values[3]; + new Message[384]; + + ArrayGetString(g_Messages, g_Current, Message, charsmax(Message)); + ArrayGetArray(g_Values, g_Current, values); + + new hostname[64]; + + get_cvar_string("hostname", hostname, charsmax(hostname)); + replace(Message, charsmax(Message), "%hostname%", hostname); + + set_hudmessage(values[0], values[1], values[2], X_POS, Y_POS, 0, 0.5, HOLD_TIME, 2.0, 2.0, -1); + + show_hudmessage(0, "%s", Message); + + client_print(0, print_console, "%s", Message); + ++g_Current; + + new Float:freq_im = get_pcvar_float(amx_freq_imessage); + + if (freq_im > 0.0) + set_task(freq_im, "infoMessage", 12345); +} + +public setMessage() +{ + + new Message[384]; + + remove_task(12345) + read_argv(1, Message, charsmax(Message)) + + while (replace(Message, charsmax(Message), "\n", "^n")) {} + + new mycol[12] + new vals[3]; + + read_argv(2, mycol, charsmax(mycol)) // RRRGGGBBB + vals[2] = str_to_num(mycol[6]) + + mycol[6] = 0 + vals[1] = str_to_num(mycol[3]) + + mycol[3] = 0 + vals[0] = str_to_num(mycol[0]) + + g_MessagesNum++ + + new Float:freq_im = get_pcvar_float(amx_freq_imessage) + + ArrayPushString(g_Messages, Message); + ArrayPushArray(g_Values, vals); + + if (freq_im > 0.0) + set_task(freq_im, "infoMessage", 12345) + + return PLUGIN_HANDLED +} + +public plugin_end() +{ + new lastinfo[8] + + num_to_str(g_Current, lastinfo, charsmax(lastinfo)) + set_localinfo("lastinfomsg", lastinfo) + + ArrayDestroy(g_Messages) + ArrayDestroy(g_Values) +} diff --git a/amxmodx/scripting/include/amxconst.inc b/amxmodx/scripting/include/amxconst.inc new file mode 100644 index 0000000..2944fcd --- /dev/null +++ b/amxmodx/scripting/include/amxconst.inc @@ -0,0 +1,593 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _amxconst_included + #endinput +#endif +#define _amxconst_included + +#include + +/** + * Internal AMXX buffer size for string retrieval. + * + * @note This is the buffer size AMX Mod X uses internally to retrieve strings + * from plugins. Most natives that take strings as arguments will + * implicitly truncate them to this maximum length. This has been raised + * to the current value with AMXX 1.8.3. Previously the limit was 3072. + * @note This is here mainly for documentation purposes. By default plugins + * don't have enough memory available to allocate an array of this size. + * You probably should not use this to actually declare a buffer unless + * you *absolutely* have to. Look at #pragma dynamic to increase a plugins + * available memory. + */ +#define MAX_STRING_LENGTH 16384 + +/** + * The maximum buffer size required to store a map's name. + */ +#define MAX_MAPNAME_LENGTH 64 + +/** + * Defines and constants related to the maximum number of clients. + * + * @note MAX_PLAYERS is not the same as MaxClients. MAX_PLAYERS is a hardcoded + * value as an upper limit, used mainly to declare arrays big enough for + * all possible server situations. MaxClients changes based on the + * server the plugin is deployed on.. + */ +#define MAX_PLAYERS 32 /* Maximum number of players AMX Mod X supports */ + +/** + * Maximum number of players the server supports + */ +public stock const MaxClients; + +/** + * Current map name + */ +public stock const MapName[MAX_MAPNAME_LENGTH]; + +/** + * Pass this into certain functions to act as a C++ NULL + */ +public stock const NULL_STRING[1]; + +/** + * Pass this into certain functions to act as a C++ NULL + */ +public stock const Float:NULL_VECTOR[3]; + +/** + * The maximum buffer size required to store a client's name. + */ +#define MAX_NAME_LENGTH 32 + +/** + * The maximum buffer size required to store a client's IP address without a port. + */ +#define MAX_IP_LENGTH 16 + +/** + * The maximum buffer size required to store a client's IP address with a port. + */ +#define MAX_IP_WITH_PORT_LENGTH 22 + +/** + * The maximum buffer size required to store a client's AuthID. + */ +#define MAX_AUTHID_LENGTH 64 + +/** + * The maximum buffer size required to store a resource path. + */ +#define MAX_RESOURCE_PATH_LENGTH 64 + +/** + * The maximum buffer size that can be displayed in a MOTD. + */ +#define MAX_MOTD_LENGTH 1536 + +/** + * The maximum size accepted by the user info buffer. + */ +#define MAX_USER_INFO_LENGTH 256 + +/** + * The maximum buffer size that can be displayed in a menu. + */ +#define MAX_MENU_LENGTH 512 + +/** + * π + */ +#define M_PI 3.1415926535 + +/** + * @section Admin privilege and authentication constants + */ + +/** + * Admin level constants + */ +#define ADMIN_ALL 0 /* everyone */ +#define ADMIN_IMMUNITY (1<<0) /* flag "a" */ +#define ADMIN_RESERVATION (1<<1) /* flag "b" */ +#define ADMIN_KICK (1<<2) /* flag "c" */ +#define ADMIN_BAN (1<<3) /* flag "d" */ +#define ADMIN_SLAY (1<<4) /* flag "e" */ +#define ADMIN_MAP (1<<5) /* flag "f" */ +#define ADMIN_CVAR (1<<6) /* flag "g" */ +#define ADMIN_CFG (1<<7) /* flag "h" */ +#define ADMIN_CHAT (1<<8) /* flag "i" */ +#define ADMIN_VOTE (1<<9) /* flag "j" */ +#define ADMIN_PASSWORD (1<<10) /* flag "k" */ +#define ADMIN_RCON (1<<11) /* flag "l" */ +#define ADMIN_LEVEL_A (1<<12) /* flag "m" */ +#define ADMIN_LEVEL_B (1<<13) /* flag "n" */ +#define ADMIN_LEVEL_C (1<<14) /* flag "o" */ +#define ADMIN_LEVEL_D (1<<15) /* flag "p" */ +#define ADMIN_LEVEL_E (1<<16) /* flag "q" */ +#define ADMIN_LEVEL_F (1<<17) /* flag "r" */ +#define ADMIN_LEVEL_G (1<<18) /* flag "s" */ +#define ADMIN_LEVEL_H (1<<19) /* flag "t" */ +#define ADMIN_MENU (1<<20) /* flag "u" */ +#define ADMIN_BAN_TEMP (1<<21) /* flag "v" */ +#define ADMIN_ADMIN (1<<24) /* flag "y" */ +#define ADMIN_USER (1<<25) /* flag "z" */ + +/** + * Admin authentication behavior flags + */ +#define FLAG_KICK (1<<0) /* flag "a" */ +#define FLAG_TAG (1<<1) /* flag "b" */ +#define FLAG_AUTHID (1<<2) /* flag "c" */ +#define FLAG_IP (1<<3) /* flag "d" */ +#define FLAG_NOPASS (1<<4) /* flag "e" */ +#define FLAG_CASE_SENSITIVE (1<<10) /* flag "k" */ + +/** + * @endsection + */ + +/** + * Return codes + */ +#define PLUGIN_CONTINUE 0 /* Results returned by public functions */ +#define PLUGIN_HANDLED 1 /* stop other plugins */ +#define PLUGIN_HANDLED_MAIN 2 /* to use in client_command(), continue all plugins but stop the command */ + +/** + * HI weapon constants + */ +#define HIW_BERETTA 1 +#define HIW_SPAS12 2 +#define HIW_M4A1 3 +#define HIW_MP5A4 4 +#define HIW_MP5SD5 5 +#define HIW_AK47 6 +#define HIW_AKS74U 7 +#define HIW_GLOCK 8 +#define HIW_M11 9 +#define HIW_M11SD 10 +#define HIW_PSG1 11 +#define HIW_ZASTAVA 12 +#define HIW_M16A2 13 +#define HIW_REMINGTON 14 +#define HIW_NATOGREN 15 +#define HIW_TANGOGREN 16 +#define HIW_FLASHBANG 17 + +/** + * Parts of body for hits + */ +#define HIT_GENERIC 0 /* none */ +#define HIT_HEAD 1 +#define HIT_CHEST 2 +#define HIT_STOMACH 3 +#define HIT_LEFTARM 4 +#define HIT_RIGHTARM 5 +#define HIT_LEFTLEG 6 +#define HIT_RIGHTLEG 7 +#define HIT_SHIELD 8 // CS only +#define MAX_BODYHITS 8 + +/** + * @section emit_sound() constants + */ + +/** + * Channels + */ +#define CHAN_AUTO 0 +#define CHAN_WEAPON 1 +#define CHAN_VOICE 2 +#define CHAN_ITEM 3 +#define CHAN_BODY 4 +#define CHAN_STREAM 5 /* allocate stream channel from the static or dynamic area */ +#define CHAN_STATIC 6 /* allocate channel from the static area */ +#define CHAN_NETWORKVOICE_BASE 7 /* voice data coming across the network */ +#define CHAN_NETWORKVOICE_END 500 /* network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END). */ + +/** + *Attenuation values + */ +#define ATTN_NONE 0.00 +#define ATTN_NORM 0.80 +#define ATTN_IDLE 2.00 +#define ATTN_STATIC 1.25 + +/** + * Pitch values + */ +#define PITCH_NORM 100 /* non-pitch shifted */ +#define PITCH_LOW 95 /* other values are possible - 0-255, where 255 is very high */ +#define PITCH_HIGH 120 + +/** + * Volume values + */ +#define VOL_NORM 1.0 + +/** + * Sound behavior constants + */ +#define SND_SPAWNING (1<<8) // we're spawing, used in some cases for ambients +#define SND_STOP (1<<5) // stop sound +#define SND_CHANGE_VOL (1<<6) // change sound vol +#define SND_CHANGE_PITCH (1<<7) // change sound pitch + +/** + * @endsection + */ + +/** + * Menu keys + */ +#define MENU_KEY_1 (1<<0) +#define MENU_KEY_2 (1<<1) +#define MENU_KEY_3 (1<<2) +#define MENU_KEY_4 (1<<3) +#define MENU_KEY_5 (1<<4) +#define MENU_KEY_6 (1<<5) +#define MENU_KEY_7 (1<<6) +#define MENU_KEY_8 (1<<7) +#define MENU_KEY_9 (1<<8) +#define MENU_KEY_0 (1<<9) + +/** + * Language constants + */ +#define LANG_SERVER 0 +#define LANG_PLAYER -1 + +/** + * @section Client print native constants + */ + +/** + * Destination types for client_print() + */ +enum +{ + print_notify = 1, + print_console, + print_chat, + print_center, + print_radio /* Counter-Strike only */ +}; + +/** + * Color types for client_print_color() + */ +enum +{ + print_team_default = 0, + print_team_grey = -1, + print_team_red = -2, + print_team_blue = -3, +}; + +/** + * Destination types for engclient_print() + */ +enum +{ + engprint_console = 0, + engprint_center, + engprint_chat, +}; + +/** + * @endsection + */ + +/** + * @section Entity rendering constants + */ + +/** + * Rendering modes (i.e. for set_user_rendering()) + */ +enum +{ + kRenderNormal = 0, /* src */ + kRenderTransColor, /* c*a+dest*(1-a) */ + kRenderTransTexture, /* src*a+dest*(1-a) */ + kRenderGlow, /* src*a+dest -- No Z buffer checks */ + kRenderTransAlpha, /* src*srca+dest*(1-srca) */ + kRenderTransAdd, /* src*a+dest */ +}; + +/** + * Rendering fx (i.e. for set_user_rendering()) + */ +enum +{ + kRenderFxNone = 0, + kRenderFxPulseSlow, + kRenderFxPulseFast, + kRenderFxPulseSlowWide, + kRenderFxPulseFastWide, + kRenderFxFadeSlow, + kRenderFxFadeFast, + kRenderFxSolidSlow, + kRenderFxSolidFast, + kRenderFxStrobeSlow, + kRenderFxStrobeFast, + kRenderFxStrobeFaster, + kRenderFxFlickerSlow, + kRenderFxFlickerFast, + kRenderFxNoDissipation, + kRenderFxDistort, /* Distort/scale/translate flicker */ + kRenderFxHologram, /* kRenderFxDistort + distance fade */ + kRenderFxDeadPlayer, /* kRenderAmt is the player index */ + kRenderFxExplode, /* Scale up really big! */ + kRenderFxGlowShell, /* Glowing Shell */ + kRenderFxClampMinScale, /* Keep this sprite from getting very small (SPRITES only!) */ +}; + +/** + * @endsection + */ + +/** + * Type for force_unmodified() + */ +enum +{ + force_exactfile = 0, /* File on client must exactly match server's file */ + force_model_samebounds, /* For model files only, the geometry must fit in the same bbox */ + force_model_specifybounds, /* For model files only, the geometry must fit in the specified bbox */ +}; + +/** + * Status for get_module() + */ +enum +{ + module_none = 0, + module_query, + module_badload, + module_loaded, + module_noinfo, + module_noquery, + module_noattach, + module_old, +}; + +/** + * AMX flag constants + */ +#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */ +#define AMX_FLAG_COMPACT 0x04 /* compact encoding */ +#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */ +#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */ +#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */ +#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */ +#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */ +#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */ + +/** + * Invalid plugin id + */ +#define INVALID_PLUGIN_ID -1 + +/** + * Menu and menu item status codes + */ +#define MENU_TIMEOUT -4 +#define MENU_EXIT -3 +#define MENU_BACK -2 +#define MENU_MORE -1 +#define ITEM_IGNORE 0 +#define ITEM_ENABLED 1 +#define ITEM_DISABLED 2 + +/** + * AMX error codes + */ +#define AMX_ERR_NATIVE 10 +#define AMX_ERR_MEMACCESS 5 +#define AMX_ERR_NONE 0 +#define AMX_ERR_BOUNDS 4 +#define AMX_ERR_STACKERR 3 +#define AMX_ERR_STACKLOW 7 +#define AMX_ERR_HEAPLOW 8 +#define AMX_ERR_DIVIDE 11 +#define AMX_ERR_NOTFOUND 19 +#define AMX_ERR_PARAMS 25 +#define AMX_ERR_GENERAL 27 + +/** + * Generic invalid handle value + */ +#define INVALID_HANDLE -1 + +/** + * @section Plugin forward related constants + */ + +/** + * Stop types for plugin forwards + */ +#define ET_IGNORE 0 //ignore return val +#define ET_STOP 1 //stop on PLUGIN_HANDLED +#define ET_STOP2 2 //same, except return biggest +#define ET_CONTINUE 3 //no stop, return biggest + +/** + * Parameter types for plugin forwards + */ +#define FP_CELL 0 +#define FP_FLOAT 1 +#define FP_STRING 2 +#define FP_ARRAY 4 +#define FP_VAL_BYREF 5 //cell & float are handled in the same way + +/** + * @endsection + */ + +/** + * LibType constants + */ +enum LibType +{ + LibType_Library, + LibType_Class +}; + +/** + * AdminProp constants + */ +enum AdminProp +{ + AdminProp_Auth = 0, + AdminProp_Password, + AdminProp_Access, + AdminProp_Flags +}; + +/** + * HashType constants + * To be used on hash_file() and hash_string() + */ +enum HashType +{ + Hash_Crc32 = 0, // Provides CRC32 hashing + Hash_Md5, // Provides MD5 hashing + Hash_Sha1, // Provides SHA1 hashing + Hash_Sha256, // Provides SHA256 hashing + + Hash_Sha3_224, // Provides SHA3 224 bit hashing + Hash_Sha3_256, // Provides SHA3 256 bit hashing + Hash_Sha3_384, // Provides SHA3 384 bit hashing + Hash_Sha3_512, // Provides SHA3 512 bit hashing + + Hash_Keccak_224, // Provides Keccak 224 bit hashing + Hash_Keccak_256, // Provides Keccak 256 bit hashing + Hash_Keccak_384, // Provides Keccak 384 bit hashing + Hash_Keccak_512 // Provides Keccak 512 bit hashing +}; + +/** + * SetTaskFlags constants for set_task_ex() + */ +enum SetTaskFlags (<<= 1) +{ + SetTask_Once = 0, // None; execute callback after the specified amount of time (Default) + SetTask_RepeatTimes = 1, // Repeat timer a set amount of times + SetTask_Repeat, // Loop indefinitely until timer is stopped + SetTask_AfterMapStart, // Time interval is treated as absolute time after map start + SetTask_BeforeMapChange // Time interval is treated as absolute time before map change +}; + +/** + * RegisterEventFlags constants for register_event_ex() + */ +enum RegisterEventFlags (<<= 1) +{ + RegisterEvent_None = 0, // None + RegisterEvent_Global = 1, // Global event (sent to every client) + RegisterEvent_Single, // Event sent to single client + RegisterEvent_OnceForMultiple, // Call only once when repeated to multiple clients + RegisterEvent_OnlyDead, // Call only if sent to dead client + RegisterEvent_OnlyAlive, // Call only if sent to alive client + RegisterEvent_OnlyHuman, // Call only if sent to human client (RegisterEvent_Single required) + RegisterEvent_OnlyBots // Call only if sent to bot (RegisterEvent_Single required) +}; + +/** + * GetPlayerFlags constants for get_players_ex() + */ +enum GetPlayersFlags (<<= 1) +{ + GetPlayers_None = 0, // No filter (Default) + GetPlayers_ExcludeDead = 1, // Do not include dead clients + GetPlayers_ExcludeAlive, // Do not include alive clients + GetPlayers_ExcludeBots, // Do not include bots + GetPlayers_ExcludeHuman, // Do not include human clients + GetPlayers_MatchTeam, // Match with team + GetPlayers_MatchNameSubstring, // Match with part of name + GetPlayers_CaseInsensitive, // Match case insensitive + GetPlayers_ExcludeHLTV, // Do not include HLTV proxies + GetPlayers_IncludeConnecting // Include connecting clients +}; + +/** + * FindPlayerFlags constants for find_player_ex() + */ +enum FindPlayerFlags (<<= 1) +{ + FindPlayer_None = 0, // None + FindPlayer_MatchName = 1, // Match with name + FindPlayer_MatchNameSubstring, // Match with name substring + FindPlayer_MatchAuthId, // Match with authid + FindPlayer_MatchIP, // Match with ip + FindPlayer_MatchTeam, // Match with team name + FindPlayer_ExcludeDead, // Do not include dead clients + FindPlayer_ExcludeAlive, // Do not include alive clients + FindPlayer_ExcludeBots, // Do not include bots + FindPlayer_ExcludeHuman, // Do not include human clients + FindPlayer_LastMatched, // Return last matched client instead of the first + FindPlayer_MatchUserId, // Match with userid + FindPlayer_CaseInsensitive, // Match case insensitively + FindPlayer_IncludeConnecting // Include connecting clients +} + +/** + * Constants for client statistics + */ +enum +{ + STATSX_KILLS = 0, + STATSX_DEATHS, + STATSX_HEADSHOTS, + STATSX_TEAMKILLS, + STATSX_SHOTS, + STATSX_HITS, + STATSX_DAMAGE, + STATSX_RANK, + STATSX_MAX_STATS +} + +/** + * Constants for get_user_origin() + */ +enum +{ + Origin_Client = 0, // Client's Origin + Origin_Eyes, // Eyes (and Weapon) Origin + Origin_AimEndClient, // Aim End Origin from Client's Position + Origin_AimEndEyes, // Aim End Origin from Eyes Position + Origin_CS_LastBullet // Last Bullet's Origin (Counter-Strike) +} + +#include // To keep backward compatibility diff --git a/amxmodx/scripting/include/amxmisc.inc b/amxmodx/scripting/include/amxmisc.inc new file mode 100644 index 0000000..2510afe --- /dev/null +++ b/amxmodx/scripting/include/amxmisc.inc @@ -0,0 +1,895 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _amxmisc_included + #endinput +#endif +#define _amxmisc_included + +#if !defined _amxmodx_included + #include +#endif + +/** + * Returns if the client has any admin flags set + * + * @param id Client index + * + * @return 1 if client has any admin flags, 0 otherwise + */ +stock is_user_admin(id) +{ + new __flags = get_user_flags(id); + return (__flags > 0 && !(__flags & ADMIN_USER)); +} + +/** + * Returns if the user can execute the current command by checking the necessary + * admin flags and parameter count. Displays a denied access message to the user + * if missing privileges or a usage example if too few parameters are provided. + * + * @note This should be used inside of a command forward as it uses read_argc() + * to check the parameter count. + * + * @param id Client index + * @param level Required admin flags + * @param cid Command id + * @param num Required number of parameters + * @param acesssilent If true no denied access message will be printed + * + * @return 1 if access granted and parameters provided, 0 otherwise + */ +stock cmd_access(id, level, cid, num, bool:accesssilent = false) +{ + new has_access = 0; + if (id == (is_dedicated_server() ? 0 : 1)) + { + has_access = 1; + } + else if (level == ADMIN_ADMIN) + { + if (is_user_admin(id)) + { + has_access = 1; + } + } + else if (get_user_flags(id) & level) + { + has_access = 1; + } + else if (level == ADMIN_ALL) + { + has_access = 1; + } + + if (has_access == 0) + { + if (!accesssilent) + { + console_print(id, "%L", id, "NO_ACC_COM"); + } + return 0; + } + if (read_argc() < num) + { + new hcmd[32], hinfo[128], hflag, bool:info_ml; + get_concmd(cid, hcmd, charsmax(hcmd), hflag, hinfo, charsmax(hinfo), level, _, info_ml); + + if (info_ml) + { + LookupLangKey(hinfo, charsmax(hinfo), hinfo, id); + } + + console_print(id, "%L: %s %s", id, "USAGE", hcmd, hinfo); + return 0; + } + + return 1; +} + +/** + * Returns if the client has the specified admin flags. + * + * @param id Client index + * @param level Required admin flags + * + * @return 1 if client has the admin flags, 0 otherwise + */ +stock access(id, level) +{ + if (level == ADMIN_ADMIN) + { + return is_user_admin(id); + } + else if (level == ADMIN_ALL) + { + return 1; + } + + return (get_user_flags(id) & level); +} + +/** + * cmd_target flags + */ +#define CMDTARGET_OBEY_IMMUNITY (1<<0) // Obey immunity +#define CMDTARGET_ALLOW_SELF (1<<1) // Allow self targeting +#define CMDTARGET_ONLY_ALIVE (1<<2) // Target must be alive +#define CMDTARGET_NO_BOTS (1<<3) // Target can't be a bot + +/** + * Processes a generic target pattern and tries to match it to a client based + * on filtering flags. If no unique target is found an appropriate message is + * displayed to the admin. + * + * @note The pattern is first matched case insensitively against client names. + * If no match is found it is matched against client authids. If still no + * match is found and the pattern starts with '#' it is finally matched + * against client userids. + * @note Since client names are matched by substring the pattern can potentially + * match multiple targets. In that case the function will return 0 and ask + * the admin to provide a unique pattern. + * @note The filtering flags are applied after the pattern matching has + * finished. That means the pattern has to be unique against all clients + * on the server even if some of them are not eligible. + * + * @param id Client index of admin performing an action + * @param arg Target pattern + * @param flags Filtering flags, see CMDTARGET_* constants above + * + * @return Client index, or 0 if no or multiple clients matched + */ +stock cmd_target(id, const arg[], flags = CMDTARGET_OBEY_IMMUNITY) +{ + new player = find_player("bl", arg); + if (player) + { + if (player != find_player("blj", arg)) + { + console_print(id, "%L", id, "MORE_CL_MATCHT"); + return 0; + } + } + else if ((player = find_player("c", arg)) == 0 && arg[0] == '#' && arg[1]) + { + player = find_player("k", str_to_num(arg[1])); + } + if (!player) + { + console_print(id, "%L", id, "CL_NOT_FOUND"); + return 0; + } + if (flags & CMDTARGET_OBEY_IMMUNITY) + { + if ((get_user_flags(player) & ADMIN_IMMUNITY) && ((flags & CMDTARGET_ALLOW_SELF) ? (id != player) : true)) + { + new imname[MAX_NAME_LENGTH]; + get_user_name(player, imname, charsmax(imname)); + console_print(id, "%L", id, "CLIENT_IMM", imname); + return 0; + } + } + if (flags & CMDTARGET_ONLY_ALIVE) + { + if (!is_user_alive(player)) + { + new imname[MAX_NAME_LENGTH]; + get_user_name(player, imname, charsmax(imname)); + console_print(id, "%L", id, "CANT_PERF_DEAD", imname); + return 0; + } + } + if (flags & CMDTARGET_NO_BOTS) + { + if (is_user_bot(player)) + { + new imname[MAX_NAME_LENGTH]; + get_user_name(player, imname, charsmax(imname)); + console_print(id, "%L", id, "CANT_PERF_BOT", imname); + return 0; + } + } + + return player; +} + +/** + * Standard method to show admin activity to clients connected to the server. + * This depends on the amx_show_activity cvar. See documentation for more details. + * + * @param id Client index performing the action + * @param name Name of client performing the action + * @param fmt Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + */ +stock show_activity(id, const name[], const fmt[], any:...) +{ + static __amx_show_activity; + if (__amx_show_activity == 0) + { + __amx_show_activity = get_cvar_pointer("amx_show_activity"); + + // if still not found, then register the cvar as a dummy + if (__amx_show_activity == 0) + { + __amx_show_activity = register_cvar("amx_show_activity", "2", FCVAR_PROTECTED); + } + } + + new prefix[10]; + if (is_user_admin(id)) + { + copy(prefix, charsmax(prefix), "ADMIN"); + } + else + { + copy(prefix, charsmax(prefix), "PLAYER"); + } + new buffer[512]; + vformat(buffer, charsmax(buffer), fmt, 4); + + switch (get_pcvar_num(__amx_show_activity)) + { + case 5: // hide name only to admins, show nothing to normal users + { + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i)) + { + if (is_user_admin(i)) + { + client_print(i, print_chat, "%L: %s", i, prefix, buffer); + } + } + } + } + case 4: // show name only to admins, show nothing to normal users + { + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i)) + { + if (is_user_admin(i)) + { + client_print(i, print_chat, "%L %s: %s", i, prefix, name, buffer); + } + } + } + } + case 3: // show name only to admins, hide name from normal users + { + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i)) + { + if (is_user_admin(i)) + { + client_print(i, print_chat, "%L %s: %s", i, prefix, name, buffer); + } + else + { + client_print(i, print_chat, "%L: %s", i, prefix, buffer); + } + } + } + } + case 2: // show name to all + { + client_print(0, print_chat, "%L %s: %s", LANG_PLAYER, prefix , name , buffer); + } + case 1: // hide name to all + { + client_print(0, print_chat, "%L: %s", LANG_PLAYER, prefix, buffer); + } + } +} + +/** + * Standard method to show admin activity to a single client. + * This depends on the amx_show_activity cvar. See documentation for more details. + * + * @param idtarget Client index to display message to + * @param id Client index performing the action + * @param name Name of client performing the action + * @param fmt Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + */ +stock show_activity_id(idtarget, idadmin, const name[], const fmt[], any:...) +{ + if (idtarget == 0 || !is_user_connected(idtarget)) + { + return; + } + + static __amx_show_activity; + if (__amx_show_activity == 0) + { + __amx_show_activity = get_cvar_pointer("amx_show_activity"); + + // if still not found, then register the cvar as a dummy + if (__amx_show_activity == 0) + { + __amx_show_activity = register_cvar("amx_show_activity", "2", FCVAR_PROTECTED); + } + } + + static prefix[10]; + if (is_user_admin(idadmin)) + { + copy(prefix, charsmax(prefix), "ADMIN"); + } + else + { + copy(prefix, charsmax(prefix), "PLAYER"); + } + + static buffer[512]; + vformat(buffer, charsmax(buffer), fmt, 5); + + switch (get_pcvar_num(__amx_show_activity)) + { + case 5: // hide name only to admins, show nothing to normal users + { + if (is_user_admin(idtarget)) + { + client_print(idtarget, print_chat, "%L: %s", idtarget, prefix, buffer); + } + } + case 4: // show name only to admins, show nothing to normal users + { + if (is_user_admin(idtarget)) + { + client_print(idtarget, print_chat, "%L %s: %s", idtarget, prefix, name, buffer); + } + } + case 3: // show name only to admins, hide name from normal users + { + if (is_user_admin(idtarget)) + { + client_print(idtarget, print_chat, "%L %s: %s", idtarget, prefix, name, buffer); + } + else + { + client_print(idtarget, print_chat, "%L: %s", idtarget, prefix, buffer); + } + } + case 2: // show name to all + { + client_print(idtarget, print_chat, "%L %s: %s", idtarget, prefix, name, buffer); + } + case 1: // hide name to all + { + client_print(idtarget, print_chat, "%L: %s", idtarget, prefix, buffer); + } + } +} + +/** + * Standard method to show activity to one single client with normal language keys. + * These keys need to be in the format of standard AMXX keys: + * eg: ADMIN_KICK_1 = ADMIN: kick %s + * ADMIN_KICK_2 = ADMIN %s: kick %s + * This depends on the amx_show_activity cvar. See documentation for more details. + * + * @param KeyWithoutName The language key that does not have the name field. + * @param KeyWithName The language key that does have the name field. + * @param __AdminName The name of the person doing the action. + * @extra Pass any extra format arguments for the language key in the variable arguments list. + * + * @noreturn + */ +stock show_activity_key(const KeyWithoutName[], const KeyWithName[], const ___AdminName[], any:...) +{ +// The variable gets used via vformat, but the compiler doesn't know that, so it still cries. +#pragma unused ___AdminName + static __amx_show_activity; + if (__amx_show_activity == 0) + { + __amx_show_activity = get_cvar_pointer("amx_show_activity"); + + // if still not found, then register the cvar as a dummy + if (__amx_show_activity == 0) + { + __amx_show_activity = register_cvar("amx_show_activity", "2", FCVAR_PROTECTED); + } + } + + new buffer[512]; + new keyfmt[256]; + new i; + + switch (get_pcvar_num(__amx_show_activity)) + { + case 5: // hide name to admins, display nothing to normal players + { + while (i++ < MaxClients) + { + if (is_user_connected(i)) + { + if (is_user_admin(i)) + { + LookupLangKey(keyfmt, charsmax(keyfmt), KeyWithoutName, i); + + // skip the "adminname" argument if not showing name + vformat(buffer, charsmax(buffer), keyfmt, 4); + client_print(i, print_chat, "%s", buffer); + } + } + } + } + case 4: // show name only to admins, display nothing to normal players + { + while (i++ < MaxClients) + { + if (is_user_connected(i)) + { + if (is_user_admin(i)) + { + LookupLangKey(keyfmt, charsmax(keyfmt), KeyWithName, i); + vformat(buffer, charsmax(buffer), keyfmt, 3); + client_print(i, print_chat, "%s", buffer); + } + } + } + } + case 3: // show name only to admins, hide name from normal users + { + while (i++ < MaxClients) + { + if (is_user_connected(i)) + { + if (is_user_admin(i)) + { + LookupLangKey(keyfmt, charsmax(keyfmt), KeyWithName, i); + vformat(buffer, charsmax(buffer), keyfmt, 3); + } + else + { + LookupLangKey(keyfmt, charsmax(keyfmt), KeyWithoutName, i); + + // skip the "adminname" argument if not showing name + vformat(buffer, charsmax(buffer), keyfmt, 4); + } + client_print(i, print_chat, "%s", buffer); + } + } + } + case 2: // show name to all users + { + while (i++ < MaxClients) + { + if (is_user_connected(i)) + { + LookupLangKey(keyfmt, charsmax(keyfmt), KeyWithName, i); + vformat(buffer, charsmax(buffer), keyfmt, 3); + client_print(i, print_chat, "%s", buffer); + } + } + } + case 1: // hide name from all users + { + while (i++ < MaxClients) + { + if (is_user_connected(i)) + { + LookupLangKey(keyfmt, charsmax(keyfmt), KeyWithoutName, i); + + // skip the "adminname" argument if not showing name + vformat(buffer, charsmax(buffer), keyfmt, 4); + client_print(i, print_chat, "%s", buffer); + } + } + } + } +} + +/** + * Returns if the mod running on the server supports colored menus. + * + * @note The full list of mods supporting colored menus: + * Counter-Strike, Counter-Strike: Condition Zero, Deathmatch Classic, + * Day of Defeat, Team Fortress Classic and Half-Life: Deathmatch. + * @note Since this is a stock and compiled into the plugin, the list of + * supported mods will not update and require recompilation of the plugin + * if the list ever changed. + * + * @return 1 if colored menus are supported, 0 otherwise + */ +stock colored_menus() +{ + static ColoredMenus = -1; + + if (ColoredMenus == -1) + { + new const ModNames[][] = { "cstrike", "czero", "dmc", "dod", "tfc", "valve" }; + new ModName[32]; + + get_modname(ModName, charsmax(ModName)); + + for (new Iterator = 0; Iterator < sizeof(ModNames); Iterator++) + { + if (equal(ModName, ModNames[Iterator])) + { + ColoredMenus = 1; + + break; + } + } + + if (ColoredMenus == -1) + ColoredMenus = 0; + } + + return ColoredMenus; +} + +/** + * Returns if the mod running on the server is a version of Counter-Strike. + * + * @return 1 if mod is Counter-Strike, 0 otherwise + */ +stock cstrike_running() +{ + new mod_name[32]; + get_modname(mod_name, charsmax(mod_name)); + + return (equal(mod_name, "cstrike") || equal(mod_name, "czero") || equal(mod_name, "csv15") || equal(mod_name, "cs13")); +} + +/** + * Returns if the server is running a specific mod. + * + * @param mod Mod name to check for + * + * @return 1 if mod name matches, 0 otherwise + */ +stock is_running(const mod[]) +{ + new mod_name[32]; + get_modname(mod_name, charsmax(mod_name)); + + return equal(mod_name, mod); +} + +/** + * Retrieves the path to the AMXX base directory. + * + * @param name Buffer to copy path to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +stock get_basedir(name[], len) +{ + return get_localinfo("amxx_basedir", name, len); +} + +/** + * Retrieves the path to the AMXX configs directory. + * + * @param name Buffer to copy path to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +stock get_configsdir(name[], len) +{ + return get_localinfo("amxx_configsdir", name, len); +} + +/** + * Retrieves the path to the AMXX data directory. + * + * @param name Buffer to copy path to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +stock get_datadir(name[], len) +{ + return get_localinfo("amxx_datadir", name, len); +} + +/** + * Provides a shorthand to register a working menu. + * + * @note Combines the necessary calls to register_menuid() and + * register_menucmd() into a single function. + * + * @param title Menu name + * @param keys Key flags + * @param function Callback function + * @param outside Catch menus outside the calling plugin + * + * @noreturn + * @error If an invalid callback function is specified, an error will + * be thrown. + */ +stock register_menu(const title[], keys, const function[], outside = 0) +{ + register_menucmd(register_menuid(title, outside), keys, function); +} + +/** + * Alias to get_configsdir provided for backwards compatibility. Originally + * intended to retrieve the AMXX custom directory. + * + * @deprecated Should not be used as the concept of a custom directory does no + * longer exists in AMXX. + * + * @param name Buffer to copy path to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +#pragma deprecated The concept of a custom directory no longer exists in AMXX. Do not use. +stock get_customdir(name[], len) +{ + return get_configsdir(name, len); +} + +/** + * Adds a menu item/command to the admin menu (amxmodmenu) handled by the + * "Menus Front-End" plugin, if it is loaded. + * + * @param MENU_TEXT Item text that will be displayed in the menu + * @param MENU_CMD Command that will be executed on the client + * @param MENU_ACCESS Admin access required for menu command + * @param MENU_PLUGIN Case-insensitive name or filename of plugin providing + * the menu command + * + * @noreturn + */ +stock AddMenuItem(const MENU_TEXT[], const MENU_CMD[], const MENU_ACCESS, const MENU_PLUGIN[]) +{ + AddMenuItem_call(MENU_TEXT, MENU_CMD, MENU_ACCESS, MENU_PLUGIN, false); +} + +/** + * Adds a menu item/command to the client menu (amx_menu) handled by the + * "Menus Front-End" plugin, if it is loaded. Items should be accessible by + * non-admins. + * + * @param MENU_TEXT Item text that will be displayed in the menu + * @param MENU_CMD Command that will be executed on the client + * @param MENU_ACCESS Admin access required for menu command + * @param MENU_PLUGIN Case-insensitive name or filename of plugin providing + * the menu command + * + * @noreturn + */ +stock AddClientMenuItem(const MENU_TEXT[], const MENU_CMD[], const MENU_ACCESS, const MENU_PLUGIN[]) +{ + AddMenuItem_call(MENU_TEXT, MENU_CMD, MENU_ACCESS, MENU_PLUGIN, true); +} + +/** + * Helper function used by AddMenuItem() and AddClientMenuItem() + * + * @param MENU_TEXT Item text that will be displayed in the menu + * @param MENU_CMD Command that will be executed on the client + * @param MENU_ACCESS Admin access required for menu command + * @param MENU_PLUGIN Case-insensitive name or filename of plugin + * providing the menu command + * @param ADD_TO_CLIENT_MENU If true adds command to client menu, false adds + * to admin menu + * + * @noreturn + */ +stock AddMenuItem_call(const MENU_TEXT[], const MENU_CMD[], const MENU_ACCESS, const MENU_PLUGIN[], const bool:ADD_TO_CLIENT_MENU) +{ + new pluginid = is_plugin_loaded("Menus Front-End"); + if (pluginid == -1) + { + log_amx("Can't add menu item ^"%s^" from plugin ^"%s^" to menu set because the Menus Front-End plugin itself is not loaded!", MENU_TEXT, MENU_PLUGIN); + return; // Menus Front-End doesn't exist, return. + } + + new filename[64], b[1]; + get_plugin(pluginid, filename, charsmax(filename), b, charsmax(b), b, charsmax(b), b, charsmax(b), b, charsmax(b)); + + new status = callfunc_begin(ADD_TO_CLIENT_MENU ? "AddClientMenu" : "AddMenu", filename); + new bool:failed = true; + switch (status) + { + case 1: + { + failed = false; + } + case 0: + { + log_amx("Run time error! (AddMenuItem_call failed)"); + } + case -2: + { + log_amx("Function not found! (AddMenuItem_call failed)"); + } + case -1: + { + log_amx("Plugin not found! (AddMenuItem_call failed)"); + } + } + if (failed) + { + return; + } + // Item text + callfunc_push_str(MENU_TEXT); + // Cmd + callfunc_push_str(MENU_CMD); + // Access + callfunc_push_int(MENU_ACCESS); + // Menu exists in this plugin + callfunc_push_str(MENU_PLUGIN); + + callfunc_end(); +} + +/** + * Computes an offset from a given value while constraining it between the + * specified bounds, rolling over if necessary. + * + * @note Example: The range is 1-5 and the base value (seed) is 3, the offset + * that the value should be moved by is also 3. Offsetting the value by 3 + * would result in 6, but it is to be constrained between 1 and 5. With + * clamp() this would result in 5, but this function rolls the value over + * and returns 1 instead. + * + * @param low Lower bound + * @param high Higher bound + * @param seed Base value + * @param offset Offset to move + * + * @return Computed offset value between specified bounds + */ +stock constraint_offset(low, high, seed, offset) +{ + new numElements = high - low + 1; + offset += seed - low; + + if (offset >= 0) + { + return low + (offset % numElements); + } + + return high - (abs(offset) % numElements) + 1; +} + +/** + * Returns if the client has any of the specified admin flags. + * + * @param id Client index + * @param flags Flag string + * + * @return 1 if the user has any of the specified flags, 0 otherwise + */ +stock has_flag(id, const flags[]) +{ + return (get_user_flags(id) & read_flags(flags)); +} + +/** + * Returns if the client has all of the specified admin flags. + * + * @param id Client index + * @param flags Flag string + * + * @return 1 if the user has all of the specified flags, 0 otherwise + */ +stock has_all_flags(id, const flags[]) +{ + new FlagsNumber = read_flags(flags); + return ((get_user_flags(id) & FlagsNumber) == FlagsNumber); +} + +/** + * Resets the client's menu. + * + * @note This is a wrapper around show_menu() for the sake of readability. + * + * @param index Client to reset menu of, 0 to reset all clients + * + * @noreturn + */ +stock reset_menu(index) +{ + show_menu(index, 0, "", 0); +} + +/** + * Calls a function after a specified time has elapsed. + * + * @param time Time interval to assign + * @param function Function to execute + * @param id Task id to assign + * @param parameter Data to pass through to callback + * @param len Size of data + * @param flags Optional flags (enum SetTaskFlags); valid flags are: + * SetTask_Once - Execute callback once (Default) + * SetTask_RepeatTimes - repeat timer a set amount of times + * SetTask_Repeat - loop indefinitely until timer is stopped + * SetTask_AfterMapStart - time interval is treated as absolute + * time after map start + * SetTask_BeforeMapChange - time interval is treated as absolute + * time before map change + * @param repeat If the SetTask_RepeatTimes flag is set, the task will be repeated this + * many times + * + * @noreturn + * @error If an invalid callback function is provided, an error is + * thrown. + */ +stock set_task_ex(Float:time, const function[], id = 0, const any:parameter[] = "", len = 0, SetTaskFlags:flags = SetTask_Once, repeat = 0) +{ + new strFlags[2]; // There should never be a need to set more than 1 flag + get_flags(_:flags, strFlags, charsmax(strFlags)); + set_task(time, function, id, parameter, len, strFlags, repeat); +} + +/** + * Stores a filtered list of client indexes to an array. + * + * @note Example retrieving all alive CTs: + * get_players_ex(players, num, GetPlayers_ExcludeDead | GetPlayers_MatchTeam, "CT") + * + * @param players Array to store indexes to + * @param num Variable to store number of indexes to + * @param flags Optional filtering flags (enum GetPlayersFlags); valid flags are: + * GetPlayers_None - No filter (Default) + * GetPlayers_ExcludeDead - do not include dead clients + * GetPlayers_ExcludeAlive - do not include alive clients + * GetPlayers_ExcludeBots - do not include bots + * GetPlayers_ExcludeHuman - do not include human clients + * GetPlayers_MatchTeam - match with team + * GetPlayers_MatchNameSubstring - match with part of name + * GetPlayers_CaseInsensitive - match case insensitive + * GetPlayers_ExcludeHLTV - do not include HLTV proxies + * GetPlayers_IncludeConnecting - include connecting clients + * @param team String to match against if the "e" or "f" flag is specified + * + * @noreturn + */ +stock get_players_ex(players[MAX_PLAYERS] = {}, &num, GetPlayersFlags:flags = GetPlayers_None, const team[] = "") +{ + new strFlags[10]; + get_flags(_:flags, strFlags, charsmax(strFlags)); + get_players(players, num, strFlags, team); +} + +/** + * Returns the number of clients on the server that match the specified flags. + * + * @note Example retrieving all alive CTs: + * new AliveCt = get_playersnum_ex(GetPlayers_ExcludeDead | GetPlayers_MatchTeam, "CT") + * + * @param flags Optional filtering flags (enum GetPlayersFlags); valid flags are: + * GetPlayers_None - No filter (Default) + * GetPlayers_ExcludeDead - do not include dead clients + * GetPlayers_ExcludeAlive - do not include alive clients + * GetPlayers_ExcludeBots - do not include bots + * GetPlayers_ExcludeHuman - do not include human clients + * GetPlayers_MatchTeam - match with team + * GetPlayers_MatchNameSubstring - match with part of name + * GetPlayers_CaseInsensitive - match case insensitive + * GetPlayers_ExcludeHLTV - do not include HLTV proxies + * GetPlayers_IncludeConnecting - include connecting clients + * @param team String to match against if the GetPlayers_MatchTeam or GetPlayers_MatchNameSubstring flag is specified + * + * @return Number of clients on the server that match the specified flags + */ +stock get_playersnum_ex(GetPlayersFlags:flags = GetPlayers_None, const team[] = "") +{ + new PlayersNum; + get_players_ex(_, PlayersNum, flags, team); + return PlayersNum; +} diff --git a/amxmodx/scripting/include/amxmodx.inc b/amxmodx/scripting/include/amxmodx.inc new file mode 100644 index 0000000..ed1f3ec --- /dev/null +++ b/amxmodx/scripting/include/amxmodx.inc @@ -0,0 +1,3438 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _amxmodx_included + #endinput +#endif +#define _amxmodx_included + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Called just after server activation. + * + * @note Good place to initialize most of the plugin, such as registering + * cvars, commands or forwards, creating data structures for later use, or + * generating and loading other required configurations. + * + * @noreturn + */ +forward plugin_init(); + +/** + * Called just before the plugin is paused from execution. + * + * @noreturn + */ +forward plugin_pause(); + +/** + * Called just after the plugin is unpaused. + * + * @noreturn + */ +forward plugin_unpause(); + +/** + * Called when the mod tries to change the map. + * + * @note This is *only* called if the mod itself handles the map change. The + * server command "changelevel", which is used by many plugins, will not + * trigger this forward. Unfortunately, this means that in practice this + * forward can be unreliable and will not be called in many situations. + * @note AMXX 1.8.3 has added the engine_changelevel() function, which will utilize + * the correct engine function to change the map, and therefore trigger + * this forward. + * + * @param map Map that the mod tries to change to + * + * @return PLUGIN_CONTINUE to let the mod change the map + * PLUGIN_HANDLED or higher to prevent the map change + */ +forward server_changelevel(map[]); + +/** + * Called when all plugins went through plugin_init() + * + * @note When this forward is called, most plugins should have registered their + * cvars and commands already. + * + * @noreturn + */ +forward plugin_cfg(); + +/** + * Called just before server deactivation and subsequent unloading of the + * plugin. + * + * @note The plugin is required to manually free Handles it has acquired, such + * as those from dynamic data structures. Failing to do that will result + * in the plugin and AMXX leaking memory. + * + * @noreturn + */ +forward plugin_end(); + +/** + * Called when a message is about to be logged. + * + * @note Message data and information can be retrieved using the read_log* set + * of functions. + * + * @return PLUGIN_CONTINUE to let the log message through + * PLUGIN_HANDLED or higher to stop the log message + */ +forward plugin_log(); + +/** + * This forward allows plugins to add models, sounds and generic files to the + * precache tables using the precache_* set of functions. + * + * @note Adding files to the precaching tables will trigger the client to + * download them to its local filesystem. + * @note There is a hard upper limit of entries in the precaching tables for + * every game, this limit is 512 in most cases. The entries will be filled + * and indexed incrementally. Going over this limit will crash the server. + * + * @noreturn + */ +forward plugin_precache(); + +/** + * Called when a clients info has changed. + * + * @param id Client index + * + * @noreturn + */ +forward client_infochanged(id); + +/** + * Called when a client is connecting. + * + * @note This forward is called too early to do anything that directly affects + * the client. + * + * @param id Client index + * + * @noreturn + */ +forward client_connect(id); + +/** + * Called when a client is connecting. + * + * @note This forward is called too early to do anything that directly affects + * the client. + * + * @param id Client index + * @param name Client name + * @param ip Client ip address with port + * @param reason A reason that will be displayed when player gets rejected (can be overwritten) + * + * @return PLUGIN_CONTINUE to let a client join to the server + * PLUGIN_HANDLED or higher to prevent a client to join + */ +forward client_connectex(id, const name[], const ip[], reason[128]); + +/** + * Called when the client gets a valid SteamID. + * + * @note This may occur before or after client_putinserver has been called. + * @note This is called for bots, and the SteamID will be "BOT". + * + * @param id Client index + * @param authid Client auth + * + * @noreturn + */ +forward client_authorized(id, const authid[]); + +/** + * @deprecated This function does not catch all cases. + */ +#pragma deprecated Use client_disconnected() instead. +forward client_disconnect(id); + +/** + * Called when a client is disconnected from the server. + * + * @note This will be called in some additional cases that client_disconnect doesn't cover, + * most notably when a client aborts the connection process. It is guaranteed to pair + * with the client_connect() forward. + * @note When this fires the player entity is still valid (e.g. is_user_connected(id) will + * return true), but no networked commands will reach the client. + * + * @param id Client index + * @param drop If true, the game has explicitly dropped the client + * @param message If drop is true, a writable buffer containing the disconnect info message + * @param maxlen Maximum size of buffer + * + * @noreturn + */ +forward client_disconnected(id, bool:drop, message[], maxlen); + +/** + * Called when a client entity has been removed from the server. + * + * @note This fires after the client_disconnected() forward, when the player entity has been + * removed (e.g. is_user_connected(id) will return false). + * + * @param id Client index + * @param drop If true, the game has explicitly dropped the client + * @param message If drop is true, contains the disconnect info message + * + * @noreturn + */ +forward client_remove(id, bool:drop, const message[]); + + +/** + * Called when a client attempts to execute a command. + * + * @note The command and its arguments can be read using the read_arg* set of + * functions. + * + * @param id Client index + * + * @return PLUGIN_CONTINUE to let the client execute the command + * PLUGIN_HANDLED or higher to stop the command + */ +forward client_command(id); + +/** + * Called when a client is entering the game. + * + * @note It is not defined whether the client already has a SteamID when this + * forward is called. client_authorized may occur either before or after + * this. + * + * @param id Client index + * + * @noreturn + */ +forward client_putinserver(id); + +/** + * Sets informations about the calling plugin. + * + * @param plugin_name Name of the plugin + * @param version Version of the plugin + * @param author Author of the plugin + * @param url URL of the plugin + * @param description Description of the plugin + * + * @return Plugin id of the calling plugin + */ +native register_plugin(const plugin_name[], const version[], const author[], const url[] = "", const description[] = ""); + +/** + * Precaches a model file. + * + * @note Can only be used inside of the plugin_precache() forward. + * + * @param name Path to the model file + * + * @return Unique cache id of the model + * @error If called outside of the plugin_precache() forward, an error is + * thrown. + */ +native precache_model(const name[]); + +/** + * Precaches a sound file. + * + * @note Can only be used inside of the plugin_precache() forward. + * @note The filepath is always relative to the "sound" folder, and the file has + * to be a wav file. Precaching a file with this will add it to the engine + * sound table, making it available for usage in emit_sound() for example. + * @note Precaching other filetypes (such as mp3 music), optionally in different + * locations, has to be done with precache_generic() + * + * @param name Path to the sound file + * + * @return Unique cache id of the sound + * @error If called outside of the plugin_precache() forward, an error is + * thrown. + */ +native precache_sound(const name[]); + +/** + * Precaches a generic file. + * + * @note Can only be used inside of the plugin_precache() forward. + * @note Precaching sounds with this will not add them to the engine sound table. + * + * @param szFile Path to the file + * + * @return Unique cache id of the file + * @error If called outside of the plugin_precache() forward, an error + * is thrown. + */ +native precache_generic(const szFile[]); + +/** + * Precaches an event file. + * + * @note The event type should always be 1. + * @note Contrary to the other precache_* natives, this can be used outside of + * the plugin_precache() forward, e.g. in plugin_init() or plugin_cfg(). + * A bug in some clients makes this necessary, as plugin_precache() is + * called before the mod has precached its own, default event files. This + * can cause the event table to be misaligned on the client, leading to + * visual and audio bugs that are hard to diagnose. + * + * @param type Event type + * @param Name Formatting rules, path to the event file + * @param ... Variable number of formatting parameters + * + * @return Unique cache id of the event + */ +native precache_event(type, const Name[], any:...); + +/** + * Changes the map. + * + * @note This calls the pfnChangelLevel engine function. + * @note This has the same behavior as using the "changelevel" server command, + * but will also trigger the server_changelevel() forward in AMXX + * plugins. It will also notify any Metamod plugins that are hooking + * the pfnChangeLevel function. + * + * @param map Map name to change to + * + * @noreturn + */ +native engine_changelevel(const map[]); + +/** + * Sets info on the client. + * + * @param index Client index + * @param info Info key + * @param value New value + * + * @noreturn + * @error If the index is not within the range of 1 to MaxClients or + * the client is not connected, an error will be thrown. + */ +native set_user_info(index, const info[], const value[]); + +/** + * Gets info from the client. + * + * @param index Client index + * @param info Info key + * @param output Buffer to copy value to + * @param len Maximum size of the buffer + * + * @return Number of cells written to buffer + * @error If the index is not within the range of 1 to MaxClients or + * the client is not connected, an error will be thrown. + */ +native get_user_info(index, const info[], output[], len); + +/** + * Sets info on the server. + * + * @param info Info key + * @param value New value + * + * @noreturn + */ +native set_localinfo(const info[], const value[]); + +/** + * Gets info from the server. + * + * @param info Info key + * @param output Buffer to copy value to + * @param len Maximum size of the buffer + * + * @return Number of cells written to buffer + */ +native get_localinfo(const info[], output[], len); + +/** + * Shows text or a file in MOTD window. + * + * @param player Client index, use 0 to display to all clients + * @param message Message to display inside the MOTD window, if this is a + * filename the contents of this file will be displayed + * @param header Text for the MOTD header, if empty the servers hostname will + * be displayed instead + * + * @noreturn + */ +native show_motd(player, const message[], const header[] = ""); + +/** + * Sends a message to the client. + * + * @note This functions return value behaves differently depending on what is + * used as the client index: If 0 is specified, then the function will + * return 0 if nothing has been sent (no client connected). If either a + * single client is specified or there is at least one client connected, + * the number of printed characters will refer to the message that is sent + * last, to the client with the highest index. + * + * @param index Client index, use 0 to display to all clients + * @param type Message type, see print_* destination constants in + * amxconst.inc + * @param message Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native client_print(index, type, const message[], any:...); + +/** + * Sends colored chat messages to clients. + * + * @note This only works in Counter-Strike 1.6 and Condition Zero. + * @note The colors can be modified inside of the format string using special + * characters. These characters can be included using the escape character + * green x04 ; use location color from this point forward + * red/blue/grey x03 ; use team color from this point forward + * red/blue/grey x02 ; use team color to the end of the client name + * ; This only works at the start of the string, + * ; and precludes using other control characters + * default x01 ; use default color from this point forward + * @note The team color is defined by the sender's index. Alternatively, a + * specific team color can be enforced using the print_team_* constants in + * amxconst.inc + * @note Usage examples: + * client_print_color(id, print_team_red, "^4Green ^3Red ^1Default") + * client_print_color(id, id2, "^4Green ^3id2's team color, ^1Default") + * @note Including colors in ML can be done using the same escaping method: + * EXAMPLE_ML_KEY = ^4Green ^3Team color ^1Default + * @note This functions return value behaves differently depending on what is + * used as the client index: If 0 is specified, then the function will + * return 0 if nothing has been sent (no client connected). If either a + * single client is specified, or there is at least one client connected, + * the number of printed characters will refer to the message that is sent + * last, to the client with the highest index. + * + * @param index Client index, use 0 to display to all clients + * @param sender Client index used as the message sender + * @param fmt Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native client_print_color(index, sender, const message[], any:...); + +/** + * Sends a message to the client via the engine. + * + * @note This functions return value behaves differently depending on what is + * used as the client index: If 0 is specified, then the function will + * return 0 if nothing has been sent (no client connected). If either a + * single client is specified, or there is at least one client connected, + * the number of printed characters will refer to the message that is sent + * last, to the client with the highest index. + * + * @param player Client index, use 0 to display to all clients + * @param type Message type, see engprint_* destination constants in + * amxconst.inc + * @param message Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native engclient_print(player, type, const message[], any:...); + +/** + * Sends a message to the console of a client or the server. + * + * @param index Client index, or 0 to print to the server console + * @param message Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native console_print(id, const message[], any:...); + +/** + * Executes a command from the specified client or the server console. + * + * @param id Client index, or 0 to execute from the server console + * @param cmd Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Length of the formatted command + */ +native console_cmd(id, const cmd[], any:...); + +/** + * Registers a function to be called on a given game event. + * + * @note Please consider using register_event_ex() instead which allows you to + * use named constants for flags instead of letters. + * @note Examples for event conditions: + * "2=c4" - Second parameter of message must be the string "c4" + * "3>10" - Third parameter of message must be greater than 10 + * "3!4" - Third parameter of message must not be equal to 4 + * "2&Buy" - Second parameter of message must contain "Buy" substring + * "2!Buy" - Second parameter of message must not equal "Buy" + * @note Due to a long-standing bug that would break compatibility with older + * plugins, the client id should be checked for alive/dead state if using + * flags "d" or "e". + * @note If multiple conditions are specified for a single parameter, only one + * of them has to hold true for the event function to be called. + * + * @param event Name of event that should be hooked + * @param function Name of callback function + * @param flags Flags used for filtering events, the valid flags are: + * "a" - Global event (sent to every client) + * "b" - Event sent to single client + * "c" - Call only once when repeated to multiple clients + * "d" - Call only if sent to dead client + * "e" - Call only if sent to alive client + * "f" - Call only if sent to human client ("b" flag required) + * "g" - Call only if sent to bot ("b" flag required) + * @param cond Condition string used for filtering events, built as: + * "" + * Argument number is the argument position to be filtered + * The comparison operator may be: + * - "=" for equality comparison (all argument types) + * - "!" for inequality comparison (all argument types) + * - "&" for bitwise and (int argument) or substring + * comparison (string argument) + * - "<" for less than comparison (int/float arguments) + * - ">" for greater than comparison (int/float arguments) + * The argument is compared to the specified value accordingly + * @param ... Any number of additional conditions + * + * @return Event handle + * @error If an invalid event name or callback function is provided, + * an error will be thrown. + */ +native register_event(const event[], const function[], const flags[], const cond[] = "", ...); + +/** + * Registers a function to be called on a given game event. + * + * @note Examples for event conditions: + * "2=c4" - Second parameter of message must be the string "c4" + * "3>10" - Third parameter of message must be greater than 10 + * "3!4" - Third parameter of message must not be equal to 4 + * "2&Buy" - Second parameter of message must contain "Buy" substring + * "2!Buy" - Second parameter of message must not equal "Buy" + * @note Due to a long-standing bug that would break compatibility with older + * plugins, the client id should be checked for alive/dead state if using + * flags "d" or "e". + * @note If multiple conditions are specified for a single parameter, only one + * of them has to hold true for the event function to be called. + * + * @param event Name of event that should be hooked + * @param function Name of callback function + * @param flags Flags used for filtering events (enum RegisterEventFlags); the valid flags are: + * RegisterEvent_Global - Global event (sent to every client) + * RegisterEvent_Single - Event sent to single client + * RegisterEvent_OnceForMultiple - Call only once when repeated to multiple clients + * RegisterEvent_OnlyDead - Call only if sent to dead client + * RegisterEvent_OnlyAlive - Call only if sent to alive client + * RegisterEvent_OnlyHuman - Call only if sent to human client (RegisterEvent_Single required) + * RegisterEvent_OnlyBots - Call only if sent to bot (RegisterEvent_Single required) + * @param cond Condition string used for filtering events, built as: + * "" + * Argument number is the argument position to be filtered + * The comparison operator may be: + * "=" for equality comparison (all argument types) + * "!" for inequality comparison (all argument types) + * "&" for bitwise and (int argument) or substring + * comparison (string argument) + * "<" for less than comparison (int/float arguments) + * ">" for greater than comparison (int/float arguments) + * The argument is compared to the specified value accordingly + * @param ... Any number of additional conditions + * + * @return Event handle + * @error If an invalid event name or callback function is provided, + * an error will be thrown. + */ +native register_event_ex(const event[], const function[], RegisterEventFlags:flags, const cond[] = "", ...); + +/** + * Enables a function hook of a game event which has been previously registered with register_event_ex(). + * + * @param handle Value returned from register_event() or register_event_ex() + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native enable_event(handle); + +/** + * Disables a function hook of a game event which has been previously registered with register_event_ex(). + * + * @param handle Value returned from register_event() or register_event_ex() + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native disable_event(handle); + +/** + * Registers a function to be called on a given log event. + * + * @note Examples for log conditions: + * "0 = World triggered" "1 = Game_Commencing" + * "1 = say" + * "3 = Terrorists_Win" + * "1 = entered the game" + * "0 = Server cvar" + * + * @param function Name of callback function + * @param argsnum Number of arguments of the log event + * @param ... Any number of conditions used for filtering events + * A condition string is built as: + * "" + * Argument number is the argument position to be filtered + * The comparison operator may be: + * - "=" for equality comparison + * - "&" for substring comparison + * The argument is compared to the specified string accordingly + * + * @return Log event handle + * @error If an invalid callback function is provided, an error will + * be thrown. + */ +native register_logevent(const function[], argsnum, ...); + +/** + * Enables a function hook of a game log event which has been previously registered with register_logevent(). + * + * @param handle Value returned from register_logevent() + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native enable_logevent(handle); + +/** + * Disables a function hook of a game log event which has been previously registered with register_logevent(). + * + * @param handle Value returned from register_logevent() + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native disable_logevent(handle); + +/** + * Sets display parameters for hudmessages. + * + * @note As of AMXX 1.61, setting the channel to -1 will automatically choose + * the next available HUD channel for the client. + * @note There are four different HUD channels available on the client (1-4). + * Sending a hudmessage to a channel will overwrite any existing messages + * already displaying on that channel. + * @note If you plan to create a permanent message, don't forget to specify a + * specific channel to avoid possible flickering due to auto-channeling. + * @note For the hudmessage coordinates x and y, -1.0 will center the message + * on the respective axis. + * @note These parameters stay until the next call to set_hudmessage overwrites + * them. Multiple calls to show_hudmessage will therefore re-use the same + * parameters. The parameters are not stored per-plugin, so other plugins + * can overwrite them. + * + * @param red Red component of hudmessage color + * @param green Green component of hudmessage color + * @param blue Blue component of hudmessage color + * @param x Location of the message on the x axis in percent + * @param y Location of the message on the y axis in percent + * @param effects Display effect + * @param fxtime Duration of the effect + * @param holdtime Time the message stays on screen + * @param fadeintime Time it takes the message to fully appear (fade-in) + * @param fadeouttime Time it takes the message to fully disappear (fade-out) + * @param channel Channel to use on the client + * + * @noreturn + */ +native set_hudmessage(red = 200, green = 100, blue = 0, Float:x = -1.0, Float:y = 0.35, effects = 0, Float:fxtime = 6.0, Float:holdtime = 12.0, Float:fadeintime = 0.1, Float:fadeouttime = 0.2, channel = -1); + +/** + * Displays a message on the client HUD. + * + * @note Use set_hudmessage to define how the message should look on screen. + * @note This functions return value behaves differently depending on what is + * used as the client index: If 0 is specified, then the function will + * return 0 if nothing has been sent (no client connected). If either a + * single client is specified, or there is at least one client connected, + * the number of printed characters will refer to the message that is sent + * last, to the client with the highest index. + * + * @param index Client index, use 0 to display to all clients + * @param message Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native show_hudmessage(index, const message[], any:...); + +/** + * Sets display parameters for director hudmessages. + * + * @note For the hudmessage coordinates x and y, -1.0 will center the message + * on the respective axis. + * @note These parameters stay until the next call to set_dhudmessage overwrites + * them. Multiple calls to show_dhudmessage will therefore re-use the same + * parameters. The parameters are not stored per-plugin, so other plugins + * can overwrite them. + * + * @param red Red component of hudmessage color + * @param green Green component of hudmessage color + * @param blue Blue component of hudmessage color + * @param x Location of the message on the x axis in percent + * @param y Location of the message on the y axis in percent + * @param effects Display effect + * @param fxtime Duration of the effect + * @param holdtime Time the message stays on screen + * @param fadeintime Time it takes the message to fully appear (fade-in) + * @param fadeouttime Time it takes the message to fully disappear (fade-out) + * + * @noreturn + */ +native set_dhudmessage(red = 200, green = 100, blue = 0, Float:x = -1.0, Float:y = 0.35, effects = 0, Float:fxtime = 6.0, Float:holdtime = 12.0, Float:fadeintime = 0.1, Float:fadeouttime = 0.2); + +/** + * Displays a director message on the client HUD. + * + * @note Use set_dhudmessage to define how the message should look on screen. + * @note Unlike the classic HUD message, which is channel-based, director + * messages are stack-based. You can have up to 8 messages displaying at + * once. If more are added, they will be overwritten in the order they were + * sent. There is no way to clear a specific message. + * @note The message has a maximum length of 128 characters which this function + * will automatically enforce. + * @note This functions return value behaves differently depending on what is + * used as the client index: If 0 is specified, then the function will + * return 0 if nothing has been sent (no client connected). If either a + * single client is specified, or there is at least one client connected, + * the number of printed characters will refer to the message that is sent + * last, to the client with the highest index. + * + * @param index Client index, use 0 to display to all clients + * @param message Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native show_dhudmessage(index, const message[], any:...); + +/** + * Displays a menu to the client. + * + * @note Keys is a bitflag value that represents which keys the user can press + * on the menu. If you want to display disabled menu options, or skip + * certain number slots, you should exclude that key from the bitflag. + * amxconst.inc provides MENU_KEY_* constants for convenience. + * @note The title parameter is not displayed to the client and is only used for + * identifying menus internally and assigning them to their callbacks. + * The title corresponds to the menu name that you register with + * register_menuid() + * + * @param index Client to display menu to, use 0 to display to all clients + * @param keys Enabled keys + * @param menu Menu body + * @param time Menu timeout in seconds, -1 to disable + * @param title Name of the menu for internal tracking purposes + * + * @return 1 on success, 0 if menu could not be displayed (client not + * connected) + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native show_menu(index, keys, const menu[], time = -1, const title[] = ""); + +/** + * Retrieves values from a client message. + * + * @note For use within callbacks registered with register_event_ex() + * @note Usage examples: + * value = read_data(1); + * read_data(2, floatvalue); + * written = read_data(3, buffer, buffersize); + * + * @param value Argument number to retrieve value from + * @param ... Changes the native's behavior depending on how many + * additional parameters are provided: + * 0 - Return the argument integer value directly + * 1 - Store the argument float value in the variable passed + * as the second parameter + * 2 - Copy the argument string value to the buffer provided + * in the second parameter, using the third as the + * maximum buffer size + * + * @return Changes depending on how many additional parameters are + * provided: + * 0 - Returns the argument integer value + * 1 - Returns the argument float value, converted + * (truncated) to an integer + * 2 - Returns the number of cells written to the buffer + */ +native read_data(value, any:...); + +/** + * Returns the number of values in the client message. + * + * @note For use within callbacks registered with register_event_ex() + * + * @return Number of values in client message + */ +native read_datanum(); + +/** + * Returns the message id of the client message. + * + * @note For use within callbacks registered with register_event_ex() + * + * @return Message id of the client message + */ +native read_datatype(); + +/** + * Retrieves current log message. + * + * @note Should only be used inside of the plugin_log() forward. + * + * @param output Buffer to copy log message to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native read_logdata(output[], len); + +/** + * Returns number of log message arguments. + * + * @note Should only be used inside of the plugin_log() forward. + * + * @return Number of arguments in the log message + */ +native read_logargc(); + +/** + * Retrieves argument of log message. + * + * @note Should only be used inside of the plugin_log() forward. + * + * @param id Argument index, starting from 0 + * @param output Buffer to copy log argument to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native read_logargv(id, output[], len); + +/** + * Parse log data about client. + * + * @note When client actions are logged, they appear in the the format + * "Name<#userid>", this native extracts the individual + * pieces of information. + * + * @param text String to process + * @param name Buffer to copy client name to + * @param nlen Maximum name buffer size + * @param userid Variable to store userid in + * @param authid Buffer to copy client authid to + * @param alen Maximum auth buffer size + * @param team Buffer to copy client team to + * @param tlen Maximum team buffer size + * + * @noreturn + * @error If the provided string is not valid client log data, an + * error will be thrown. + */ +native parse_loguser(const text[], name[], nlen, &userid =-2, authid[] = "", alen = 0, team[] = "", tlen = 0); + +/** + * Sends a message to the console of the server. + * + * @param message Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + */ +native server_print(const message[], any:...); + +/** + * Returns if the given mapname is deemed valid by the engine. + * + * @param mapname Name of the map + * + * @return 1 if the map name is valid, 0 otherwise + */ +native is_map_valid(const mapname[]); + +/** + * Returns if the client is a bot. + * + * @param index Client index + * + * @return 1 if client is a bot, 0 otherwise + */ +native is_user_bot(index); + +/** + * Returns if the client is a HLTV proxy. + * + * @param index Client index + * + * @return 1 if client is a HLTV proxy, 0 otherwise + */ +native is_user_hltv(index); + +/** + * Returns if the client is authorized. + * + * @note This does not throw an error if the provided index is out of the + * 1 to MaxClients range. That means you can safely use this native + * without manually verifying that the index is a valid client index. + * + * @param index Client index + * + * @return 1 if client is authorized, 0 otherwise + */ +native is_user_authorized(index); + +/** + * Returns if the client is connected. + * + * @note This does not throw an error if the provided index is out of the + * 1 to MaxClients range. That means you can safely use this native + * without manually verifying that the index is a valid client index. + * + * @param index Client index + * + * @return 1 if client is connected, 0 otherwise + */ +native is_user_connected(index); + +/** + * Returns if the client is connecting. + * + * @param index Client index + * + * @return 1 if client is connecting, 0 otherwise + */ +native is_user_connecting(index); + +/** + * Returns if the client is alive. + * + * @note This will never return true if a client is not connected. If you need + * to know whether a client is alive, an additional call to + * is_user_connected() is unnecessary. + * + * @param index Client index + * + * @return 1 if client is alive, 0 otherwise + */ +native is_user_alive(index); + +/** + * Returns if the server is a dedicated server. + * + * @return 1 if server is a dedicated server, 0 otherwise + */ +native is_dedicated_server(); + +/** + * Returns if the server is running on Linux. + * + * @return 1 if server is running on Linux, 0 otherwise + */ +native is_linux_server(); + +/** + * Returns if the AMXX installation has the JIT enabled. + * + * @return 1 if JIT is enabled, 0 otherwise + */ +native is_jit_enabled(); + +/** + * Retrieves the version string of the AMXX installation. + * + * @param buffer Buffer to copy version to + * @param length Maximum buffer size + * + * @return Number of cells written to the buffer + */ +native get_amxx_verstring(buffer[], length); + +/** + * Returns the last known attacker of a client. + * + * @note As of AMXX 1.75 this can return a non-client entity index if the client + * was attacked by a non-client entity. + * + * @param index Client index + * @param ... If provided, the attacker weapon will be stored in an + * optional second parameter, and the body hit place will be + * stored in an optional third parameter + * + * @return Attacker client index, a non-client entity or 0 if no + * attacker was found + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native get_user_attacker(index, ...); + +/** + * Traces the client's current aim vector to see if it hits something. + * + * @note If the trace does not hit a client, id and body will be set to 0. + * @note If the trace hits nothing within the specified distance, 0 is returned. + * @note For a list of possible body hitplaces see the HIT_* constants in amxconst.inc. + * + * @param index Client index to trace aim from + * @param id Variable to store hit client index (if applicable) + * @param body Variable to store hit client body part (if applicable) + * @param dist Maximum distance of the trace + * + * @return Distance between the trace start and end point + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native Float:get_user_aiming(index, &id, &body = HIT_GENERIC, dist = 9999); + +/** + * Returns the client's frags. + * + * @note While this is mod-independent, the mod may track frag count differently, + * so it can only be retrieved using another native or other methods. + * @note This will actually return the client's overall score, which may or may + * not be equal to their scored frags depending on the mod. + * + * @param index Client index + * + * @return Frags/Score of the client. Also returns 0 if the client is + * not connected or the index is not within the range of + * 1 to MaxClients + */ +native get_user_frags(index); + +/** + * Returns the client's armor value. + * + * @note While this is mod-independent, the mod may track armor data differently, + * so it can only be retrieved using another native or other methods. + * + * @param index Client index + * + * @return Amount of armor the client has. Also returns 0 if the client + * is not connected or the index is not within the range of + * 1 to MaxClients + */ +native get_user_armor(index); + +/** + * Returns the client's death count. + * + * @note While this is mod-independent, the mod may track death count differently, + * so it can only be retrieved using another native or other methods. + * + * @param index Client index + * + * @return Amount of deaths the client has. Also returns 0 if the + * client is not connected or the index is not within the range + * of 1 to MaxClients + */ +native get_user_deaths(index); + +/** + * Returns the client's health points. + * + * @note While this is mod-independent, the mod may track health points + * differently, so it can only be retrieved using another native or other + * methods. + * + * @param index Client index + * + * @return Amount of health points the client has. Also returns 0 if + * the client is not connected or the index is not within the + * range of 1 to MaxClients + */ +native get_user_health(index); + +/** + * Retrieves a client's index by name. + * + * @param name Name to search for + * + * @return Client index on success, 0 otherwise + */ +native get_user_index(const name[]); + +/** + * Retrieves the IP of a client or the server. + * + * @param index Client index, use 0 to retrieve the server IP + * @param ip Buffer to copy IP to + * @param len Maximum buffer size + * @param without_port Remove the port from the IP if nonzero + * + * @return Number of cells written to the buffer + */ +native get_user_ip(index, ip[], len, without_port = 0); + +/** + * Returns if the client has the specified weapon in their inventory. + * + * @param index Client index + * @param weapon Weapon index + * @param setweapon If zero the weapon bit will be removed from the client's + * inventory, if 1 it will be set + * + * @return 1 if the weapon is present, 0 if it is not + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native user_has_weapon(index, weapon, setweapon = -1); + +/** + * Returns weapon index of the currently carried weapon. Also allows retrieval + * of ammo in the clip and backpack. + * + * @param index Client index + * @param clip Optional variable to store clip ammo to + * @param ammo Optional variable to store backpack ammo to + * + * @return Weapon index on success or 0 if the client is not connected + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native get_user_weapon(index, &clip = 0, &ammo = 0); + +/** + * Retrieves ammo in the clip and backpack of the specified weapon. + * + * @param index Client index + * @param weapon Weapon index + * @param clip Variable to store clip ammo to + * @param ammo Variable to store backpack ammo to + * + * @return 1 on success or 0 if the client is not connected + * @error If the client index is not within the range of 1 to + * MaxClients or the weapon index is invalid, an error will + * be thrown. + */ +native get_user_ammo(index, weapon, &clip, &ammo); + +/** + * Converts an integer to a text string. + * + * @note The conversion algorithm is limited to a certain range of numbers, but + * is guaranteed to work correctly for all numbers from 0 to 999. Outside + * of that range, the conversion will result in an incorrect string, but + * will not fail. + * @note The conversion is to english text, there is no way to change this. + * + * @param num Integer to convert + * @param output Buffer to copy string to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native num_to_word(num, output[], len); + +/** + * Returns the team id of the client, and optionally retrieves the name of + * the team. + * + * @param index Client index + * @param team Buffer to copy team name to + * @param len Maximum size of buffer + * + * @return Team index on success, -1 if client index is invalid or + * the client is not connected + */ +native get_user_team(index, team[] = "", len = 0); + +/** + * Returns client's playing time in seconds. + * + * @param index Client index + * @param flag If nonzero, the result will not include the time it took + * the client to connect. + * + * @return Connection time in seconds, 0 if client index is invalid or + * client is not connected + */ +native get_user_time(index, flag = 0); + +/** + * Retrieves the ping and loss of a client. + * + * @param index Client index + * @param ping Variable to store ping in + * @param loss Variable to store loss in + * + * @return 1 on success, 0 if client index is invalid or the client + * is not connected + */ +native get_user_ping(index, &ping, &loss); + +/** + * Retrieves an origin related to the client. + * + * @note For a list of possible modes see the Origin_* constants in amxconst.inc. + * + * @param index Client index + * @param origin Array to store origin in + * @param mode What type of origin to retrieve: + * Origin_Client - current position + * Origin_Eyes - position of eyes (and weapon) + * Origin_AimEndClient - aim end position from client position + * Origin_AimEndEyes - aim end position from eyes (hit point for weapon) + * Origin_CS_LastBullet - position of last bullet hit (only for Counter-Strike) + * + * @return 1 on success, 0 if client is not connected + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native get_user_origin(index, origin[3], mode = 0); + +/** + * Retrieves all weapons in the client inventory, stores them in an array, and + * returns the inventory as a bitflag sum. + * + * @note Make sure that num has an initial value of 0 or the native will not + * work correctly. + * + * @param index Client index + * @param weapons Array to store weapon indexes in + * @param num Variable to store number of weapons in the inventory to + * + * @return Bitflag sum of weapon indexes, 0 if client is not connected + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native get_user_weapons(index, weapons[32], &num); + +/** + * Retrieves the full name of a weapon. + * + * @param id Weapon index + * @param weapon Buffer to copy name to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native get_weaponname(id, weapon[], len); + +/** + * Retrieves the name of a client or the server. + * + * @param index Client index, or 0 to retrieve the server hostname + * @param name Buffer to copy name to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native get_user_name(index, name[], len); + +/** + * Retrieves the SteamID of a client. + * + * @note The SteamID is only available once the client_authorized() forward has + * been called for the client. + * + * @param index Client index + * @param authid Buffer to copy auth to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native get_user_authid(index, authid[], len); + +/** + * Returns the userid of a client. + * + * @param index Client index + * + * @return Client userid, 0 if the userid is not available or the + * client index is invalid + */ +native get_user_userid(index); + +/** + * Slaps the client with specified power. Killing the client if applicable. + * + * @note This removes "power" amount of health from the client, performing + * a kill if they have no health left after the slap. + * @note The function will apply a velocity to the client that is independent + * of the slap power. The slap direction can be influenced by the third + * parameter. + * + * @param index Client index + * @param power Power of the slap + * @param rnddir If set to zero the player will be slapped along it's aim + * vector, otherwise the direction will be randomized + * + * @return 1 if user is alive and slap succeeded, 0 otherwise + */ +native user_slap(index, power, rnddir = 1); + +/** + * Kills a client. + * + * @param index Client index + * @param flag If nonzero, the death will not affect the client's score + * + * @return 1 on success, 0 if client index is invalid or the client + * is not connected + */ +native user_kill(index, flag = 0); + +/** + * Logs a message to the current AMXX log file. + * + * @note The message will automatically be tagged with the plugin's name and the + * log will include a timestamp with the message. + * + * @param string Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + */ +native log_amx(const string[], any:...); + +/** + * Logs a message to the current server log file. + * + * @note The log will include a timestamp with the message. + * + * @param string Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + */ +native log_message(const message[], any:...); + +/** + * Logs a message hookable by plugins to the current server log file. + * + * @note The log will include a timestamp with the message. + * @note The message can be hooked using "register_logevent". + * + * @param string Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + */ +native elog_message(const message[], any:...); + +/** + * Logs a message to the specified file + * + * @note The log will include a timestamp with the message. + * + * @param string Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + */ +native log_to_file(const file[], const message[], any:...); + +/** + * Returns the number of clients on the server. + * + * @param flag Count clients still in the connecting process if nonzero + * + * @return Number of clients on the server + */ +native get_playersnum(flag = 0); + +/** + * Stores a filtered list of client indexes to an array. + * + * @note Please consider using get_players_ex() instead which allows you to + * use named constants for flags instead of letters. + * @note Example retrieving all alive CTs: get_players(players, num "ae", "CT") + * + * @param players Array to store indexes to + * @param num Variable to store number of indexes to + * @param flags Optional list of filtering flags: + * "a" - do not include dead clients + * "b" - do not include alive clients + * "c" - do not include bots + * "d" - do not include human clients + * "e" - match with team + * "f" - match with part of name + * "g" - match case insensitive + * "h" - do not include HLTV proxies + * "i" - include connecting clients + * @param team String to match against if the "e" or "f" flag is specified + * + * @noreturn + */ +native get_players(players[MAX_PLAYERS], &num, const flags[] = "", const team[] = ""); + +/** + * Retrieves argument of client command as string. + * + * @note Should only be used inside of the client_command() forward. + * + * @param id Argument index starting from 1, 0 returns the command itself + * @param output Buffer to copy command argument to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native read_argv(id, output[], len); + +/** + * Retrieves argument of client command as integer value. + * + * @note Should only be used inside of the client_command() forward. + * + * @param id Argument index starting from 1 + * + * @return Integer value + */ +native read_argv_int(id); + +/** + * Retrieves argument of client command as float value. + * + * @note Should only be used inside of the client_command() forward. + * + * @param id Argument index starting from 1 + * + * @return Float value + */ +native Float:read_argv_float(id); + +/** + * Retrieves full client command string. + * + * @note Should only be used inside of the client_command() forward. + * + * @param output Buffer to copy command line to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native read_args(output[], len); + +/** + * Returns number of client command arguments. + * + * @note Should only be used inside of the client_command() forward. + * @note This count includes the command itself. I.e. in a command with 4 + * arguments, this will return 5. + * + * @return Number of arguments in the command + */ +native read_argc(); + +/** + * Converts a flag string to a bitflag value. + * + * @note Example: The string "abcd" represents the sum of 1, 2, 4, and 8 - or + * (1<<0)|(1<<1)|(1<<2)|(1<<3). The function will return 15. + * + * @param flags Flag string to convert + * + * @return Bitflag value + */ +native read_flags(const flags[]); + +/** + * Converts a bitflag value to a flag string. + * + * @note Example: The value 3 will yield the string "ab" + * + * @param flags Bitflag value to convert + * @param output Buffer to copy flag string to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native get_flags(flags, output[], len); + +/** + * Find a player given a filter. + * + * @note Please consider using find_player_ex() instead which allows you to + * use named constants for flags instead of letters. + * @note If matching by userid, do not also specify the "a", "b" or "c" flags, + * or the function may not return a correct result. + * + * @param flags List of filtering flags: + * "a" - match with name + * "b" - match with name substring + * "c" - match with authid + * "d" - match with ip + * "e" - match with team name + * "f" - do not include dead clients + * "g" - do not include alive clients + * "h" - do not include bots + * "i" - do not include human clients + * "j" - return last matched client instead of the first + * "k" - match with userid + * "l" - match case insensitively + * "m" - include connecting clients + * @param ... String to match against (integer if "k" flag is specified) + * + * @return Client index, or 0 if no client was found + */ +native find_player(const flags[], ...); + +/** + * Find a player given a filter. + * + * @note If matching by userid, do not also specify FindPlayer_MatchName, FindPlayer_MatchNameSubstring + * or FindPlayer_MatchAuthId, or the function may not return a correct result. + * + * @param flags Filtering flags (enum FindPlayerFlags); valid flags are: + * FindPlayer_MatchName - match with name + * FindPlayer_MatchNameSubstring - match with name substring + * FindPlayer_MatchAuthId - match with authid + * FindPlayer_MatchIP - match with ip + * FindPlayer_MatchTeam - match with team name + * FindPlayer_ExcludeDead - do not include dead clients + * FindPlayer_ExcludeAlive - do not include alive clients + * FindPlayer_ExcludeBots - do not include bots + * FindPlayer_ExcludeHuman - do not include human clients + * FindPlayer_LastMatched - return last matched client instead of the first + * FindPlayer_MatchUserId - match with userid + * FindPlayer_CaseInsensitive - match case insensitively + * FindPlayer_IncludeConnecting - include connecting clients + * @param ... String to match against (integer if FindPlayer_MatchUserId is specified) + * + * @return Client index, or 0 if no client was found + */ +native find_player_ex(FindPlayerFlags:flags, ...); + +/** + * Removes double-quotes from the beginning and end of a string. + * + * @note If the string only has a double-quote at either the start *or* the end, + * and not both, the function will do nothing. + * @note The function does not perform any trimming per-se. But if a + * double-quote is found at the beginning of the string, it will remove + * one ^r (carriage return) character at the end of the string if present, + * even if no matching double-quote is found. This is for convenience. + * + * @param text String to remove double-quotes from + * + * @return 1 if matching double-quotes have been removed, 0 otherwise + */ +native remove_quotes(text[]); + +/** + * Executes a command on the client. + * + * @note Executing malicious commands on the client ("slowhacking") is frowned + * upon. + * @note Valve has introduced a command filter to Counter-Strike 1.6. It is not + * possible to execute many commands if the client has opted in to this. + * + * @param index Client index, use 0 to execute on all clients + * @param command Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Length of formatted command string + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native client_cmd(index, const command[], any:...); + +/** + * Execute a command from the client without actually sending it to the client's + * DLL. + * + * @note This emulates a client command on the server side, and is an excellent + * tool to force a client to do certain actions related to the game. + * @note The command has to stand alone in the command parameter, only add + * arguments using the designated parameters. + * @note Commands emulated using this function will not trigger plugin command + * hooks. For an alternative that does, see amxclient_cmd() + * + * @param index Client index, use 0 to execute from all clients + * @param command Client command to execute on + * @param arg1 Optional command arguments + * @param arg2 Optional command arguments + * + * @noreturn + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native engclient_cmd(index, const command[], const arg1[] = "", const arg2[] = ""); + +/** + * Execute a command from the client without actually sending it to the client's + * DLL. This triggers plugin command hooks. + * + * @note This emulates a client command on the server side, and is an excellent + * tool to force a client to do certain actions related to the game. + * @note The command has to stand alone in the command parameter, only add + * arguments using the designated parameters. + * @note Commands emulated using this function will trigger other plugin's + * command hooks. For an alternative that doesn't, see engclient_cmd() + * + * @param index Client index, use 0 to execute from all clients + * @param command Client command to execute on + * @param arg1 Optional command arguments + * @param arg2 Optional command arguments + * + * @noreturn + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native amxclient_cmd(index, const command[], const arg1[] = "", const arg2[] = ""); + +/** + * Queues a command to be executed from the server console. + * + * @note Warning: This is a potential source of command injection. Do not feed + * client-controlled input (including client names) to this function + * without sanitizing it first. + * @note The queued commands will be executed by the engine on the next frame. + * If you require them to be executed immediately, see server_exec() + * + * @param command Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + */ +native server_cmd(const command[], any:...); + +/** + * Retrieves the name of the currently played map. + * + * @param name Buffer to copy map name to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + */ +native get_mapname(name[], len); + +/** + * Returns time remaining on map. + * + * @return Time left on map, in seconds + */ +native get_timeleft(); + +/** + * Returns the game time based on the game tick. + * + * @note This time is counted up from map start. If the engine is not processing + * this function will return the same value between calls, which makes it + * unusable for profiling purposes. + * + * @return Game time, in seconds + */ +native Float:get_gametime(); + +/** + * Returns the maxplayers setting of the current server, that is how many + * clients it supports. + * + * @note As of AMXX 1.8.3, this value is also exposed through a dynamic constant + * via the MaxClients variable, declared in amxconst.inc + * + * @return Maxplayers setting + */ +native get_maxplayers(); + +/** + * Retrieves the name of the currently played mod. + * + * @note This retrieves the short name of the mod. Example: for Counter-Strike, + * it will copy "cstrike" to the buffer. + * + * @param name Buffer to copy mod name to + * @param len Maximum size of the buffer + * + * @return Number of cells written to buffer + */ +native get_modname(name[], len); + +/** + * Retrieves the current time using the specified format string. + * + * @note Uses the strftime C function. For a list of valid format parameters, + * see: http://cplusplus.com/reference/clibrary/ctime/strftime.html + * A common example for a format string would be: "%m/%d/%Y - %H:%M:%S" + * + * @param format Format string + * @param output Buffer to copy formatted time string to + * @param len Maximum size of buffer + * + * @return Number of cells written to buffer + */ +native get_time(const format[], output[], len); + +/** + * Retrieves the provided time using the specified format string. + * + * @note Uses the strftime C function. For a list of valid format parameters, + * see: http://cplusplus.com/reference/clibrary/ctime/strftime.html + * A common example for a format string would be: "%m/%d/%Y - %H:%M:%S" + * + * @param output Buffer to copy formatted time string to + * @param len Maximum size of buffer + * @param format Format string + * @param time Unix timestamp, use -1 to use the current time + * + * @return Number of cells written to buffer + * @error If the conversion process fails, an error will be thrown. + */ +native format_time(output[], len, const format[], time = -1); + +/** + * Returns the system time as a unix timestamp (number of seconds since unix + * epoch). + * + * @param offset Optional offset value in seconds + * + * @return Unix time stamp + */ +native get_systime(offset = 0); + +/** + * Converts time strings to unix time stamp. + * + * @note Uses the strptime C function. For a list of valid format parameters, + * see: http://www.cplusplus.com/reference/ctime/strftime/ + * An example for a input/format combination would be: + * Input: "10:32:54 04/02/2013" Format: "%H:%M:%S %m:%d:%Y" + * @note Information missing from the input will be filled with the current + * time and date. + * + * @param input Time string to convert + * @param format Formatting information for conversion + * @param time If different from -1, the converted time will be added to + * this time stamp + * + * @return Unix time stamp + * @error If the conversion process fails, an error will be thrown. + */ +native parse_time(const input[], const format[], time = -1); + +/** + * Calls a function after a specified time has elapsed. + * + * @note Please consider using set_task_ex() instead which allows you to + * use named constants for flags instead of letters. + * + * @param time Time interval to assign + * @param function Function to execute + * @param id Task id to assign + * @param parameter Data to pass through to callback + * @param len Size of data + * @param flags Optional set of flags: + * "a" - repeat timer a set amount of times + * "b" - loop indefinitely until timer is stopped + * "c" - time interval is treated as absolute time after + * map start + * "d" - time interval is treated as absolute time before + * map change + * @param repeat If the "a" flag is set, the task will be repeated this + * many times + * + * @noreturn + * @error If an invalid callback function is provided, an error is + * thrown. + */ +native set_task(Float:time, const function[], id = 0, const any:parameter[] = "", len = 0, const flags[] = "", repeat = 0); + +/** + * Removes all tasks with the specified id. + * + * @param id Task id to search for + * @param outside Will remove tasks set by other plugins if nonzero + * + * @return Number of removed tasks + */ +native remove_task(id = 0, outside = 0); + +/** + * Modifies the time interval of all tasks with the specified id. + * + * @param id Task id to search for + * @param newTime New time interval to set + * @param outside Will affect tasks set by other plugins if nonzero + * + * @return Number of affected tasks + */ +native change_task(id = 0, Float:newTime = 1.0, outside = 0); + +/** + * Returns if a task with the specified id exists. + * + * @param id Task id to search for + * @param outside Search for tasks set by other plugins if nonzero + * + * @return 1 if a task was found, 0 otherwise + */ +native task_exists(id = 0, outside = 0); + +/** + * Sets the specified admin flags to a client. + * + * @note For a list of possible flags, see the ADMIN_* constants in amxconst.inc + * @note This function just adds the flags using a bitwise-or operation. After it + * has run, the flags may not exactly equal the specified bitflag sum. + * @note AMXX stores multiple sets of flags internally, but only flag set + * 0 is actively used. You should not change the value of the third + * parameter from the default. + * + * @param index Client index, 0 to set flags of server + * @param flags Admin flags + * @param id Flag set id, ranging from 0 to 31 + * + * @noreturn + * @error If the index is not within the range of 0 to MaxClients, an + * error will be thrown. + */ +native set_user_flags(index, flags = -1, id = 0); + +/** + * Returns the client's admin flags as a bitflag sum. + * + * @note For a list of possible flags, see the ADMIN_* constants in amxconst.inc + * @note AMXX stores multiple sets of flags internally, but only flag set + * 0 is actively used. You should not change the value of the second + * parameter from the default. + * + * @param index Client index, 0 to set flags of server + * @param id Flag set id, ranging from 0 to 31 + * + * @return Bitflag sum of client's admin flags + * @error If the index is not within the range of 0 to MaxClients, an + * error will be thrown. + */ +native get_user_flags(index, id = 0); + +/** + * Removes the specified admin flags from a client. + * + * @note For a list of possible flags, see the ADMIN_* constants in amxconst.inc + * @note This function just removes the flags using a bitwise-and operation. + * @note AMXX stores multiple sets of flags internally, but only flag set + * 0 is actively used. You should not change the value of the third + * parameter from the default. + * + * @param index Client index, 0 to set flags of server + * @param flags Admin flags + * @param id Flag set id, ranging from 0 to 31 + * + * @noreturn + * @error If the index is not within the range of 0 to MaxClients, an + * error will be thrown. + */ +native remove_user_flags(index, flags = -1, id = 0); + +/** + * Registers a callback to be called when the client executes a command from the + * console. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * @note Opting in to FlagManager enables the admin privileges to be overwritten + * by the end user via the cmdaccess.ini config file. + * @note Automatic detection for FlagManager will only include a command if it + * has required privileges (flags is not -1) and it is not a command + * starting with "say". + * + * @param client_cmd Command to register + * @param function Callback function + * @param flags Admin privilege flags required + * @param info Command description + * @param FlagManager 0 opts out of flag manager, 1 opts in, -1 selects + * automatically + * @param info_ml If true, the parameter "info" will be looked up as multilingual key + * + * @return Command id, 0 on failure + * @error If an invalid callback function is specified, an error + * will be thrown. + */ +native register_clcmd(const client_cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false); + +/** + * Registers a callback to be called when the client or server executes a + * command from the console. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * @note Opting in to FlagManager enables the admin privileges to be overwritten + * by the end user via the cmdaccess.ini config file. + * @note Automatic detection for FlagManager will only include a command if it + * has required privileges (flags is not -1) and it is not a command + * starting with "say". + * + * @param client_cmd Command to register + * @param function Callback function + * @param flags Admin privilege flags required + * @param info Command description + * @param FlagManager 0 opts out of flag manager, 1 opts in, -1 selects + * automatically + * @param info_ml If true, the parameter "info" will be looked up as multilingual key + * + * @return Command id, 0 on failure + * @error If an invalid callback function is specified, an error + * will be thrown. + */ +native register_concmd(const cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false); + +/** + * Registers a callback to be called when the server executes a command from the + * console. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param client_cmd Command to register + * @param function Callback function + * @param flags Admin privilege flags required + * @param info Command description + * @param info_ml If true, the parameter "info" will be looked up as multilingual key + * + * @return Command id, 0 on failure + * @error If an invalid callback function is specified, an error + * will be thrown. + */ +native register_srvcmd(const server_cmd[], const function[], flags = -1, const info[] = "", bool:info_ml = false); + +/** + * Retrieves information about a client command. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param index Command index + * @param command Buffer to copy command name to + * @param len1 Maximum name buffer size + * @param flags Variable to store privilege flags to + * @param info Buffer to copy command description to + * @param len2 Maximum description buffer size + * @param flag Only considers commands that can be accessed with + * the specified privilege flags + * @param info_ml Variable to store whether the parameter "info" is a multilingual key + * + * @return 1 on success, 0 if command was not found + */ +native get_clcmd(index, command[], len1, &flags, info[], len2, flag, &bool:info_ml = false); + +/** + * Returns number of registered client commands. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param flag Only considers commands that can be accessed with + * the specified privilege flags + * + * @return Number of registered client commands + */ +native get_clcmdsnum(flag); + +/** + * Retrieves information about a server command. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param index Command index + * @param command Buffer to copy command name to + * @param len1 Maximum name buffer size + * @param flags Variable to store privilege flags to + * @param info Buffer to copy command description to + * @param len2 Maximum description buffer size + * @param flag Only considers commands that can be accessed with + * the specified privilege flags + * @param info_ml Variable to store whether the parameter "info" is a multilingual key + * + * @return 1 on success, 0 if command was not found + */ +native get_srvcmd(index, server_cmd[], len1, &flags, info[], len2, flag, &bool:info_ml = false); + +/** + * Returns number of registered server commands. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param flag Only considers commands that can be accessed with + * the specified privilege flags + * + * @return Number of registered server commands + */ +native get_srvcmdsnum(flag); + +/** + * Retrieves information about a console command. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param index Command index + * @param command Buffer to copy command name to + * @param len1 Maximum name buffer size + * @param flags Variable to store privilege flags to + * @param info Buffer to copy command description to + * @param len2 Maximum description buffer size + * @param flag Only considers commands that can be accessed with + * the specified privilege flags + * @param id If set to 0 only server commands will be considered, + * positive will only consider client commands, otherwise + * all console commands will be considered + * @param info_ml Variable to store whether the parameter "info" is a multilingual key + * + * @return 1 on success, 0 if command was not found + */ +native get_concmd(index, cmd[], len1, &flags, info[], len2, flag, id = -1, &bool:info_ml = false); + +/** + * Returns the parent plugin id of a console command. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param cid Command index + * @param flag_mask Only considers commands that can be accessed with + * the specified privilege flags. + * @param id_type If set to 0 only server commands will be considered, + * positive will only consider client commands, otherwise + * all console commands will be considered. + * + * @return Plugin id + */ +native get_concmd_plid(cid, flag_mask, id_type); + +/** + * Returns number of registered console commands. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * + * @param flag Only considers commands that can be accessed with + * the specified privilege flags + * @param id If set to 0 only server commands will be considered, + * positive will only consider client commands, otherwise + * all console commands will be considered + * + * @return Number of registered console commands + */ +native get_concmdsnum(flag, id = -1); + +/** + * Returns unique menu id of a menu. + * + * @param menu Menu name + * @param outside Catch menus outside the calling plugin + * + * @return Menu id + */ +native register_menuid(const menu[], outside = 0); + +/** + * Registers a callback function to a menu id and keys. + * + * @param menuid Menu id + * @param keys Key flags + * @param function Callback function + * + * @noreturn + * @error If an invalid callback function is specified, an error + * will be thrown. + */ +native register_menucmd(menuid, keys, const function[]); + +/** + * Returns if the client is watching a menu. + * + * @note If there is no menu, the id is 0. If the id is negative, then the client + * views a VGUI menu. Otherwise, the id is an id acquired from the + * register_menuid() function. + * + * @param index Client index + * @param id Variable to store menu id to + * @param keys Variable to store menu keys to + * + * @return 1 if client views a menu, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, an error will be thrown. + */ +native get_user_menu(index, &id, &keys); + +/** + * Forces the server to execute the command queue immediately. + * + * @note Commands can be added to the queue using server_cmd() + * + * @noreturn + */ +native server_exec(); + +/** + * Emits a sound from an entity from the engine. + * + * @note The sample must be precached using precache_sound() so it is available + * in the engine's sound table. + * @note For a list of available channels, see CHAN_* constants in amxconst.inc, + * sounds emitted from the same channel will override each other. + * @note There are helpful reference constants in amxconst.inc for sound volume + * (VOL_*), attenuation (ATTN_*), flags (SND_*), and pitch (PITCH_*). + * + * @param index Entity index, use 0 to emit from all clients + * @param channel Channel to emit from + * @param sample Sound file to emit + * @param vol Volume in percent + * @param att Sound attenuation + * @param flags Emit flags + * @param pitch Sound pitch + * + * @noreturn + */ +native emit_sound(index, channel, const sample[], Float:vol, Float:att, flags, pitch); + +/** + * Returns a random floating point value generated by the engine. + * + * @param a Minimum value (inclusive) + * @param b Maximum value (inclusive) + * + * @return Generated random value + */ +native Float:random_float(Float:a, Float:b); + +/** + * Returns a random integer value generated by the engine. + * + * @param a Minimum value (inclusive) + * @param b Maximum value (inclusive) + * + * @return Generated random value + */ +native random_num(a, b); + +/** + * Returns unique id of a client message. + * + * @note Example usage: get_user_msgid("TextMsg") + * @note The message id is unique as long as the server is running, but might + * change between updates. They should not be hardcoded into plugins. + * @note On first server start, this function will return 0 if used inside + * plugin_precache(). Consider hooking RegUserMsg in order to retrieve + * the correct message id. + * + * @param name Client message name + * + * @return Message id, 0 if message was not found + */ +native get_user_msgid(const name[]); + +/** + * Retrieves the client message name from a message id. + * + * @param msgid Client message id + * @param name Buffer to copy message name to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer, 0 on invalid message id + */ +native get_user_msgname(msgid, name[], len); + +/** + * Returns a unique id for a public variable. + * + * @note Variables declared with the "public" specifier are accessible by-name + * from outside of the declaring plugin. + * @note If multiple plugins declare the same public variable, this native will + * still return a unique id. + * + * @param name Variable name + * + * @return Xvar id on success, -1 on failure + */ +native get_xvar_id(const name[]); + +/** + * Returns if a public variable exists in any loaded plugin. + * + * @param name Variable name + * + * @return 1 if public cvar exists, 0 otherwise + */ +native xvar_exists(const name[]); + +/** + * Returns the integer value of a public variable. + * + * @note If multiple plugins declare the same public variable, they are not + * automatically synchronized. The xvar system accesses only one of all + * public variables directly. Xvars have to be read through the natives or + * the value will be incorrect. + * + * @param id Xvar id, an xvar id can be retrieved using get_xvar_id() + * + * @return Xvar integer value + */ +native get_xvar_num(id); + +/** + * Returns the float value of a public variable. + * + * @note If multiple plugins declare the same public variable, they are not + * automatically synchronized. The xvar system accesses only one of all + * public variables directly. Xvars have to be read through the natives or + * the value will be incorrect. + * + * @param id Xvar id, an xvar id can be retrieved using get_xvar_id() + * + * @return Xvar float value + */ +native Float:get_xvar_float(id); + +/** + * Sets the integer value of a public variable. + * + * @note If multiple plugins declare the same public variable, they are not + * automatically synchronized. The xvar system accesses only one of all + * public variables directly. Xvars have to be set through the natives or + * the xvar will not be updated. + * + * @param id Xvar id, an xvar id can be retrieved using get_xvar_id() + * @param value Value to set + * + * @noreturn + * @error If an invalid xvar id is specified, an error will be thrown. + */ +native set_xvar_num(id, value = 0); + +/** + * Sets the float value of a public variable. + * + * @note If multiple plugins declare the same public variable, they are not + * automatically synchronized. The xvar system accesses only one of all + * public variables directly. Xvars have to be set through the natives or + * the xvar will not be updated. + * + * @param id Xvar id, an xvar id can be retrieved using get_xvar_id() + * @param value Value to set + * + * @noreturn + * @error If an invalid xvar id is specified, an error will be thrown. + */ +native set_xvar_float(id, Float:value = 0.0); + +/** + * Returns if a module is loaded. + * + * @param name Module name + * + * @return Module id of the matching module, -1 otherwise + */ +native is_module_loaded(const name[]); + +/** + * Retrieves info about a module by module index. + * + * @note For a list of possible status flags, see module_* constants in + * amxconst.inc + * + * @param id Module id + * @param name Buffer to copy module name to + * @param nameLen Maximum name buffer size + * @param author Buffer to copy module author to + * @param authorLen Maximum author buffer size + * @param version Buffer to copy module version to + * @param versionLen Maximum version buffer size + * @param status Variable to store module status to + * + * @return Module id on success, -1 on invalid module + */ +native get_module(id, name[], nameLen, author[], authorLen, version[], versionLen, &status); + +/** + * Returns the number of currently registered modules. + * + * @return Number of modules + */ +native get_modulesnum(); + +/** + * Returns if a plugin is loaded by registered name or filename. + * + * @note An example for a registered name would be "Admin Base", while a possible + * filename would be "admin.amxx". + * @note Prior to AMXX 1.80, this function would only search for plugins + * registered names, not the filename. + * @note The plugin name matching is case insensitive, while the filename + * matching is case sensitive. + * + * @param name Plugin name or filename + * @param usefilename If true searches for plugin filename, false searches for + * plugin name + * + * @return Plugin id of the matching plugin, -1 otherwise + */ +native is_plugin_loaded(const name[], bool:usefilename = false); + +/** + * Retrieves info about a plugin by plugin index. + * + * @param index Plugin index, -1 to target calling plugin + * @param filename Buffer to copy plugin filename to + * @param len1 Maximum filename buffer size + * @param name Buffer to copy plugin name to + * @param len2 Maximum name buffer size + * @param version Buffer to copy plugin version to + * @param len3 Maximum version buffer size + * @param author Buffer to copy plugin author to + * @param len4 Maximum author buffer size + * @param status Buffer to copy plugin status flags to + * @param len5 Maximum status buffer size + * @param url Buffer to copy plugin url to + * @param len6 Maximum url buffer size + * @param desc Buffer to copy plugin description to + * @param len7 Maximum description buffer size + * + * @return Plugin index on success, -1 if there is no plugin with given + * index + */ +native get_plugin(index, filename[] = "", len1 = 0, name[] = "", len2 = 0, version[] = "", len3 = 0, author[] = "", len4 = 0, status[] = "", len5 = 0, url[] = "", len6 = 0, desc[] = "", len7 = 0); + +/** + * Returns the number of loaded AMXX plugins. + * + * @return Number of loaded plugins + */ +native get_pluginsnum(); + +/** + * Pauses a plugin so it will not be executed until it is unpaused. + * + * @note This used to be able to pause specific functions, but this functionality + * (along with the flags "b" and "e") has been deprecated. + * @note If used without flag "c" this will pause the calling plugin. + * + * @param flag Pause flags + * "a" - pause plugin + * "c" - search for other plugins using param1 + * "d" - stop plugin, making it unavailable to unpause + * @param param1 Plugin filename + * @param param2 Unused and ignored + * + * @return 1 on success, 0 otherwise + * @error If it is attempted to use the deprecated functionality, + * an error is thrown. + */ +native pause(const flag[], const param1[] = "", const param2[] = ""); + +/** + * Unpauses a plugin so it will resume execution if it was previously paused. + * + * @note This used to be able to unpause specific functions, but this + * functionality (along with the flags "b" and "e") has been deprecated. + * @note Without specifying flag "c" this function will do nothing, as a plugin + * is incapable of unpausing itself. This is a relict of the deprecated + * functionality. + * + * @param flag Pause flags + * "a" - pause plugin + * "c" - search for other plugins using param1 + * @param param1 Plugin filename + * @param param2 Unused and ignored + * + * @return 1 on success, 0 otherwise + * @error If it is attempted to use the deprecated functionality, + * an error is thrown. + */ +native unpause(const flag[], const param1[] = "", const param2[] = ""); + +/** + * Initiates a function call to this or another plugin by function name. + * + * @note This only sets up the function call and covers the pre-requisites. + * Push parameters using the callfunc_push_* set of functions. The call + * will be executed only upon using callfunc_end() + * + * @param func Function name + * @param plugin Plugin filename, if empty the calling plugin is targeted + * The filename has to be the full exact name (e.g. stats.amxx) + * + * @return 1 on success + * 0 on runtime error + * -1 if plugin was not found + * -2 if function was not found + * @error If called while another callfunc has not yet been finished, + * an error is thrown. + */ +native callfunc_begin(const func[], const plugin[] = ""); + +/** + * Initiates a function call to this or another plugin by function id. + * + * @note This only sets up the function call and covers the pre-requisites. + * Push parameters using the callfunc_push_* set of functions. The call + * will be executed only upon using callfunc_end() + * @note The function id can be retrieved by get_func_id() + * + * @param func Function id + * @param plugin Plugin filename, if empty the calling plugin is targeted + * The filename has to be the full exact name (e.g. stats.amxx) + * + * @return 1 on success + * -1 if plugin was not found + * -2 if function is not executable + * @error If called while another callfunc has not yet been finished, + * or the specified function is invalid, an error is thrown. + */ +native callfunc_begin_i(func, plugin = -1); + +/** + * Retrieves a functions id for use with callfunc_begin_i() + * + * @param funcName Function name + * @param pluginId Plugin id, if -1 the calling plugin is targeted + * The plugin id can be retrieved using find_plugin_byfile() + * + * @return >=0 Function id on success + * -1 if plugin or function was not found + */ +native get_func_id(const funcName[], pluginId = -1); + +/** + * Pushes an int value onto the current call. + * + * @param value Int value to push + * + * @noreturn + * @error If called without initiating a callfunc, or the maximum + * amount of parameters is reached, an error is thrown. + */ +native callfunc_push_int(value); + +/** + * Pushes a float value onto the current call. + * + * @param value Float value to push + * + * @noreturn + * @error If called without initiating a callfunc, or the maximum + * amount of parameters is reached, an error is thrown. + */ +native callfunc_push_float(Float: value); + +/** + * Pushes an int value reference onto the current call. + * + * @note Changes made to this value by the called function will be reflected + * in the calling plugin. + * + * @param value Int value to push + * + * @noreturn + * @error If called without initiating a callfunc, or the maximum + * amount of parameters is reached, an error is thrown. + */ +native callfunc_push_intrf(&value); + +/** + * Pushes a float value reference onto the current call. + * + * @note Changes made to this value by the called function will be reflected + * in the calling plugin. + * + * @param value Float value to push + * + * @noreturn + * @error If called without initiating a callfunc, or the maximum + * amount of parameters is reached, an error is thrown. + */ +native callfunc_push_floatrf(&Float:value); + +/** + * Pushes a string onto the current call. + * + * @note This will defy the "const" specifier if copyback is true, which is + * only kept for special backwards compatibility. + * + * @param VALUE String to push + * @param copyback If true, any changes made in the called function will be + * copied back to the calling plugin + * + * @noreturn + * @error If called without initiating a callfunc, or the maximum + * amount of parameters is reached, an error is thrown. + */ +native callfunc_push_str(const VALUE[], bool:copyback = true); + +/** + * Pushes an array onto the current call. + * + * @note This will defy the "const" specifier if copyback is true, which is + * only kept for special backwards compatibility. + * + * @param VALUE Array to push + * @param array_size Size of the array + * @param copyback If true, any changes made in the called function will be + * copied back to the calling plugin + * + * @noreturn + * @error If called without initiating a callfunc, or the maximum + * amount of parameters is reached, an error is thrown. + */ +native callfunc_push_array(const VALUE[], array_size, bool:copyback = true); + +/** + * Completes the call to a function. + * + * @return 1 on success + * -1 if the plugin was not found + * -2 if the function was not found + * @error If called without initiating a callfunc, an error is thrown. + */ +native callfunc_end(); + +/** + * Called when an inconsistent file is encountered by the engine. + * + * @param id Client index + * @param filename Detected file + * @param reason Buffer storing the disconnect reason (can be overwritten) + * + * @return PLUGIN_CONTINUE to let the engine kick the client + * PLUGIN_HANDLED to block the inconsistency kick + */ +forward inconsistent_file(id, const filename[], reason[64]); + +/** + * Forces the clients and server to be running with the same version of a + * specified file. + * + * @note For a list of possible enforcement types, see the force_* constants + * in amxconst.inc + * + * @param force_type Enforcement type + * @param mins Bounding box mins vector + * @param maxs Bounding box maxs vector + * @param filename Filename + * + * @return 1 on success, 0 otherwise + */ +native force_unmodified(force_type, const mins[3], const maxs[3], const filename[]); + +/** + * Calculates the MD5 keysum of a string. + * + * @param szString String to calculate keysum of + * @param md5buffer Buffer to copy the MD5 hash to + * + * @return Number of cells written to the buffer (always 32) + */ +#pragma deprecated Use hash_string() function. Also, see Hash_* constants. +native md5(const szString[], md5buffer[34]); + +/** + * Calculates the MD5 keysum of a file. + * + * @param file Path to file to calculate keysum of + * @param md5buffer Buffer to copy the MD5 hash to + * + * @return Number of cells written to the buffer (always 32) + * @error If the file can not be opened, and error is thrown. + */ +#pragma deprecated Use hash_file() function. Also, see Hash_* constants. +native md5_file(const file[], md5buffer[34]); + +/** + * Generate a hash value (message digest) + * + * @param string String to be hashed. + * @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file. + * @param output Output string to store hash in. + * @param outputSize The maximum size of the output string to store hash in. + * + * @return Number of written bytes. + */ +native hash_string(const string[], const HashType:type, output[], const outputSize); + +/** + * Generate a hash value using the contents of a given file + * + * @param fileName Path of file to be hashed. + * @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file. + * @param output Output string to store hash in. + * @param outputSize The maximum size of the output string to store hash in. + * + * @return Number of written bytes. + * @error If the file couldn't be opened, an error is thrown. + */ +native hash_file(const fileName[], const HashType:type, output[], const outputSize); + +/** + * Returns the internal flags set on the plugin's state. + * + * @param hdr If nonzero, the function will return the pcode rather than + * state flags + * @param plid Plugin id, -1 to target calling plugin + * + * @return Plugin flags + */ +native plugin_flags(hdr = 0, plid = -1); + +/** + * Allows plugins to declare module dependencies using require_module() + * + * @deprecated Module dependency has been automatically handled by the compiler + * since AMXX 1.50, released in 2005. This forward is no longer + * called. + * + * @noreturn + */ +#pragma deprecated Module dependency is now automatically handled by the compiler. This forward is no longer called. +forward plugin_modules(); + +/** + * Adds a module dependency. + * + * @deprecated Module dependency has been automatically handled by the compiler + * since AMXX 1.50, released in 2005. This native has no effect. + * + * @noreturn + */ +#pragma deprecated Module dependency is now automatically handled by the compiler. This native has no effect. +native require_module(const module[]); + +/** + * Returns if the server is 64 bit. + * + * @deprecated As a result of Valve dropping support for 64bit binaries, AMXX is + * also not shipping 64bit builds anymore. This native is basically + * guaranteed to return 0. + * + * @return 1 if the server is 64 bit, 0 otherwise + */ +#pragma deprecated AMXX is not shipping 64bits builds anymore. This native is basically guaranteed to return 0. +native is_amd64_server(); + +/** + * Returns plugin id by filename. + * + * @param filename Filename to match + * @param ignoreCase If nonzero matches case insensitively, case sensitively + * otherwise + * + * @return Plugin id, -1 (INVALID_PLUGIN_ID) on failure + */ +native find_plugin_byfile(const filename[], ignoreCase = 1); + +/** + * Called before plugin_init(), allows the plugin to register natives. + * + * @noreturn + */ +forward plugin_natives(); + +/** + * Registers a native. + * + * @note Style 0 natives call the handler in the following manner: + * + * public native_handler(plugin_id, argc) + * + * plugin_id - plugin calling the native + * argc - number of parameters + * + * @note Style 1 natives are deprecated. Plugins should not use them, they might + * break. + * @note Style 1 natives work a little different. Instead of passing plugin id + * and number of parameters, the handler should be prototyped just like the + * native would be called. For each by-reference parameter, the plugin + * then has to use param_convert() to properly use them. + * @note A native should *never* recurse. Bad things will happen. + * + * @param name Native name + * @param handler Callback function + * @param style Native style + * + * @noreturn + * @error If an invalid callback is specified, an error is thrown. + */ +native register_native(const name[], const handler[], style = 0); + +/** + * Registers the plugin as a library. + * + * @note To mark a library as required, place the following in the include + * file: + * #pragma reqlib + * #if !defined AMXMODX_NOAUTOLOAD + * #pragma loadlib + * #endif + * + * @noreturn + */ +native register_library(const library[]); + +/** + * Logs an error in the native and breaks into the AMXX debugger. + * + * @note This acts as if the calling plugin - the plugin that is calling the + * native, not the plugin calling this function - triggered the error, + * just like when AMXX natives error. + * + * @param error Error number + * @param fmt Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + * @error The function is guaranteed to throw an error, but will make + * it appear as if the plugin calling the native triggered it. + */ +native log_error(error, const fmt[], any:...); + +/** + * Converts a parameter to work as a by-reference parameter. + * + * @deprecated Style 1 natives are deprecated and should be converted to + * style 0. This should not be used. + * + * @note This only needs to be called if the native was registered with style 1. + * @note Remember that arrays (and strings) are always by-reference and need to + * be converted. + * + * @param num Argument to convert, starting from 1 + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 0, an error will be thrown. + */ +native param_convert(num); + +/** + * Retrieves a string from the plugin calling the native. + * + * @param param Argument to retrieve, starting from 1 + * @param dest Buffer to copy string to + * @param maxlen Maximum size of buffer + * + * @return Number of cells copied to buffer + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native get_string(param, dest[], maxlen); + +/** + * Copies a string to the plugin calling the native. + * + * @param param Argument to set, starting from 1 + * @param dest Buffer to copy string from + * @param maxlen Maximum size of buffer + * + * @return Number of cells copied from buffer + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native set_string(param, dest[], maxlen); + +/** + * Returns the integer value of a parameter from the plugin calling the native. + * + * @param param Argument to retrieve, starting from 1 + * + * @return Integer value + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native get_param(param); + +/** + * Returns the float value of a parameter from the plugin calling the native. + * + * @param param Argument to retrieve, starting from 1 + * + * @return Float value + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native Float:get_param_f(param); + +/** + * Returns the integer value of a by-reference parameter from the plugin calling + * the native. + * + * @param param Argument to retrieve, starting from 1 + * + * @return Integer value + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native get_param_byref(param); + +/** + * Returns the float value of a by-reference parameter from the plugin calling + * the native. + * + * @param param Argument to retrieve, starting from 1 + * + * @return Float value + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native Float:get_float_byref(param); + +/** + * Sets the integer value of a by-reference parameter to the plugin calling the + * native. + * + * @param param Argument to set, starting from 1 + * @param value Value to set parameter to + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native set_param_byref(param, value); + +/** + * Sets the float value of a by-reference parameter to the plugin calling the + * native. + * + * @param param Argument to set, starting from 1 + * @param value Value to set parameter to + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native set_float_byref(param, Float:value); + +/** + * Retrieves an array from the plugin calling the native. + * + * @param param Argument to retrieve, starting from 1 + * @param dest Buffer to copy array to + * @param maxlen Size of buffer + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native get_array(param, dest[], size); + +/** + * Retrieves a float array from the plugin calling the native. + * + * @param param Argument to retrieve, starting from 1 + * @param dest Buffer to copy array to + * @param maxlen Size of buffer + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native get_array_f(param, Float:dest[], size); + +/** + * Copies an array to the plugin calling the native. + * + * @param param Argument to set, starting from 1 + * @param source Buffer to copy array from + * @param maxlen Size of buffer + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native set_array(param, const source[], size); + +/** + * Copies a float array to the plugin calling the native. + * + * @param param Argument to set, starting from 1 + * @param source Buffer to copy array from + * @param maxlen Size of buffer + * + * @noreturn + * @error If used outside of a native callback, or the native was + * created with style 1, an error will be thrown. + */ +native set_array_f(param, const Float:source[], size); + +/** + * Allows to trap error messages that occur in a plugin. + * + * @note This can be used to override the debug messages that occur when the + * plugin causes some kind of runtime error. + * @note The handler will be called in the following manner: + * + * public error_filter(error_code, bool:debugging, message[]) + * + * error_code - AMX_ERR_* code. + * debugging - True if the plugin is in debug mode, false otherwise + * message[] - Message sent along with the error + * + * @note The handler should return PLUGIN_CONTINUE to let the error through the + * filter, or PLUGIN_HANDLED to block the error from displaying. + * + * @param handler Function name to call + * + * @noreturn + * @error If an invalid callback function is provided, an error + * is thrown. + */ +native set_error_filter(const handler[]); + +/** + * Returns a trace handle for the item at the top of the traced call stack. + * + * @note Intended for use inside an error handler set with set_error_filter() + * + * @return Trace handle, 0 if no debugging information is available + */ +native dbg_trace_begin(); + +/** + * Returns the next item in a traced call stack. + * + * @param trace Trace handle + * + * @return New trace handle, 0 if no more traces exist + */ +native dbg_trace_next(trace); + +/** + * Retrieves the call stack info for a trace. + * + * @param trace Trace handle + * @param line Variable to set line at which plugin failed to + * @param function Buffer to copy function to + * @param maxLength1 Maximum function buffer size + * @param file Buffer to copy filename to + * @param maxLength2 Maximum filename buffer size + * + * @return 1 on success, 0 if no trace data is available + */ +native dbg_trace_info(trace, &line, function[], maxLength1, file[], maxLength2); + +/** + * Retrieves the formatted error string from a trace. + * + * @note The string format is generally: "Run time error : " + * + * @param buffer Buffer to copy error message to + * @param maxLength Maximum buffer size + * + * @return 1 on success, 0 if no trace data is available + */ +native dbg_fmt_error(buffer[], maxLength); + +/** + * Sets a native filter, letting the plugin intercept and handle an + * automatic native requirement. + * + * @note This has to be used inside the plugin_native() forward, otherwise it + * has no effect. + * @note This is useful for creating plugins that can dynamically decide which + * modules or features to use at runtime, often necessary for cross-mod + * plugins. It allows to deploy a single version of the plugin instead + * of compiling multiple versions for each use-case. + * @note The handler will be called in the following manner: + * + * public native_filter(const native[], index, trap) + * + * native - Native name + * index - Native index + * trap - 0 if native couldn't be found, 1 if native use was attempted + * + * @note The handler should return PLUGIN_CONTINUE to let the error through the + * filter (which will throw a run-time error), or return PLUGIN_HANDLED + * to continue operation. + * @note Returning PLUGIN_CONTINUE if trap is 0 will result in the plugin + * failing to load! + * + * @param handler Function name to call + * + * @return 1 if handler is set successfully, 0 otherwise (called + * outside of plugin_native() forward) + * @error If an invalid callback function is provided, an error is + * thrown. + */ +native set_native_filter(const handler[]); + +/** + * Sets a module/library filter, letting the plugin intercept and handle an + * automatic module requirement. + * + * @note This has to be used inside the plugin_native() forward, otherwise it + * has no effect. + * @note This is useful for creating plugins that can dynamically decide which + * modules or features to use at runtime, often necessary for cross-mod + * plugins. It allows to deploy a single version of the plugin instead + * of compiling multiple versions for each use-case. + * @note For a list of possible libtypes see the LibType enum in amxconst.inc + * @note The handler will be called in the following manner: + * + * public module_filter(const library[], LibType:type) + * + * library - Shortname of library or class that is required + * libtrype - Type of requirement being checked (library/module or class) + * + * @note The handler should return PLUGIN_CONTINUE to let the error through the + * filter (which will result in the plugin failing to load), or + * PLUGIN_HANDLED to imply that load can continue without the module. + * @note Errors occuring inside the handler will not be filtered and cause the + * plugin to fail load as if the handler returned PLUGIN_CONTINUE. + * + * @return 0 on success, -1 if filtering is not available, -2 if handler + * could not be found. + */ +native set_module_filter(const handler[]); + +/** + * Aborts execution of the current callback by throwing an error. + * + * @note Warning: This function should not be used inside error filters, module + * filters (native filters are safe if trap equals 1) or the + * plugin_natives() forward. + * @note The message will automatically be tagged with the plugin's name and the + * log will include a timestamp with the message. + * @note For a list of possible error codes, see AMX_* constants in amxconst.inc + * + * @param error Error code + * @param fmt Formatting rules + * @param ... Variable list of formatting parameters + * + * @noreturn + * @error The function is guaranteed to throw an error, using the + * specified custom log message. + */ +native abort(error, const fmt[] = "", any:...); + +/** + * Returns if a specific module is loaded. + * + * @note This uses the same method AMXX uses internally to see if a module is + * required by a plugin. + * @note Example usage: module_exists("cstrike") + * + * @param logtag Module shortname + * + * @return 1 if module is loaded, 0 otherwise + */ +native module_exists(const logtag[]); + +/** + * Returns if a specific library or class is loaded. + * + * @note This is the newer version of module_exists(), enabling users to + * distinguish between libraries and classes, while module_exists() always + * checks for both types. + * @note For a list of possible types, see the LibType enum in amxconst.inc + * + * @param library Library/Class shortname + * @param type Type to search for + * + * @return 1 if module is loaded, 0 otherwise + */ +native LibraryExists(const library[], LibType:type); + +/** + * Returns the next valid hudchannel for the client. + * + * @note This function uses the same method set_hudmessage() uses to determine + * the next channel if it is set to auto-select. + * + * @param player Client index + * + * @return Valid hudchannel (1-4) + * @error If the index is not within the range of 1 to MaxClients or + * the client is not connected, an error will be thrown. + */ +native next_hudchannel(player); + +/** + * Creates a HUD synchronization object. + * + * @note Create one of these for each section of the screen that contains + * overlapping HUD messages. For example, if using both sides of the + * screen to display three messages that could potentially overlap, + * each side is considered a synchronizable area. You can then use + * ShowSyncHudMsg() to correctly synchronize displaying the HUD message + * with any other messages potentially in its class. + * @note This does not do anything like reserving screen area. Its sole + * purpose is to be able to wipe an old message on an auto-channel and + * ensure that it will not clear a message from another plugin. + * + * @param num Unused and ignored + * @param ... Unused and ignored + * + * @return HUD sync object handle + */ +native CreateHudSyncObj(num = 0, ...); + +/** + * Displays a synchronized HUD message. + * + * @note This will check that the HUD object has its previous display on the + * screen cleared before it proceeds to write another message. It will + * only do this in the case of that channel not having been cleared + * already. + * @note This uses the display parameters set with set_hudmessage(), ignoring + * the selected channel in favor of its own synchronization. + * @note This functions return value behaves differently depending on what is + * used as the client index: If 0 is specified, then the function will + * return 0 if nothing has been sent (no client connected). If either a + * single client is specified, or there is at least one client connected, + * the number of printed characters will refer to the message that is sent + * last, to the client with the highest index. + * + * @param target Client index, use 0 to display to all clients + * @param syncObj HUD sync object handle + * @param fmt Formatting rules + * @param ... Variable number of formatting parameters + * + * @return Number of printed characters + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native ShowSyncHudMsg(target, syncObj, const fmt[], any:...); + +/** + * Clears the display on a HUD sync object. + * + * @note This sends an empty message to the previously occupied HUD channel. + * It is not quite the same as manually sending an empty message to the + * sync object as that would send out two separate messages, one for + * clearing the occupied channel and another using a new channel, which + * will subsequently not mark the sync object as cleared. + * + * @param target Client index, use 0 to display to all clients + * @param syncObj HUD sync object handle + * + * @noreturn + * @error If a single client is specified and the index is not within + * the range of 1 to MaxClients, an error will be thrown. + */ +native ClearSyncHud(target, syncObj); + +/** + * Triggers the software interrupt 3, used for breaking into an attached + * debugger. + * + * @note Warning: This is a debugging function that is not intended for general + * plugin use. Using this function will either halt the server and break + * into the attached debugger, or outright crash the server if no + * debugger is attached. + * + * @noreturn + */ +native int3(); + +/** + * Sets the calling plugin to a failed state. + * + * @note Calling this will cause the calling plugin to completely cease + * operation. It is not possible to recover. + * @note This should be used to gracefully handle fatal errors. The log message + * will appear in the AMXX error log. + * + * @param fmt Formatting rules + * @param ... Variable number of formatting parameters + * + * @noreturn + * @error The function is guaranteed to throw a fatal error, ceasing + * further operation of the plugin. + */ +native set_fail_state(const fmt[], any:...); + +/** + * Returns the reference address of the variable passed in. + * + * @note Addresses are local to the plugin and do not represent a full CPU + * address. + * + * @param ... Variable to retrieve address from + * + * @return Variable address + */ +native get_var_addr(any:...); + +/** + * Returns the value of an address. + * + * @note Addresses can be acquired using get_var_addr() + * + * @param addr Variable address + * + * @return Value at address + * @error If the plugin attempts to access an address outside of the + * stack or heap limits of the plugin, an error will be thrown. + */ +native get_addr_val(addr); + +/** + * Sets the value of an address. + * + * @note Addresses can be acquired using get_var_addr() + * + * @param addr Variable address + * @param val Value to set + * + * @noreturn + * @error If the plugin attempts to access an address outside of the + * stack or heap limits of the plugin, an error will be thrown. + */ +native set_addr_val(addr, val); + +/** + * Creates a global forward that will be called in all plugins. + * + * @note For a list of valid stop types, see the ET_* constants in amxconst.inc + * @note For a list of valid parameter types, see the FP_* constants in + * amxconst.inc + * + * @param name Function name to call + * @param stop_type Treatment of the plugin return values + * @param ... List of parameter types + * + * @return Forward handle, -1 on failure + */ +native CreateMultiForward(const name[], stop_type, ...); + +/** + * Creates a private forward that will be called in a single plugin. + * + * @note Unlike other natives expecting a plugin id, specifying -1 will not + * select the calling plugin, and instead throw an error. + * + * @param plugin_id Plugin to call forward in. The plugin id can be + * retrieved using find_plugin_byfile() + * @param name Function name to call + * @param ... List of parameter types + * + * @return Forward handle, -1 on failure + * @error If an invalid plugin id is specified, an error will be + * thrown. + */ +native CreateOneForward(plugin_id, const name[], ...); + +/** + * Prepares an array for use in a forward. Pass the result ExecuteForward() + * instead of the array itself. + * + * @param array Array to prepare + * @param size Size of array + * @param copyback If nonzero, modifications made by the called plugin(s) + * will be copied back to the caller + * + * @return Special handle for use in ExecuteForward() + */ +native PrepareArray(const array[], size, copyback = 0); + +/** + * Executes a forward. + * + * @note Passing arrays requires them to be prepared using PrepareArray() + * + * @param forward_handle Forward handle + * @param ret Optional variable to store return value in + * @param ... Variable number of parameters to pass through + * + * @return 1 on success, 0 if forward can't be executed + * @error If the number of parameters mismatch from the number + * of parameters that the forward was declared with, + * an error is thrown. + */ +native ExecuteForward(forward_handle, &ret = 0, any:...); + +/** + * Destroys and deallocates a forward. + * + * @note Does not distinguish between private and global forwards. + * + * @param forward_handle Forward handle + * + * @noreturn + */ +native DestroyForward(forward_handle); + +/** + * Sets all elements of array to a specified value. + * + * @param array Array to modify + * @param value Value to set each element to + * @param size Size of array + * + * @noreturn + */ +native arrayset(any:array[], any:value, size); + +/** + * Returns the weapon id associated with a weapon name. + * + * @note The weapon name is case sensitive and has the weapon_* form. + * + * @param name Weapon name + * + * @return Weapon id, or 0 if no id was found + */ +native get_weaponid(const name[]); + +/** + * Adds an admin to the dynamic admin storage for lookup at a later time. + * + * @note For a list of possible access flags, see the ADMIN_* constants in + * amxconst.inc + * @note For a list of possible auth flags, see the FLAG_* constants in + * amxconst.inc + * + * @param AuthData Auth information to set (can be name, IP or SteamID) + * @param Password Password to set + * @param Access Admin access flags + * @param Flags Auth behavior flags + * + * @noreturn + */ +native admins_push(const AuthData[], const Password[], Access, Flags); + +/** + * Returns the number of admins in the dynamic admin storage. + * + * @return Number of admins + */ +native admins_num(); + +/** + * Retrieves information about a dynamically stored admin. + * + * @note For a list of possible props, see the AdminProp enum in amxconst.inc + * + * @param num Admin storage index + * @param Property Admin property to retrieve + * @param Buffer Buffer to copy property information to, if AdminProp_Auth + * or AdminProp_Password is specified + * @param BufferSize Maximum buffer size + * + * @return Property value if AdminProp_Access or AdminProp_Flags + * is requested, 0 otherwise + * @error If an invalid storage index is specified, an error will + * be thrown. + */ +native admins_lookup(num, AdminProp:Property, Buffer[] = "", BufferSize = 0); + +/** + * Clears the list of dynamically stored admins. + * + * @noreturn + */ +native admins_flush(); + +/** + * Returns if a map contains at least one entity with the provided class name. + * + * @param classname Entity classname to match + * + * @return True if an entity is found, false otherwise + */ +native bool:has_map_ent_class(const classname[]); + + +/** + * Called when the map has loaded, and all configs are done executing. + * This includes servercfgfile (server.cfg), amxx.cfg, plugin's config, and + * per-map config. + * + * @note This is best place to initialize plugin functions which are based on cvar data. + * @note This will always be called once and only once per map. It will be + * called few seconds after plugin_cfg(). + * + * @noreturn + */ +forward OnConfigsExecuted(); + +/** + * Called when the map has loaded, right after plugin_cfg() but any time + * before OnConfigsExecuted. It's called after amxx.cfg and all + * AutoExecConfig() exec commands have been added to the server command buffer. + * + * @note This will always be called once and only once per map. + * + * @noreturn + */ +forward OnAutoConfigsBuffered(); + +/** + * Specifies that the given config file should be executed after plugin load. + * + * @note OnConfigsExecuted() will not be called until the config file has executed, + * but it will be called if the execution fails. + * @note The name parameter should not contain dots, otherwise file will not be executed. + * + * @param autoCreate If true, and the config file does not exist, such a config + * file will be automatically created and populated with + * information from the plugin's registered cvars. + * @param name Name of the config file, excluding the .cfg extension. + * If empty, is assumed. + * @param folder Folder under plugins/ to use. + * + * @noreturn + */ +native AutoExecConfig(bool:autoCreate = true, const name[] = "", const folder[] = ""); + +/** + * Creates a single use hook for the next frame. + * + * @param callback Function to be executed on the next frame. + * @param data Optional data to be passed to the callback function. + * + * @note Callback function prototype: + * public function(data) + * + * @noreturn + */ +native RequestFrame(const callback[], any:data = 0); + +// Always keep this at the bottom of this file +#include diff --git a/amxmodx/scripting/include/amxmodx_version.inc b/amxmodx/scripting/include/amxmodx_version.inc new file mode 100644 index 0000000..1dd85bc --- /dev/null +++ b/amxmodx/scripting/include/amxmodx_version.inc @@ -0,0 +1,20 @@ + +#if defined _amxmodx_version_included + #endinput +#endif +#define _amxmodx_version_included + +#define AMXX_VERSION_TAG "" +#define AMXX_VERSION_CSET "9fbf91d" +#define AMXX_VERSION_MAJOR "1" +#define AMXX_VERSION_MAJOR_NUM 1 +#define AMXX_VERSION_MINOR "10" +#define AMXX_VERSION_MINOR_NUM 10 +#define AMXX_VERSION_RELEASE "0" +#define AMXX_VERSION_LOCAL_REV_NUM 5417 +#define AMXX_VERSION_LOCAL_REV "5417" +#define AMXX_VERSION 1.100 +#define AMXX_VERSION_NUM 200 + +stock const AMXX_VERSION_STR[] = "1.10.0.5417"; + \ No newline at end of file diff --git a/amxmodx/scripting/include/amxxarch.inc b/amxmodx/scripting/include/amxxarch.inc new file mode 100644 index 0000000..66c6a0f --- /dev/null +++ b/amxmodx/scripting/include/amxxarch.inc @@ -0,0 +1,43 @@ +/* + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * See LICENSE.TXT file for more information. + * + */ + #if defined _AmxxArch_included + #endinput +#endif +#define _AmxxArch_included + +#if AMXX_VERSION_NUM >= 175 + #pragma reqlib AmxxArch + #if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib AmxxArch + #endif +#else + #pragma library AmxxArch +#endif + +#define AA_NO_ERROR 0 + +/* +* @param filepath Path to the file +* @param outdir Directory where the archive will be unpacked +* @param callback Callback function (example: public OnComplete(idcaller, error)) +* @param idcaller player id or 0 +* +* @noreturn +*/ +native AA_Unarchive( const filepath[], const outdir[], const callback[], const idcaller = 0); \ No newline at end of file diff --git a/amxmodx/scripting/include/cellarray.inc b/amxmodx/scripting/include/cellarray.inc new file mode 100644 index 0000000..2031344 --- /dev/null +++ b/amxmodx/scripting/include/cellarray.inc @@ -0,0 +1,525 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _cellarray_included + #endinput +#endif + +#define _cellarray_included + +/** + * Cellarray tag declaration + * + * @note These dynamic arrays are intended to be used for a form of global + * storage without requiring a #define that needs to be increased each + * time the plugin author requires more storage. These are not designed + * to be a full replacement for normal arrays, as those are faster and + * should be used whenever possible. + * @note Plugins are responsible for freeing all Array handles they acquire, + * including those from ArrayClone. Failing to free handles will result + * in the plugin and AMXX leaking memory. + */ +enum Array +{ + Invalid_Array = 0 +}; + +/** + * Returns the number of cells required to fit a string of the specified size + * (including the null terminator). + * + * @param size Number of bytes. + * + * @return Minimum number of cells required to fit the byte count. + */ +stock ByteCountToCells(size) +{ + if (!size) + { + return 1; + } + + return (size + 3) / 4; +} + +/** + * Creates a handle to a dynamically sized array. + * + * @note It is very important that the provided cellsize matches up with the + * buffer sizes that are passed with subsequent Array[Get|Set|Push] calls. + * @note Initially the "reserved" parameter was intended to create blank entries + * that would immediately be usable with Array[Get|Set] functions. This + * functionality was never working as intended, and can now be achieved + * using ArrayResize(). + * + * @param cellsize Size of each array entry in cells + * @param reserved Pre-allocates space in the array for the specified + * number of items. The items are not valid to read or set + * until they have actually been pushed into the array. + * + * @return New array handle, which must be freed via ArrayDestroy() + * @error If an invalid cellsize is provided an error will be + * thrown. + */ +native Array:ArrayCreate(cellsize = 1, reserved = 32); + +/** + * Clones an array, returning a new handle with the same size and data. + * + * @param which Array handle + * + * @return Handle to the cloned array on success, 0 otherwise + * @error If an invalid handle is provided an error will be + * thrown. + */ +native Array:ArrayClone(Array:which); + +/** + * Clears all entries from the array. + * + * @param which Array handle + * + * @noreturn + * @error Invalid handle + */ +native ArrayClear(Array:which); + +/** + * Returns the number of elements in the array. + * + * @param which Array handle + * + * @return Number of elements in the array + * @error If an invalid handle is provided an error will be + * thrown. + */ +native ArraySize(Array:which); + +/** + * Resizes an array. + * + * @note If the size is smaller than the current array size the array is + * truncated and data lost. + * + * @param which Array handle + * @param newsize New size + * + * @noreturn + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native bool:ArrayResize(Array:which, newsize); + +/** + * Retrieves an array of data from a cellarray. + * + * @note If the size parameter is specified as -1 the output buffer has to match + * the size the array was created with. + * + * @param which Array handle + * @param item Item index in the array + * @param output Buffer to copy value to + * @param size If not set, assumes the buffer size is equal to the + * cellsize. Otherwise, the specified size is used. + * + * @return Number of cells copied + * @error If an invalid handle or index is provided an error will + * be thrown. + */ +native ArrayGetArray(Array:which, item, any:output[], size = -1); + +/** + * Returns a single cell of data from an array + * + * @param which Array handle + * @param item Item index in the array + * @param block If the array has a cellsize >1 this optionally specifies + * which block to read from + * @param asChar If true reads the value as a byte instead of a cell + * + * @return Integer value + * @error If an invalid handle, index or block is provided an + * error will be thrown. + */ +native any:ArrayGetCell(Array:which, item, block = 0, bool:asChar = false); + +/** + * Returieves string data from an array. + * + * @param which Array handle + * @param item Item index in the array + * @param output Buffer to copy value to + * @param size Maximum size of the buffer + * + * @return Number of characters copied + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayGetString(Array:which, item, output[], size); + +/** + * Fills an item's data with the contents of an array. + * + * @note If the size parameter is specified as -1 the input buffer has to match + * the size the array was created with. + * @note The item index must already be valid. Use ArrayPushArray to create + * a new array item in the cellarray. + * + * @param which Array handle + * @param item Item index in the array + * @param input Array to copy to the cellarray + * @param size If not set, assumes the buffer size is equal to the + * cellsize. Otherwise, the specified size is used. + * + * @return Number of cells copied + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArraySetArray(Array:which, item, const any:input[], size =-1); + +/** + * Sets an item's data to a single cell value. + * + * @note The item index must already be valid. Use ArrayPushArray to create + * a new array item in the cellarray. + * + * @param which Array handle + * @param item Item index in the array + * @param input Value to set + * @param block If the array has a cellsize >1 this optionally specifies + * which block to write to + * @param asChar If true writes the value as a byte instead of a cell + * + * @noreturn + * @error If an invalid handle, index or block is provided an + * error will be thrown. + */ +native ArraySetCell(Array:which, item, any:input, block = 0, bool:asChar = false); + +/** + * Sets an item's data to a string value. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * @note The item index must already be valid. Use ArrayPushString to create + * a new array item in the cellarray. + * + * @param which Array handle + * @param item Item index in the array + * @param input String to copy to the array + * + * @return Number of characters copied + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArraySetString(Array:which, item, const input[]); + +/** + * Creates a new item at the end of the cellarray and copies the provided array + * into it. + * + * @note The input will be truncated if it is bigger than the cellsize the array + * was created with. + * + * @param which Array handle + * @param input Array to copy to the cellarray + * @param size If not set, assumes the buffer size is equal to the + * cellsize. Otherwise, the specified size is used. + * + * @return Index of the new entry + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native ArrayPushArray(Array:which, const any:input[], size = -1); + +/** + * Creates a new item at the end of the array and sets the item's single cell + * value. + * + * @param which Array handle + * @param input Value to set + * + * @return Index of the new entry + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native ArrayPushCell(Array:which, any:input); + +/** + * Creates a new item at the end of the array and copies the provided string + * into it. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * + * @param which Array handle + * @param input String to copy to the array + * + * @return Index of the new entry + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native ArrayPushString(Array:which, const input[]); + +/** + * Creates a new item behind the specified item and copies the provided array + * into it. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Array to copy to the cellarray + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertArrayAfter(Array:which, item, const any:input[]); + +/** + * Creates a new item behind the specified item and sets the item's single cell + * value. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Value to set + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertCellAfter(Array:which, item, any:input); + +/** + * Creates a new item behind the specified item and copies the provided string + * into it. All items beyond it get shifted up by one. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * + * @param which Array handle + * @param item Item index in the array + * @param input String to copy to the array + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertStringAfter(Array:which, item, const input[]); + +/** + * Creates a new item in front of the specified item and copies the provided + * array into it. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Array to copy to the cellarray + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertArrayBefore(Array:which, item, const any:input[]); + +/** + * Creates a new item in front of the specified item and sets the item's single + * cell value. All items beyond it get shifted up by one. + * + * @param which Array handle + * @param item Item index in the array + * @param input Value to set + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertCellBefore(Array:which, item, const any:input); + +/** + * Creates a new item in front of the specified item and copies the provided + * string into it. All items beyond it get shifted up by one. + * + * @note The input will be truncated if it is longer than the cellsize the array + * was created with. + * + * @param which Array handle + * @param item Item index in the array + * @param input String to copy to the array + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayInsertStringBefore(Array:which, item, const input[]); + +/** + * Swaps the position of two items. + * + * @param which Array handle + * @param item1,item2 Item pair to swap + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArraySwap(Array:which, item1, item2); + +/** + * Deletes an item from the array. All items beyond it get shifted down by one. + * + * @param which Array handle + * @param item Item to delete + * + * @noreturn + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native ArrayDeleteItem(Array:which, item); + +/** + * Searches through the array and returns the index of the first occurence of + * the specified string. + * + * @param which Array handle + * @param item String to search for + * + * @return Array index on success, -1 if the string can't be found + * @error Invalid handle. + */ +native ArrayFindString(Array:which, const item[]); + +/** + * Searches through the array and returns the index of the first occurence of + * the specified value. + * + * @param which Array handle + * @param item Value to search for + * + * @return Array index on success, -1 if the value can't be found + * @error If an invalid handle is provided an error will be + * thrown. + */ +native ArrayFindValue(Array:which, any:item); + +/** + * Creates a special handle that can be passed to a string format routine for + * printing as a string (with the %a format option). + * + * @note It is recommended to pass the function as a parameter to the format + * routine directly. The array item must contain a null-terminated string! + * @note Do not save or otherwise use the handles returned by this function. + * @note Example usage: + * console_print(id, "%a", ArrayGetStringHandle(MessageArray, i)); + * + * @param which Array handle + * @param item Item to retrieve handle of + * + * @return Handle to the item + * @error If an invalid handle or an invalid index is provided an + * error will be thrown. + */ +native DoNotUse:ArrayGetStringHandle(Array:which, item); + +/** + * Destroys the array and frees its memory. + * + * @note The function automatically sets the variable passed to it to 0 to aid + * in preventing accidental usage after destroy. + * + * @param which Array to destroy + * + * @return 1 if the Array was destroyed, 0 if nothing had to be + * destroyed (invalid handle) + */ +native ArrayDestroy(&Array:which); + +/** + * Similar to sorting.inc's CustomSort, the sorting algorithm then uses the + * custom comparison function to sort the data. + * + * @note The function is called in the following manner: + * + * public MySortFunc(Array:array, item1, item2, const data[], data_size) + * + * array - Array handle in its current un-sorted state + * item1, item2 - Current item pair being compared + * data[] - Extra data array passed to the sort func + * data_size - Size of extra data + * + * @note The comparison function should return: + * -1 if item1 should go before item2 + * 0 if item1 and item2 are equal + * 1 if item1 should go after item2 + * + * @note All parameters after item2 are optional and do not need to be specified + * and used. + * @note Unlike the sorting.inc version, the array passed to the callback is not + * in mid-sorted state. + * + * @param array Array handle + * @param comparefunc Callback function used for comparison + * @param data Extra data that is passed through to the callback + * @param data_size Size of extra data + * + * @noreturn + * @error If an invalid handle or an invalid callback is provided + * an error will be thrown. + */ +native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0); + +/** + * A faster version of ArraySort, the sorting algorithm then uses the custom + * comparison function to sort the data. + * + * @note The advantage of this function is that the data of the elements being + * compared is directly passed to the function, instead of the item + * indexes that are passed by ArraySort. This removes the need for calling + * ArrayGet[Cell|String|Array] every time before being able to compare the + * elements. + * + * @note For Arrays with a cellsize of 1 (used for storing integers and floats), + * the function is called in the following manner: + * + * public MySortFunc(Array:array, elem1, elem2, const data[], data_size) + * + * array - Array handle in its current un-sorted state + * elem1, elem2 - Current element pair being compared + * data[] - Extra data array passed to the sort func + * data_size - Size of extra data + * + * @note For Arrays with a cellsize larger than 1 (used for storing arrays and + * strings), the function is called in the following manner: + * + * public MySortFunc(Array:array, elem1[], elem2[], const data[], data_size) + * + * array - Array handle in its current un-sorted state + * elem1[], elem2[] - Current element pair being compared + * data[] - Extra data array passed to the sort func + * data_size - Size of extra data + * + * + * @note The comparison function should return: + * -1 if elem1 should go before elem2 + * 0 if elem1 and elem2 are equal + * 1 if elem1 should go after elem2 + * + * @note All parameters after item2 are optional and do not need to be specified + * and used. + * @note Unlike the sorting.inc version, the array passed to the callback is not + * in mid-sorted state. + * + * @param array Array handle + * @param comparefunc Callback function used for comparison + * @param data Extra data that is passed through to the callback + * @param data_size Size of extra data + * + * @noreturn + * @error If an invalid handle or an invalid callback is provided + * an error will be thrown. + */ +native ArraySortEx(Array:array, const comparefunc[], data[]="", data_size=0); diff --git a/amxmodx/scripting/include/cellstack.inc b/amxmodx/scripting/include/cellstack.inc new file mode 100644 index 0000000..15e8567 --- /dev/null +++ b/amxmodx/scripting/include/cellstack.inc @@ -0,0 +1,166 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _cellstack_included + #endinput +#endif +#define _cellstack_included + +/** + * Stack tag declaration + * + * @note Plugins are responsible for freeing all Stack handles they acquire. + * Failing to free handles will result in the plugin and AMXX leaking + * memory. + */ +enum Stack +{ + Invalid_Stack = 0 +}; + +/** + * Creates a stack structure. A stack is a LIFO (last in, first out) vector of + * of items. It has O(1) insertion and O(1) removal. + * + * @note Stacks provide only two operations: Push (adding an item to the top) + * and Pop (remove an item from the top, in reverse-push order). + * @note The contents of the stack are uniform; i.e. storing a string and then + * retrieving it as an integer is NOT the same as str_to_num()! + * @note The "blocksize" determines how many cells each stack slot has, it can + * not be changed after creation. + * + * @param blocksize The number of cells each entry in the stack can hold + * + * @return New stack Handle, which must be freed via DestroyStack() + * @error If an invalid blocksize is provided an error will be + * thrown. + */ +native Stack:CreateStack(blocksize = 1); + +/** + * Pushes a value onto the end of the stack, adding a new index. + * + * @note This may safely be used even if the stack has a blocksize greater than + * 1. + * + * @param handle Stack handle + * @param value Value to push + * + * @noreturn + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native PushStackCell(Stack:handle, any:value); + +/** + * Pushes a string onto the end of a stack, truncating it if it is too long. + * + * @param handle Stack handle + * @param value String to push + * + * @noreturn + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native PushStackString(Stack:handle, const value[]); + +/** + * Pushes an array of cells onto the end of a stack. The cells are pushed as a + * block (i.e. the entire array takes up one stack slot), rather than pushing + * each cell individually. + * + * @param handle Stack handle + * @param values Block of values to copy + * @param size If not set, the number of elements copied from the array + * will be equal to the blocksize, if set higher than the + * blocksize, the operation will be truncated, + * + * @noreturn + * @error If an invalid handle is provided or the resizing + * operation runs out of memory, an error will be thrown. + */ +native PushStackArray(Stack:handle, const any:values[], size= -1); + +/** + * Pops a cell value from a stack. + * + * @param handle Stack handle + * @param value Variable to store the value in + * @param block Optionally specify which block to read from (useful if the + * blocksize is > 0) + * @param asChar Optionally read as a byte instead of a cell + * + * @return True on success, false if the stack is empty. + * @error If an invalid handle, invalid block or invalid byte is + * provided, an error will be thrown. + */ +native bool:PopStackCell(Stack:handle, &any:value, block = 0, bool:asChar = false); + +/** + * Pops a string value from a stack. + * + * @param handle Stack handle + * @param buffer Buffer to copy string to + * @param maxlength Maximum size of the buffer + * @param written Variable to store number of characters copied to + * + * @return True on success, false if the stack is empty + * @error If an invalid handle is provided an error will be thrown. + */ +native bool:PopStackString(Stack:handle, buffer[], maxlength, &written = 0); + +/** + * Pops an array of cells from a stack. + * + * @param handle Stack handle + * @param buffer Array to copy value to + * @param size Size of buffer, if not set (-1) assumes the size is equal to + * the stack blocksize + * + * @return True on success, false if the stack is empty + * @error If an invalid handle is provided an error will be thrown. + */ +native bool:PopStackArray(Stack:handle, any:buffer[], size = -1); + +/** + * Returns if a stack is empty. + * + * @param handle Stack handle + * + * @return True if empty, false if not empty + * @error If an invalid handle is provided an error will be thrown. + */ +native bool:IsStackEmpty(Stack:handle); + +/** + * Pops a value off a stack, ignoring it completely. + * + * @param handle Stack handle + * + * @return True if a value was popped, false if stack is empty + * @error If an invalid handle is provided an error will be thrown. + */ +stock PopStack(Stack:handle) +{ + new value; + return PopStackCell(handle, value); +} + +/** + * Destroys a stack and frees its memory. + * + * @note The function automatically sets the variable passed to it to 0 to aid + * in preventing accidental usage after destroy. + * + * @param handle Stack to destroy + * + * @return 1 if the Stack was destroyed, 0 if nothing had to be + * destroyed (invalid handle) + */ +native DestroyStack(&Stack:handle); diff --git a/amxmodx/scripting/include/celltrie.inc b/amxmodx/scripting/include/celltrie.inc new file mode 100644 index 0000000..cf69dfe --- /dev/null +++ b/amxmodx/scripting/include/celltrie.inc @@ -0,0 +1,412 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _celltrie_included + #endinput +#endif +#define _celltrie_included + +/** + * Hash map tag declaration + * + * @note The word "Trie" in this API is historical. As of AMX Mod X 1.8.3, + * tries have been internally replaced with hash tables, which have O(1) + * insertion time instead of O(n). + * @note Plugins are responsible for freeing all Trie handles they acquire. + * Failing to free handles will result in the plugin and AMXX leaking + * memory. + */ +enum Trie +{ + Invalid_Trie = 0 +}; + +/** + * Hash map iterator tag declaration + * + * @note The word "Trie" in this API is historical. As of AMX Mod X 1.8.3, + * tries have been internally replaced with hash tables, which have O(1) + * insertion time instead of O(n). + * @note Plugins are responsible for freeing all TrieIter handles they acquire. + * Failing to free handles will result in the plugin and AMXX leaking + * memory. + */ +enum TrieIter +{ + Invalid_TrieIter = 0 +} + +/** + * Hash map snapshot tag declaration + * + * @note Plugins are responsible for freeing all Snapshot handles they acquire. + * Failing to free handles will result in the plugin and AMXX leaking + * memory. + */ +enum Snapshot +{ + Invalid_Snapshot = 0 +}; + +/** + * Creates a hash map. A hash map is a container that maps strings (called keys) + * to arbitrary values (cells, arrays or strings). + * + * @note Keys in a hash map are unique so there is no more than one entry in the + * map for any given key. + * @note Insertion, deletion, and lookup in a hash map are all considered to be + * fast operations, amortized to O(1), or constant time. + * + * @return New Map handle, which must be freed via TrieDestroy() + */ +native Trie:TrieCreate(); + +/** + * Clears all entries from a Map. + * + * @param handle Map handle + * + * @error If an invalid handle is provided an error will be + * thrown. + * @noreturn + */ +native TrieClear(Trie:handle); + +/** + * Sets a cell value in a hash map, either inserting a new entry or replacing + * an old one. + * + * @param handle Map handle + * @param key Key string + * @param value Value to store + * @param replace If false the operation will fail if the key is already set + * + * @return 1 on success, 0 otherwise + * @error If an invalid handle is provided an error will be + * thrown. + */ +native TrieSetCell(Trie:handle, const key[], any:value, bool:replace = true); + +/** + * Sets a string value in a hash map, either inserting a new entry or replacing + * an old one. + * + * @param handle Map handle + * @param key Key string + * @param value String to store + * @param replace If false the operation will fail if the key is already set + * + * @return 1 on success, 0 otherwise + * @error If an invalid handle is provided an error will be + * thrown. + */ +native TrieSetString(Trie:handle, const key[], const value[], bool:replace = true); + +/** + * Sets an array value in a hash map, either inserting a new entry or replacing + * an old one. + * + * @param handle Map handle + * @param key Key string + * @param buffer Array to store + * @param size Array size + * @param replace If false the operation will fail if the key is already set + * + * @return 1 on success, 0 otherwise + * @error If an invalid handle is provided an error will be + * thrown. or invalid array size + */ +native TrieSetArray(Trie:handle, const key[], const any:buffer[], size, bool:replace = true); + +/** + * Retrieves a cell value from a hash map. + * + * @param handle Map handle + * @param key Key string + * @param value Variable to store value to + * + * @return True on success, false if either the key is not set or the + * value type does not match (value is string or array) + * @error If an invalid handle is provided an error will be + * thrown. + */ +native bool:TrieGetCell(Trie:handle, const key[], &any:value); + +/** + * Retrieves a string from a hash map. + * + * @param handle Map handle + * @param key Key string + * @param output Buffer to copy the value to + * @param outputsize Maximum size of buffer + * @param size Optional variable to store the number of cells written + * to the buffer in + * + * @return True on success, false if either the key is not set or + * the value type does not match (value is cell or array) + * @error If an invalid handle is provided an error will be + * thrown. + */ +native bool:TrieGetString(Trie:handle, const key[], output[], outputsize, &size = 0); + +/** + * Retrieves a string from a hash map. + * + * @param handle Map handle + * @param key Key string + * @param output Array to copy the value to + * @param outputsize Maximum size of array + * @param size Optional variable to store the number of cells written + * to the array in + * + * @return True on success, false if either the key is not set or + * the value type does not match (value is cell or string) + * @error If an invalid handle or array size is provided an error + * will be thrown. + */ +native bool:TrieGetArray(Trie:handle, const key[], any:output[], outputsize, &size = 0); + +/** + * Removes an entry from a hash map. + * + * @param handle Map handle + * @param key Key string + * + * @return True on success, false if the key was never set + * @error If an invalid handle is provided an error will be + * thrown. + */ +native bool:TrieDeleteKey(Trie:handle, const key[]); + +/** + * Checks a hash map for the existence of an entry. + * + * @param handle Map handle + * @param key Key string + * + * @return True if the key is set, false otherwise + * @error If an invalid handle is provided an error will be + * thrown. + */ +native bool:TrieKeyExists(Trie:handle, const key[]); + +/** + * Destroys a hash map and frees its memory. + * + * @note The function automatically sets the variable passed to it to 0 to aid + * in preventing accidental usage after destroy. + * + * @param handle Map handle + * + * @return 1 on success, 0 if an invalid handle was passed in + */ +native TrieDestroy(&Trie:handle); + +/** + * Returns the number of entries in a hash map. + * + * @param handle Map handle + * + * @return Number of elements in the hash map + * @error If an invalid handle is provided an error will be + * thrown. + */ +native TrieGetSize(Trie:handle); + +/** + * Creates a snapshot of all keys in a hash map. If the map is changed + * afterwards, the changes are not reflected in the snapshot. + * Keys are not sorted. + * + * @param handle Map handle + * + * @return New map snapshot handle, which must be freed via + * TrieSnapshotDestroy() + * @error If an invalid handle is provided an error will be + * thrown. + */ +native Snapshot:TrieSnapshotCreate(Trie:handle); + +/** + * Returns the number of keys in a map snapshot. Note that this may be + * different from the size of the map, since the map can change after the + * snapshot of its keys was taken. + * + * @param handle Map snapshot handle + * + * @return Number of keys + * @error If an invalid handle is provided an error will be + * thrown. + */ +native TrieSnapshotLength(Snapshot:handle); + +/** + * Returns the buffer size required to store a given key. That is, it returns + * the length of the key plus one. + * + * @param handle Map snapshot handle + * @param index Key index (starting from 0) + * + * @return Buffer size required to store the key string + * @error If an invalid handle is provided an error will be + * thrown. or index out of range + */ +native TrieSnapshotKeyBufferSize(Snapshot:handle, index); + +/** + * Retrieves the key string of a given key in a map snapshot. + * + * @param handle Map snapshot handle + * @param index Key index (starting from 0) + * @param buffer String buffer + * @param maxlength Maximum buffer length + * + * @return Number of bytes written to the buffer + * @error If an invalid handle is provided an error will be + * thrown. or index out of range + */ +native TrieSnapshotGetKey(Snapshot:handle, index, buffer[], maxlength); + +/** + * Destroys a map snapshot and frees its memory. + * + * @note The function automatically sets the variable passed to it to 0 to aid + * in preventing accidental usage after destroy. + * + * @param handle Map snapshot handle + * + * @return 1 on success, 0 if an invalid handle was passed in + */ +native TrieSnapshotDestroy(&Snapshot:handle); + + +/** + * Creates an iterator for a map. It provides iterative read-only access to the + * maps contents. + * + * @note Removing or adding keys to the underlying map will invalidate all its + * iterators. Updating values of existing keys is allowed and the changes + * will be immediately reflected in the iterator. + * @note Iterators are designed to be short-lived and not stored, and creating + * them is very cheap. Reading data from an iterator is just as fast as + * reading directly from the map. + * @note Just like in snapshots the keys are not sorted. + * + * @return New iterator handle, which must be freed via TrieIterDestroy(). + * @error Invalid Handle + */ +native TrieIter:TrieIterCreate(Trie:handle); + +/** + * Returns if the iterator has reached its end and no more data can be read. + * + * @param handle Iterator handle + * + * @return True if iterator has reached the end, false otherwise + * @error Invalid Handle + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native bool:TrieIterEnded(TrieIter:handle); + +/** + * Advances the iterator to the next key/value pair if one is available. + * + * @param handle Iterator handle + * + * @error Invalid Handle + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native TrieIterNext(TrieIter:handle); + +/** + * Retrieves the key the iterator currently points to. + * + * @param handle Iterator handle. + * @param key Buffer to store the current key in. + * @param outputsize Maximum size of string buffer. + * + * @return Nnumber of bytes written to the buffer + * @error Invalid handle + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native TrieIterGetKey(TrieIter:handle, key[], outputsize); + +/** + * Retrieves the number of elements in the underlying map. + * + * @note When used on a valid iterator this is exactly the same as calling TrieGetSize on the map directly. + * + * @param handle Iterator handle + * + * @return Number of elements in the map + * @error Invalid handle + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native TrieIterGetSize(TrieIter:handle); + +/** + * Retrieves a value at the current position of the iterator. + * + * @param handle Iterator handle + * @param value Variable to store value in + * + * @return True on success, false if the iterator is empty or the current + * value is an array or a string. + * @error Invalid handle + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native bool:TrieIterGetCell(TrieIter:handle, &any:value); + +/** + * Retrieves a string at the current position of the iterator. + * + * @param handle Iterator handle + * @param buffer Buffer to store the string in + * @param outputsize Maximum size of string buffer + * @param size Optional parameter to store the number of bytes written to the buffer. + * + * @return True on success, false if the iterator is empty or the current value + * is not a string. + * @error Invalid handle + * Invalid buffer size + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native bool:TrieIterGetString(TrieIter:handle, buffer[], outputsize, &size = 0); + +/** + * Retrieves an array at the current position of the iterator. + * + * @param handle Iterator handle + * @param buffer Buffer to store the array + * @param outputsize Maximum size of buffer + * @param size Optional parameter to store the number of bytes written to the buffer + * + * @return True on success, false if the iterator is empty or the current + * value is not an array. + * @error Invalid handle + * Invalid buffer size + * Iterator has been closed (underlying map destroyed) + * Iterator is outdated + */ +native bool:TrieIterGetArray(TrieIter:handle, any:array[], outputsize, &size = 0); + +/** + * Destroys an iterator handle. + * + * @param handle Iterator handle. + * + * @return True on success, false if the value was never set. + */ +native TrieIterDestroy(&TrieIter:handle); diff --git a/amxmodx/scripting/include/colorchat.inc b/amxmodx/scripting/include/colorchat.inc new file mode 100644 index 0000000..2416555 --- /dev/null +++ b/amxmodx/scripting/include/colorchat.inc @@ -0,0 +1,142 @@ +/* Fun functions +* +* by Numb +* +* This file is provided as is (no warranties). +*/ + +#if defined _colorchat_included + #endinput +#endif +#define _colorchat_included + +enum Color +{ + NORMAL = 1, // clients scr_concolor cvar color + GREEN, // Green Color + TEAM_COLOR, // Red, grey, blue + GREY, // grey + RED, // Red + BLUE, // Blue +} + +new TeamName[][] = +{ + "", + "TERRORIST", + "CT", + "SPECTATOR" +} + +ColorChat(id, Color:type, const msg[], {Float,Sql,Result,_}:...) +{ + new message[256]; + + switch(type) + { + case NORMAL: // clients scr_concolor cvar color + { + message[0] = 0x01; + } + case GREEN: // Green + { + message[0] = 0x04; + } + default: // White, Red, Blue + { + message[0] = 0x03; + } + } + + vformat(message[1], 251, msg, 4); + + // Make sure message is not longer than 192 character. Will crash the server. + message[192] = '^0'; + + new team, ColorChange, index, MSG_Type; + + if(id) + { + MSG_Type = MSG_ONE; + index = id; + } else { + index = FindPlayer(); + MSG_Type = MSG_ALL; + } + + team = get_user_team(index); + ColorChange = ColorSelection(index, MSG_Type, type); + + ShowColorMessage(index, MSG_Type, message); + + if(ColorChange) + { + Team_Info(index, MSG_Type, TeamName[team]); + } +} + +ShowColorMessage(id, type, message[]) +{ + static bool:saytext_used; + static get_user_msgid_saytext; + if(!saytext_used) + { + get_user_msgid_saytext = get_user_msgid("SayText"); + saytext_used = true; + } + message_begin(type, get_user_msgid_saytext, _, id); + write_byte(id) + write_string(message); + message_end(); +} + +Team_Info(id, type, team[]) +{ + static bool:teaminfo_used; + static get_user_msgid_teaminfo; + if(!teaminfo_used) + { + get_user_msgid_teaminfo = get_user_msgid("TeamInfo"); + teaminfo_used = true; + } + message_begin(type, get_user_msgid_teaminfo, _, id); + write_byte(id); + write_string(team); + message_end(); + + return 1; +} + +ColorSelection(index, type, Color:Type) +{ + switch(Type) + { + case RED: + { + return Team_Info(index, type, TeamName[1]); + } + case BLUE: + { + return Team_Info(index, type, TeamName[2]); + } + case GREY: + { + return Team_Info(index, type, TeamName[0]); + } + } + + return 0; +} + +FindPlayer() +{ + new i = -1; + + while(i <= get_maxplayers()) + { + if(is_user_connected(++i)) + return i; + } + + return -1; +} \ No newline at end of file diff --git a/amxmodx/scripting/include/core.inc b/amxmodx/scripting/include/core.inc new file mode 100644 index 0000000..d78e9b2 --- /dev/null +++ b/amxmodx/scripting/include/core.inc @@ -0,0 +1,202 @@ +/* Core functions +* +* (c) Copyright 1998-2003, ITB CompuPhase +* +* This file is provided as is (no warranties). +*/ + +#if defined _core_included + #endinput +#endif +#define _core_included + +/** + * Returns the free memory space available to the plugin. + * + * @note This is a debugging function that is not intended for general plugin + * use. + * + * @return Free memory space in bytes + */ +native heapspace(); + +/** + * Returns the function index of a public function declared in the plugin. + * + * @param name Function name + * + * @return Function index > 0 on success, -1 if function was not found + * @error If the function name is too long (longer than 63 characters) + * an error will be thrown. + */ +native funcidx(const name[]); + +/** + * Returns the number of arguments passed into the currently executed function. + * + * @return Number of arguments passed + */ +native numargs(); + +/** + * Retrieves an argument value passed into the currently executed function. + * + * @param arg Argument index + * @param index Index to retrieve from the argument (for arrays and strings) + * + * @return Argument value at given index + */ +native getarg(arg, index = 0); + +/** + * Sets the value of an argument passed into the currently executed function. + * + * @note This is not equal to assigning a new value to a by-reference argument. + * + * @param arg Argument index + * @param index Index to set in the argument (for arrays and strings) + */ +native setarg(arg, index = 0, value); + +/** + * Converts a character to lowercase. + * + * @note This is not UTF8 or locale-safe. + * + * @param c Character to convert + * + * @return Converted character + */ +native tolower(c); + +/** + * Converts a character to uppercase. + * + * @note This is not UTF8 or locale-safe. + * + * @param c Character to convert + * + * @return Converted character + */ +native toupper(c); + +/** + * Swaps the bytes of a value (the lowest byte becomes the highest byte). + * + * @param c Value to swap + * + * @return Byte-swapped value + */ +native swapchars(c); + +/** + * Returns a random number between 0 and a specified upper bound. + * + * @param max Exclusive upper bound + * + * @return Random value + */ +native random(max); + +/** + * Returns the smaller of two provided values. + * + * @param value1 Value one + * @param value2 Value two + * + * @return Smaller of the two values + */ +native min(value1, value2); + +/** + * Returns the bigger of two provided values. + * + * @param value1 Value one + * @param value2 Value two + * + * @return Bigger of the two values + */ +native max(value1, value2); + +/** + * Limits a provided value between two specified bounds. + * + * @param value Value to clamp + * @param min Lower bound + * @param max Upper bound + * + * @return The value if it is between the lower and upper bound, min if + * value is below, max if it is above the specified bounds. + */ +native clamp(value, min = cellmin, max = cellmax); + +/** + * Returns a value raised to a specified exponent. + * + * @param value Value + * @param exponent Exponent to raise value to + * + * @return Value to the power of exponent + */ +native power(value, exponent); + +/** + * Returns the approximated square root of a value. + * + * @note This uses a simple successice approximation algorithm (continuously + * dividing the value) and only deals with integers, this makes it very + * imprecise. + * + * @param value Value + * + * @return Square root of the value + */ +native sqroot(value); + +/** + * Retrieves the current time in hours, minutes and seconds. + * + * @param hour Variable to store hours in + * @param minute Variable to store minutes in + * @param second Variable to store seconds in + * + * @return Unix timestamp + */ +native time(&hour = 0, &minute = 0, &second = 0); + +/** + * Retrieves the current date in year, month and day. + * + * @param year Variable to store year in + * @param month Variable to store month in + * @param day Variable to store day in + * + * @noreturn + */ +native date(&year = 0, &month = 0, &day = 0); + +/** + * Returns the elapsed CPU seconds. + * + * @note This is a debugging function that is not intended for general plugin + * use. + * @note This uses the C clock() function internally and comes with all its + * drawbacks attached. + * + * @param granularity Unused + * + * @return Number of CPU seconds elapsed + */ +native tickcount(&granularity = 0); + +/** + * Returns the absolute value of a number. + * + * @param x Integral value + * + * @return Absolute value of x (x if it is greater than 0, -x otherwise) + */ +stock abs(x) +{ + return x > 0 ? x : -x; +} diff --git a/amxmodx/scripting/include/csstats.inc b/amxmodx/scripting/include/csstats.inc new file mode 100644 index 0000000..84b7a4d --- /dev/null +++ b/amxmodx/scripting/include/csstats.inc @@ -0,0 +1,298 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _csstats_included + #endinput +#endif +#define _csstats_included + +#include + +/** + * Retrieves the client's current weapon statistics. + * + * @note For a list of default CS weapon ids see the CSW_* constants in + * amxconst.inc, this function also works on custom weapons. + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * + * @param index Client index + * @param wpnindex Weapon id, or 0 to retrieve total statistics across all + * weapons + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * + * @return 1 on success, 0 if no statistics are available for the weapon + * id + * @error If an invalid client index or weapon id is provided, an + * error will be thrown. + */ +native get_user_wstats(index, wpnindex, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS]); + +/** + * Retrieves the client's weapon statistics from the current round. + * + * @note For a list of default CS weapon ids see the CSW_* constants in + * amxconst.inc, this function also works on custom weapons. + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * + * @param index Client index + * @param wpnindex Weapon id, or 0 to retrieve total statistics across all + * weapons + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * + * @return 1 on success, 0 if no statistics are available for the + * weapon id + * @error If an invalid client index or weapon id is provided, an + * error will be thrown. + */ +native get_user_wrstats(index, wpnindex, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS]); + +/** + * Retrieves the client's weapon statistics from the permanent storage on the + * server. + * + * @note The permanent storage is updated on every respawn or client disconnect. + * @note Player rank is determined by the customizable "get_score" function in + * "data/csstats.amxx". By default it uses the difference of kills to + * deaths/teamkills. + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * 7 - Rank + * + * @param index Client index + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * + * @return Players rank > 0 on success, or 0 if player is not ranked + * and no statistics are available + * @error If an invalid client index is provided, an error will be + * thrown. + */ +native get_user_stats(index, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS]); + +/** + * Retrieves the client's statistics from the current round. + * + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * + * @param index Client index + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * + * @return 1 on success, 0 if no statistics are available + * @error If an invalid client index is provided, an error will be + * thrown. + */ +native get_user_rstats(index, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS]); + +/** + * Retrieves the client's statistics inflicted upon another client from the + * current round. + * + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * + * @param index Client index + * @param victim Victim client index, or 0 to retrieve the statistics against + * all victims + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * @param wpnname Optional buffer to copy last used weapon name to + * @param len Maximum buffer size + * + * @return 1 on success, 0 if no statistics are available against the + * specified victim + * @error If an invalid client index is provided, an error will be + * thrown. + */ +native get_user_vstats(index, victim, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS], wpnname[] = "", len = 0); + +/** + * Retrieves the client's statistics received from another client from the + * current round. + * + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * + * @param index Client index + * @param wpnindex Attacker client index, or 0 to retrieve the statistics from + * all attackers + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * @param wpnname Optional buffer to copy last used weapon name to + * @param len Maximum buffer size + * + * @return 1 on success, 0 if no statistics are available against the + * specified attacker + * @error If an invalid client index is provided, an error will be + * thrown. + */ +native get_user_astats(index, wpnindex, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS], wpnname[] = "", len = 0); + +/** + * Resets the current round weapon, attacker and victim statistics. + * + * @param index Client index + * + * @noreturn + * @error If an invalid client index is provided, an error will be + * thrown. + */ +native reset_user_wstats(index); + +/** + * Retrieves statistics from the permanent storage on the server via iterative, + * incremental access. + * + * @note The permanent storage is updated on every respawn or client disconnect. + * @note Player rank is determined by the customizable "get_score" function in + * "data/csstats.amxx". By default it uses the difference of kills to + * deaths/teamkills. + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - Kills + * 1 - Deaths + * 2 - Headshots + * 3 - Teamkills + * 4 - Shots + * 5 - Hits + * 6 - Damage + * 7 - Rank + * + * @param index Rank index + * @param stats Buffer to copy statistics to + * @param bodyhits Buffer to copy body hits to + * @param name Buffer to copy client name to + * @param len Maximum name buffer size + * @param authid Buffer to copy client auth id to + * @param authidlen Maximum authid buffer size + * + * @return Next rank index (> 0 and > index), or 0 if no more + * statistics exist + */ +native get_stats(index, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS], name[], len, authid[] = "", authidlen = 0); + +/** + * Returns the number of all entries in the permanent statistics storage. + * + * @return Number of entries in statistics storage + */ +native get_statsnum(); + +/** + * Retrieves the client's objective statistics from the permanent storage. + * + * @note The permanent storage is updated on every respawn or client disconnect. + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - total defusions + * 1 - bomb defused + * 2 - bomb plants + * 3 - bomb explosions + * + * @param index Client index + * @param stats Buffer to copy statistics to + * + * @return Players rank > 0 on success, or 0 if player is not ranked + * and no statistics are available + * @error If an invalid client index is provided, an error will be + * thrown. + */ +native get_user_stats2(index, stats[STATSX_MAX_OBJECTIVE]); + +/** + * Retrieves objective statistics from the permanent storage on the server via + * iterative, incremental access. + * + * @note The permanent storage is updated on every respawn or client disconnect. + * @note For a list of possible stat constants see the STATSX_* constants in + * amxconst.inc + * @note The fields in the statistics are: + * 0 - total defusions + * 1 - bomb defused + * 2 - bomb plants + * 3 - bomb explosions + * + * @param index Client index + * @param stats Buffer to copy statistics to + * @param authid Buffer to copy client auth id to + * @param authidlen Maximum authid buffer size + * + * @return Next rank index (> 0 and > index), or 0 if no more + * statistics exist + */ +native get_stats2(index, stats[STATSX_MAX_OBJECTIVE], authid[] = "", authidlen = 0); diff --git a/amxmodx/scripting/include/csstats_const.inc b/amxmodx/scripting/include/csstats_const.inc new file mode 100644 index 0000000..a392d1b --- /dev/null +++ b/amxmodx/scripting/include/csstats_const.inc @@ -0,0 +1,29 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Counter-Strike Functions +// + +#if defined _csstats_const_included + #endinput +#endif +#define _csstats_const_included + +/** + * Constants for objective based statistics + */ +enum +{ + STATSX_TOTAL_DEFUSIONS = 0, + STATSX_BOMBS_DEFUSED, + STATSX_BOMBS_PLANTED, + STATSX_BOMB_EXPLOSIONS, + STATSX_MAX_OBJECTIVE +} diff --git a/amxmodx/scripting/include/cstrike.inc b/amxmodx/scripting/include/cstrike.inc new file mode 100644 index 0000000..bb366f4 --- /dev/null +++ b/amxmodx/scripting/include/cstrike.inc @@ -0,0 +1,1287 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Counter-Strike Functions +// + +#if defined _cstrike_included + #endinput +#endif +#define _cstrike_included + +#pragma reqlib cstrike +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib cstrike +#endif + +#include + +/** + * Returns client's deaths. + * + * @param index Client index + * + * @return Client deaths + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_deaths(index); + +/** + * Sets client's deaths. + * + * @param index Client index + * @param newdeaths New value to set + * @param scoreboard If true the scoreboard will be updated to reflect the new value. + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_set_user_deaths(index, newdeaths, bool:scoreboard = true); + +/** + * Returns index of the entity that a hostage is following. + * + * @note Hostages can theoretically follow any entity in the game, so the + * returned entity index is not necessarily a client index. + * + * @param index Hostage entity index + * + * @return Entity index if hostage is following something, 0 otherwise + * @error If the provided entity index is not a hostage, an error will + * be thrown. + */ +native cs_get_hostage_foll(index); + +/** + * Sets hostage to follow an entity. + * + * @note Hostages can theoretically follow any entity in the game, so the + * followedindex does not have to be a client index. + * + * @param index Hostage entity index + * @param followedindex New entity to follow + * + * @noreturn + * @error If the provided entity index is not a hostage, an + * error will be thrown. + */ +native cs_set_hostage_foll(index, followedindex = 0); + +/** + * Returns unique id of a hostage. + * + * @param index Hostage entity index + * + * @return Unique hostage id + * @error If the provided entity index is not a hostage, an error will + * be thrown. + */ +native cs_get_hostage_id(index); + +/** + * Returns amount of ammo in the client's backpack for a specific weapon. + * + * @note For a list of possible weapon ids see the CSW_* constants in + * amxconst.inc + * @note Some weapons share ammo types and therefore ammo backpack pools. List + * of ammo types: + * ammo_338magnum - awp + * ammo_762nato - scout, ak47, g3sg1 + * ammo_556natobox - m249 + * ammo_556nato - famas, m4a1, aug, sg550, galil, sg552 + * ammo_buckshot - m3, xm1014 + * ammo_45acp - usp, ump45, mac10 + * ammo_57mm - fiveseven, p90 + * ammo_50ae - deagle + * ammo_357sig - p228 + * ammo_9mm - glock, mp5, tmp, elites + * / - hegrenade + * / - flashbang + * / - smokegrenade + * + * @param index Client index + * @param weapon Weapon id + * + * @return Amount of ammo in backpack + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, or an invalid + * weapon id is provided, an error will be thrown. + */ +native cs_get_user_bpammo(index, weapon); + +/** + * Sets amount of ammo in the client's backpack for a specific weapon. + * + * @note For a list of possible weapon ids see the CSW_* constants in + * amxconst.inc + * @note Some weapons share ammo types and therefore ammo backpack pools. List + * of ammo types: + * ammo_338magnum - awp + * ammo_762nato - scout, ak47, g3sg1 + * ammo_556natobox - m249 + * ammo_556nato - famas, m4a1, aug, sg550, galil, sg552 + * ammo_buckshot - m3, xm1014 + * ammo_45acp - usp, ump45, mac10 + * ammo_57mm - fiveseven, p90 + * ammo_50ae - deagle + * ammo_357sig - p228 + * ammo_9mm - glock, mp5, tmp, elites + * / - hegrenade + * / - flashbang + * / - smokegrenade + * + * @param index Client index + * @param weapon Weapon id + * @param amount New backpack ammo amount to set + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, or an invalid + * weapon id is provided, an error will be thrown. + */ +native cs_set_user_bpammo(index, weapon, amount); + +/** + * Returns if the client has a defuse kit. + * + * @param index Client index + * + * @return 1 if the client has a defuse kit, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, or an invalid + * weapon id is provided, an error will be thrown. + */ +native cs_get_user_defuse(index); + +/** + * Sets the client's defusekit status and allows to set a custom HUD icon and + * color. + * + * @param index Client index + * @param defusekit If nonzero the client will have a defusekit, otherwise + * it will be removed + * @param r Red component of icon color + * @param g Green component of icon color + * @param b Blue component of icon color + * @param icon HUD sprite to use as icon + * @param flash If nonzero the icon will flash red + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_set_user_defuse(index, defusekit = 1, r = 0, g = 160, b = 0, icon[] = "defuser", flash = 0); + +/** + * Returns if the client is inside a buyzone. + * + * @param index Client index + * + * @return 1 if the client is inside a buyzone, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_buyzone(index); + +/** + * Returns if the client has a primary weapon or a shield in the inventory. + * + * @param index Client index + * + * @return 1 if the client has a primary weapon or shield in the + * inventory, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_hasprim(index); + +/** + * Retrieves the client's player model. + * + * @param index Client index + * @param model Buffer to copy model to + * @param len Maximum buffer size + * + * @return Number of cells written to buffer + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_model(index, model[], len); + +/** + * Sets the client's player model. + * + * @note This is not a one-time set. The CStrike module will remember the + * selected model and try to prevent attempts at changing the player + * model, or immediately re-apply it if necessary. + * @note Updating modelindex is useful for custom models which don't have + * the same structure as the default ones (hitbox, etc..). Model must + * be precached before. + * + * @param index Client index + * @param model Model name + * @param update_index If true, the modelindex is updated as well + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, the provided + * model is empty, or if modeindex is updated and the + * provided model is not precached, an error will be thrown. + */ +native cs_set_user_model(index, const model[], bool:update_index = false); + +/** + * Resets the client's model. + * + * @note This lifts the model-lock set by a previous cs_set_user_model() call. + * + * @param index Client index + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_reset_user_model(index); + +/** + * Returns the client's amount of money. + * + * @param index Client index + * + * @return Amount of money + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_money(index); + +/** + * Sets the client's amount of money. + * + * @param index Client index + * @param money New amount to set + * @param flash If nonzero the HUD will flash the difference between new + * and old amount in red or green + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_set_user_money(index, money, flash = 1); + +/** + * Returns if the client's has night vision goggles. + * + * @param index Client index + * + * @return 1 if user has NVG, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_nvg(index); + +/** + * Sets the client's night vision goggles. + * + * @param index Client index + * @param nvgoogles If nonzero the NVG will be added to the client's + * inventory, otherwise they will be removed from it + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_set_user_nvg(index, nvgoggles = 1); + +/** + * Returns if the client has the ability to plant the bomb. + * + * @note Only with this set can the client plant the bomb within the usual bomb + * target areas. If this is not set the user can not plant the bomb, even + * when he has one in the inventory. + * + * @param index Client index + * + * @return 1 if the client is able to plant the bomb, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_plant(index); + +/** + * Sets the client's ability to plant the bomb and displays or hides the bomb + * HUD icon. + * + * @note Only with this set can the client plant the bomb within the usual bomb + * target areas. If this is not set the user can not plant the bomb, even + * when he has one in the inventory. This is only correctly set when the + * client touches a bomb and picks it up "manually" (only possible for + * Terrorists), so this should be used if the bomb is added to the + * inventory through other means. + * + * @param index Client index + * @param plant If nonzero the client will be able to plant the bomb, + * otherwise he will be unable to + * @param showbombicon If nonzero the green C4 icon will be displayed on the + * client's hud, otherwise it will be hidden + * + * @return 1 if the client is able to plant the bomb, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_set_user_plant(index, plant = 1, showbombicon = 1); + +/** + * Sets the client's team without killing the player, and sets the client model. + * + * @note For a list of valid team ids see the CsTeams enum, and for a list of + * valid internal model ids see the CsInternalModel enum. + * + * @param index Client index + * @param team Team id + * @param model Internal model id, if CS_DONTCHANGE the game will choose the model + * or if CS_NORESET the game will not update it. + * @param send_teaminfo If true, a TeamInfo message will be sent + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_set_user_team(index, any:team, any:model = CS_DONTCHANGE, bool:send_teaminfo = true); + +/** + * Returns the client's team and optionally the model id. + * + * @note For a list of valid team ids see the CsTeams enum, and for a list of + * valid internal model ids see the CsInternalModel enum. + * + * @param index Client index + * @param model Optional variable to store model id in + * + * @return Team id + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native CsTeams:cs_get_user_team(index, &any:model = CS_DONTCHANGE); + +/** + * Returns if the client is a VIP. + * + * @param index Client index + * + * @return 1 if the client is a VIP, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_vip(index); + +/** + * Sets the client's VIP status and displayed model and scoreboard flag. + * + * @note This is mostly useful for removing VIP status so the client can change + * teams and/or buy items properly. It does not alter gameplay, the player + * that is selected as VIP at the start of a round will retain the + * internal VIP status and remain the primary objective for the game mode. + * + * @param index Client index + * @param vip If nonzero the client will be made a VIP, otherwise the + * VIP status will be removed + * @param model If nonzero the client's model will be changed to the VIP + * model, otherwise a random CT model will be selected + * @param scoreboard If nonzero the scoreboard will be updated to reflect the + * new VIP status + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_set_user_vip(index, vip = 1, model = 1, scoreboard = 1); + +/** + * Returns if the client has committed a team kill in the current round. + * + * @note If this is set to 1 the client will be punished at the start of the + * next round depending on the value of the mp_tkpunish cvar. The team + * kill status is then reset. + * + * @param index Client index + * + * @return 1 if the client has committed a team kill, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_tked(index); + +/** + * Sets the client's team kill status, indicating whether the client has + * committed a team kill in the current round. + * + * @note If this is set to 1 the client will be punished at the start of the + * next round depending on the value of the mp_tkpunish cvar. The team + * kill status is then reset. + * + * @param index Client index + * @param tk Team kill status + * @param subtract Amount of frags to subtract, negative values add frags + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_set_user_tked(index, tk = 1, subtract = 1); + +/** + * Returns if the client is currently driving a vehicle and if so, indicates + * the speed. + * + * @param index Client index + * + * @return 0 if the client is not driving, 1 if driving a vehicle but + * not moving, 2 to 4 if driving positive speeds, 5 if + * driving at a negative speed (backing), see TRAIN_* constants + * in hlsdk_const.inc + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_driving(index); + +/** + * Returns if the client has a shield in the inventory. + * + * @param index Client index + * + * @return 1 if the client has a shield, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_shield(index); + +/** + * Returns if the client is using a stationary gun. + * + * @param index Client index + * + * @return 1 if the client uses a stationary gun, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_stationary(index); + +/** + * Returns the client's armor value and retrieves the type of armor. + * + * @note For a list of possible armor types see the CsArmorType enum. + * + * @param index Client index + * @param armortype Variable to store armor type in + * + * @return Amount of armor, 0 if client has no armor + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_get_user_armor(index, &CsArmorType:armortype = CS_ARMOR_NONE); + +/** + * Sets the client's armor value the type of armor. + * + * @note For a list of possible armor types see the CsArmorType enum. + * @note Sends the appropriate message to update the client's HUD. + * + * @param index Client index + * @param armorvalue Amount of armor to set + * @param armortype CS armor type + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native cs_set_user_armor(index, armorvalue, CsArmorType:armortype); + +/** + * Returns if the weapon is in burst mode. + * + * @note Only the Glock and Famas can return 1 as they are the only guns in the + * game that have a burst fire mode. + * @note This native does not verify that the provided entity is a weapon + * entity. It will return incorrect values for non-weapon entities. + * + * @param index Weapon entity index + * + * @return 1 if the weapon is in burst mode, 0 otherwise + * @error If an invalid entity index or a client index is provided, + * an error will be thrown. + */ +native cs_get_weapon_burst(index); + +/** + * Sets the weapon's burst mode. + * + * @note Only the Glock and Famas can be set to burst fire mode as they are the + * only guns in the game that provide such a mode. + * @note This native does not verify that the provided entity is a weapon + * entity. It will result in undefined behavior if used on non-weapon + * entities. + * + * @param index Weapon entity index + * @param burstmode If nonzero the weapon will be put into burstmode, + * otherwise the burst mode will be removed + * + * @return 1 if burst mode set successfully, 0 if entity is not + * an applicable weapon + * @error If an invalid entity index or a client index is + * provided, an error will be thrown. + */ +native cs_set_weapon_burst(index, burstmode = 1); + +/** + * Returns if the weapon is in silenced mode. + * + * @note Only the USP and M4A1 can return 1 as they are the only guns in the + * game that have a silenced fire mode. + * @note This native does not verify that the provided entity is a weapon + * entity. It will return incorrect values for non-weapon entities. + * + * @param index Weapon entity index + * + * @return 1 if the weapon is in silenced mode, 0 otherwise + * @error If an invalid entity index or a client index is provided, + * an error will be thrown. + */ +native cs_get_weapon_silen(index); + +/** + * Sets the weapon's silenced mode. + * + * @note Only the USP and M4A1 can be set to silenced fire mode as they are the + * only guns in the game that provide such a mode. + * @note This native does not verify that the provided entity is a weapon + * entity. It will result in undefined behavior if used on non-weapon + * entities. + * + * @param index Weapon entity index + * @param silence If nonzero the weapon will be put into silenced + * mode, otherwise the silenced mode will be removed + * @param draw_animation If 1 and the weapon is currently held by a + * client, the appropriate weapon animation will be + * played + * If 2, same as 1 but follows game behavior by playing + * the associated player's model sequence and disallowing + * firing while animation is playing. + * + * @return 1 if silenced mode set successfully, 0 if entity is + * not an applicable weapon + * @error If an invalid entity index or a client index is + * provided, an error will be thrown. + */ +native cs_set_weapon_silen(index, silence = 1, draw_animation = 1); + +/** + * Returns the amount of ammo in weapon's magazine. + * + * @note This native does not verify that the provided entity is a weapon + * entity. It will return incorrect values for non-weapon entities. + * + * @param index Weapon entity index + * + * @return Amount of ammo in magazine + * @error If an invalid entity index or a client index is provided, + * an error will be thrown. + */ +native cs_get_weapon_ammo(index); + +/** + * Sets the amount of ammo in weapon's clip. + * + * @note This native does not verify that the provided entity is a weapon + * entity. It will result in undefined behavior if used on non-weapon + * entities. + * + * @param index Weapon entity index + * @param newammo New ammo amount + * + * @noreturn + * @error If an invalid entity index or a client index is provided, + * an error will be thrown. + */ +native cs_set_weapon_ammo(index, newammo); + +/** + * Returns the weapon id of an entity. + * + * @note For a list of possible weapon ids see the CSW_* constants in + * amxconst.inc + * @note This native does not verify that the provided entity is a weapon + * entity. It will return incorrect values for non-weapon entities. + * + * @param index Weapon entity index + * + * @return Weapon id + * @error If an invalid entity index or a client index is provided, + * an error will be thrown. + */ +native cs_get_weapon_id(index); + +/** + * Returns if "no knives" mode is enabled. + * + * @note "No knives" mode means that the CStrike module will prevent the game + * from creating (and thus attaching) "weapon_knife" entities. This means + * that clients will spawn without knives, but knives can still be put + * into the client inventories directly. + * + * @return 1 if "no knives" mode is enabled, 0 otherwise + */ +native cs_get_no_knives(); + +/** + * Enables or disables the "no knives" mode. + * + * @note "No knives" mode means that the CStrike module will prevent the game + * from creating (and thus attaching) "weapon_knife" entities. This means + * that clients will spawn without knives, but knives can still be put + * into the client inventories directly. + * + * @param noknives If nonzero enable "no knives" mode, disable otherwise + * + * @noreturn + */ +native cs_set_no_knives(noknives = 0); + +/** + * Sets a dead client up for spawning. + * + * @note This sets the client deadflag and triggers a client think, effectively + * making the game respawn the client. Should only be used on dead + * clients. + * + * @param player Client index + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_user_spawn(player); + +/** + * Returns the armoury entity's weapon id. + * + * @note Not all weapon ids are supported by Counter-Strike, an armoury entity + * can not be a pistol, a knife or a bomb for exmaple. The full list is: + * CSW_SCOUT, CSW_HEGRENADE, CSW_XM1014, CSW_MAC10, CSW_AUG, + * CSW_SMOKEGRENADE, CSW_AWP, CSW_MP5NAVY, CSW_M249, CSW_M3, CSW_M4A1, + * CSW_TMP, CSW_G3SG1, CSW_VEST, CSW_VESTHELM, CSW_FLASHBANG, + * CSW_SG552, CSW_AK47, CSW_P90 + * + * @param index Armoury entity index + * @param count Optional variable to store in the number of times that an item can be retrieved + * from the same entity before being hidden + * + * @return Weapon id + * @error If a non-armoury entity is provided, an error will be + * thrown. + */ +native cs_get_armoury_type(index, &count = 1); + +/** + * Sets the amoury entity type. + * + * @note Not all weapon ids are supported by Counter-Strike, an armoury entity + * can not be a pistol, a knife or a bomb for exmaple. The full list is: + * CSW_SCOUT, CSW_HEGRENADE, CSW_XM1014, CSW_MAC10, CSW_AUG, + * CSW_SMOKEGRENADE, CSW_AWP, CSW_MP5NAVY, CSW_M249, CSW_M3, CSW_M4A1, + * CSW_TMP, CSW_G3SG1, CSW_VEST, CSW_VESTHELM, CSW_FLASHBANG, + * CSW_SG552, CSW_AK47, CSW_P90 + * @note This does not update the entity model. + * @note On restart, entity is always unhidden and the count is restored (this can not be below 1). + * + * @param index Armoury entity index + * @param type Weapon id + * @param count Number of times that an item can be retrieved from + * the same entity before being hidden + * If zero, the entity is hidden + * If below zero, nothing is set + * @noreturn + * @error If a non-armoury entity is provided, an error will be + * thrown. + */ +native cs_set_armoury_type(index, type, count = -1); + +/** + * Returns the weapon entity index that was packed into a weaponbox. + * + * @param weaponboxIndex Weaponbox entity index + * + * @return Weapon entity index on success or 0 if no weapon can be found + * @error If a non-weaponbox entity is provided or the entity is invalid, an error will be + * thrown. + */ +native cs_get_weaponbox_item(weaponboxIndex); + +/** + * Returns the map zones the client is inside of as a bitflag value. + * + * @note If the user does not have the ability to plant (cs_get_user_plant() + * returns 0) then the bitflag will not contain CS_MAPZONE_BOMBTARGET. + * @nore For a list of possible zone flags see the CS_MAPZONE_* constants. + * + * @param index Client index + * + * @return Bitflag value of map zones + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_mapzones(index); + +/** + * Sets a zoom type on the client. + * + * @note Zoom types are not tied to their intended weapons, so any zoom type can + * be combined with any weapon. + * @note For a list of possible zoom types see the zoom type enum above + * (CS_*_ZOOM constants). + * + * @param index Client index + * @param type Zoom type + * @param mode If zero (blocking) the client will be forced to use the zoom + * type set and won't be able to change it until it is reset + * with CS_RESET_ZOOM, otherwise the user can restore back to + * normal as usual + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, or an invalid zoom + * type is provided, an error will be thrown. + */ +native cs_set_user_zoom(index, type, mode); + +/** + * Returns if the client is zooming. + * + * @note For a list of possible zoom types see the zoom type enum above + * (CS_*_ZOOM constants). + * + * @param index Client index + * + * @return Zoom type if the user is zoomed in, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_zoom(index); + +/** + * Returns if a submodel is set on the client. + * + * @note In Counter-Strike the submodel setting determines whether the user has + * a bomb backpack (if a Terrorist) or a defuse kit (if a CT) on their + * model. + * + * @param index Client index + * + * @return 1 if submodel is set, 0 otherwise + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_submodel(index); + +/** + * Sets the submodel on a client. + * + * @note In Counter-Strike the submodel setting determines whether the user has + * a bomb backpack (if a Terrorist) or a defuse kit (if a CT) on their + * model. + * + * @param index Client index + * @param value If nonzero the submodel is set, otherwise it is removed + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + */ +native cs_set_user_submodel(index, value); + +/** + * Returns the client's last activity time. + * + * @note This is the time that the internal Counter-Strike afk kicker uses to + * see who has been inactive too long. + * + * @param index Client index + * + * @return Last activity time + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + */ +native Float:cs_get_user_lastactivity(index); + +/** + * Sets the client's last activity time. + * + * @note This is the time that the internal Counter-Strike afk kicker uses to + * see who has been inactive too long. + * + * @param index Client index + * @param value New last activity time + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + */ +native cs_set_user_lastactivity(index, Float:value); + +/** + * Returns the amount of hostages that the client has killed. + * + * @note This is the value that the internal Counter-Strike hostage punisher + * uses to determine if a client should be kicked, depending on the + * value of the mp_hostagepenalty value. + * + * @param index Client index + * + * @return Amount of hostages killed + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + */ +native cs_get_user_hostagekills(index); + +/** + * Sets the amount of hostages that the client has killed. + * + * @note This is the value that the internal Counter-Strike hostage punisher + * uses to determine if a client should be kicked, depending on the + * value of the mp_hostagepenalty value. The punisher only checks this + * value when a hostage is killed, so setting this will not cause the + * client to be kicked until they actually kill a hostage. + * + * @param index Client index + * @param value New amount of hostages killed + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + */ +native cs_set_user_hostagekills(index, value); + +/** + * Returns the last time a hostage was used. + * + * @param index Hostage entity + * + * @return Last use time + * @error If the provided entity index is not a hostage, an error will + * be thrown. + */ +native Float:cs_get_hostage_lastuse(index); + +/** + * Sets the last time a hostage was used. + * + * @param index Hostage entity + * @param value New last use time + * + * @noreturn + * @error If the provided entity index is not a hostage, an error will + * be thrown. + */ +native cs_set_hostage_lastuse(index, Float:value); + +/** + * Returns the next time a hostage can be used. + * + * @param index Hostage entity + * + * @return Next use time + * @error If the provided entity index is not a hostage, an error will + * be thrown. + */ +native Float:cs_get_hostage_nextuse(index); + +/** + * Sets the next time a hostage can be used. + * + * @param index Hostage entity + * @param value New next use time + * + * @noreturn + * @error If the provided entity index is not a hostage, an error will + * be thrown. + */ +native cs_set_hostage_nextuse(index, Float:value); + +/** + * Returns the game time at which the bomb will explode. + * + * @param index C4 entity + * + * @return Explosion time + * @error If the provided entity index is not a bomb, an error will be + * thrown. + */ +native Float:cs_get_c4_explode_time(index); + +/** + * Sets the game time at which the bomb will explode. + * + * @param index C4 entity + * @param value New explosion time + * + * @noreturn + * @error If the provided entity index is not a bomb, an error will be + * thrown. + */ +native cs_set_c4_explode_time(index, Float:value); + +/** + * Returns if the bomb is being defused. + * + * @param c4index C4 entity + * + * @return 1 if the bomb is being defused, 0 otherwise + * @error If the provided entity index is not a bomb, an error will be + * thrown. + */ +native bool:cs_get_c4_defusing(c4index); + +/** + * Sets if the bomb is being defused. + * + * @param c4index C4 entity + * @param defusing True if the bomb should be defused, false otherwise + * + * @noreturn + * @error If the provided entity index is not a bomb, an error will be + * thrown. + */ +native cs_set_c4_defusing(c4index, bool:defusing); + +/** + * Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper. + * + * @note Unlike other mods CS keeps track of entities using a custom hashtable. + * This function adds entities to this hashtable, providing benefits over + * the default CreateNamedEntity (used by create_entity() for example): + * - Storing entities in a hashtable allows CS to improve classname lookup + * performance compared to functions like FindEntityByString (used by + * find_ent_by_class() for example) that usually have to loop + * through all entities incrementally. + * - As CS exclusively uses the hashtable for classname lookup, entities + * created using the default engine functions will not be found by the + * game. For example "weaponbox" entities are supposed to be + * automatically cleaned up on round restart but are not considered if + * they have not been added to the hashtable. + * @note The faster hashtable lookup can be utilized with cs_find_ent_by_class() + * @note When creating an entity the classname has to be valid in the mod, as + * the engine needs to link the entity to an existing class internally. + * The classname string that is stored in the entvar struct + * (EV_SZ_classname) is separate from this association and can later be + * freely changed to serve other purposes. + * + * @param classname Entity class name + * + * @return Index of the created entity (> 0), 0 otherwise + */ +native cs_create_entity(const classname[]); + +/** + * Finds an entity in the world using Counter-Strike's custom FindEntityByString + * wrapper. + * + * @note Unlike other mods CS keeps track of entities using a custom hashtable. + * This function utilizes the hasthable and allows for considerably faster + * classname lookup compared to the default FindEntityByString (used by + * find_ent_by_class() for example). + * @note This exclusively considers entities in the hashtable, created by the + * game itself, using cs_create_entity(), or added via cs_set_ent_class(). + * + * @param start_index Entity index to start searching from. -1 to start from + * the first entity + * @param classname Classname to search for + * + * @return Entity index > 0 if found, 0 otherwise + */ +native cs_find_ent_by_class(start_index, const classname[]); + +/** + * Finds an entity in the world using Counter-Strike's custom FindEntityByString + * wrapper, matching by owner. + * + * @note Unlike other mods CS keeps track of entities using a custom hashtable. + * This function utilizes the hasthable and allows for considerably faster + * classname lookup compared to the default FindEntityByString (used by + * find_ent_by_owner() for example). + * @note This exclusively considers entities in the hashtable, created by the + * game itself, using cs_create_entity(), or added via cs_set_ent_class(). + * + * @param start_index Entity index to start searching from. -1 to start from + * the first entity + * @param classname Classname to search for + * @param owner Entity index to search for entity's owner + * + * @return Entity index > 0 if found, 0 otherwise + */ +native cs_find_ent_by_owner(start_index, const classname[], owner); + +/** + * Sets a custom classname of an entity. + * + * @note Unlike other mods CS keeps track of entities using a custom hashtable. + * This function adds or updates the classname in the hasthable as well. + * This is useful for use with cs_find_ent_by_class() and cs_find_ent_by_owner(). + * + * @param index Entity index + * @param classname Classname to update for + * + * @noreturn + */ +native cs_set_ent_class(index, const classname[]); + +/** + * Returns the item id associated with an item name and its aliases. + * + * @note The item name is case sensitive an can be with or without + * weapon_ and item_ prefixes. This can be a command alias as well. + * Values examples: ak47, weapon_ak47, kevlar, item_kevlar, vest, bullpup, ... + * + * @param name Alias or classname + * @param classid If item is a weapon, variable to store the associated + * weapon class id in (CS_WEAPONCLASS_* constants) + * + * @return Item id (CSI_* constants) + */ +native any:cs_get_item_id(const name[], &CsWeaponClassType:classid = CS_WEAPONCLASS_NONE); + +/** + * Returns the alias name associated with an item index. + * + * @param itemid Item id (CSI_* constants) + * @param name Buffer to store alias name to + * @param name_maxlen Maximum buffer size + * @param altname Optional buffer to store if available alternative alias name to + * @param altname_maxlen Maximum buffer size + * + * @return True if alias is found, false otherwise + */ +native bool:cs_get_item_alias(itemid, name[], name_maxlen, altname[] = "", altname_maxlen = 0); + +/** + * Returns an item name associated with a command alias. + * + * @note The alias is case sensitive. + * @note If not an alias to a weapon, buffer will be set with the original alias. + * + * @param alias Alias name + * @param itemname Buffer to store item name to + * @param maxlength Maximum buffer size + * + * @return True if alias is translated, false otherwise + */ +native bool:cs_get_translated_item_alias(const alias[], itemname[], maxlength); + +/** + * Returns some information about a weapon. + * + * @param weapon_id Weapon id, see CSW_* constants + * @param type Info type, see CS_WEAPONINFO_* constants + * + * @return Weapon information value + * @error If weapon_id and type are out of bound, an error will be thrown. + */ +native any:cs_get_weapon_info(weapon_id, CsWeaponInfo:type); + +/** + * Returns active weapon entity. + * + * @param playerIndex Player index + * + * @return Weapon entity index on success or 0 if there is no active weapon + * @error If the client index is not within the range of 1 to + * maxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_weapon_entity(playerIndex); + +/** + * Returns weapon index of the active weapon. + * + * @note More reliable than get_user_weapon. + * + * @param playerIndex Player index + * @param clip Optional variable to store clip ammo to + * @param ammo Optional variable to store backpack ammo to + * + * @return Weapon index on success or 0 if there is no active weapon + * @error If the client index is not within the range of 1 to + * maxClients, or the client is not connected, an error will be + * thrown. + */ +native cs_get_user_weapon(playerIndex, &clip = 0, &ammo = 0); + +/** + * Returns a weapon class id associated with a weapon id. + * + * @param weapon_id Weapon id (CSI_* constants) + * + * @return Weapon class id (CS_WEAPONCLASS_* constants) + */ +stock CsWeaponClassType:cs_get_weapon_class(weapon_id) +{ + new CsWeaponClassType:type = CS_WEAPONCLASS_NONE; + + if (cs_is_valid_itemid(weapon_id, .weapon_only = true) || weapon_id == CSI_SHIELD) + { + switch (weapon_id) + { + case CSI_SHIELDGUN, CSI_SHIELD: + { + type = CS_WEAPONCLASS_PISTOL; + } + case CSI_KNIFE: + { + type = CS_WEAPONCLASS_KNIFE; + } + default: + { + new const bits = (1 << weapon_id); + + if(bits & CSI_ALL_PISTOLS) + { + type = CS_WEAPONCLASS_PISTOL; + } + else if(bits & CSI_ALL_GRENADES) + { + type = CS_WEAPONCLASS_GRENADE; + } + else if(bits & CSI_ALL_SMGS) + { + type = CS_WEAPONCLASS_SUBMACHINEGUN; + } + else if(bits & CSI_ALL_SHOTGUNS) + { + type = CS_WEAPONCLASS_SHOTGUN; + } + else if(bits & CSI_ALL_MACHINEGUNS) + { + type = CS_WEAPONCLASS_MACHINEGUN; + } + else if(bits & CSI_ALL_RIFLES) + { + type = CS_WEAPONCLASS_RIFLE; + } + else if(bits & CSI_ALL_SNIPERRIFLES) + { + type = CS_WEAPONCLASS_SNIPERRIFLE; + } + } + } + } + + return type; +} + +/** + * Checks whether an item id is not out of bounds. + * + * @param id Item id (CSI_* constants) + * @param weapon_only If true, only the real weapon ids will be checked, + * including shield as well + * + * @return True if item id is valid, false otherwise + */ +stock bool:cs_is_valid_itemid(id, bool:weapon_only = false) +{ + if (id <= CSI_NONE) + { + return false; + } + + if (id > CSI_LAST_WEAPON && id != CSI_SHIELDGUN && weapon_only) + { + return false; + } + + if (id >= CSI_MAX_COUNT) + { + return false; + } + + return true; +} + +/** + * Called when CS internally fires a command to a player. + * + * @note This is most notably used by the rebuy/autobuy functionality, + * Condition Zero also uses this to pass commands to bots internally. + * + * @param id Client index + * @param cmd Command string + * + * @return PLUGIN_CONTINUE to let the command continue + * PLUGIN_HANDLED to block the command + */ +forward CS_InternalCommand(id, const cmd[]); + +/** + * Called when a client attempts to purchase an item. + * + * @note This is called immediately when the client issues a buy command. The + * game has not yet checked if the client can actually buy the weapon. + * @note For a list of possible item ids see the CSI_* constants. + * + * @param index Client index + * @param item Item id + * + * @return PLUGIN_CONTINUE to let the buy attempt continue + * PLUGIN_HANDLED to block the buy attempt + */ +forward CS_OnBuyAttempt(index, item); + +/** + * Called when a client purchases an item. + * + * @note This is called right before the user receives the item and before the + * money is deducted from their cash reserves. + * @note For a list of possible item ids see the CSI_* constants. + * + * @param index Client index + * @param item Item id + * + * @return PLUGIN_CONTINUE to let the buy continue + * PLUGIN_HANDLED to block the buy + */ +forward CS_OnBuy(index, item); diff --git a/amxmodx/scripting/include/cstrike_const.inc b/amxmodx/scripting/include/cstrike_const.inc new file mode 100644 index 0000000..00d3b85 --- /dev/null +++ b/amxmodx/scripting/include/cstrike_const.inc @@ -0,0 +1,521 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Counter-Strike Functions +// + +#if defined _cstrike_const_included + #endinput +#endif +#define _cstrike_const_included + +/** + * IDs of weapons in CS + */ +#define CSW_NONE 0 +#define CSW_P228 1 +#define CSW_GLOCK 2 // Unused by game, See CSW_GLOCK18. +#define CSW_SCOUT 3 +#define CSW_HEGRENADE 4 +#define CSW_XM1014 5 +#define CSW_C4 6 +#define CSW_MAC10 7 +#define CSW_AUG 8 +#define CSW_SMOKEGRENADE 9 +#define CSW_ELITE 10 +#define CSW_FIVESEVEN 11 +#define CSW_UMP45 12 +#define CSW_SG550 13 +#define CSW_GALI 14 +#define CSW_GALIL 14 +#define CSW_FAMAS 15 +#define CSW_USP 16 +#define CSW_GLOCK18 17 +#define CSW_AWP 18 +#define CSW_MP5NAVY 19 +#define CSW_M249 20 +#define CSW_M3 21 +#define CSW_M4A1 22 +#define CSW_TMP 23 +#define CSW_G3SG1 24 +#define CSW_FLASHBANG 25 +#define CSW_DEAGLE 26 +#define CSW_SG552 27 +#define CSW_AK47 28 +#define CSW_KNIFE 29 +#define CSW_P90 30 +#define CSW_VEST 31 // Custom +#define CSW_VESTHELM 32 // Custom +#define CSW_SHIELDGUN 99 +#define CSW_LAST_WEAPON CSW_P90 + +const CSW_ALL_WEAPONS = (~(1< + +#pragma reqclass xstats +#if !defined AMXMODX_NOAUTOLOAD + #pragma defclasslib xstats csx +#endif + +/** + * Map objective flags returned by get_map_objectives(). + */ +enum MapObjective +{ + MapObjective_Bomb = (1<<0), + MapObjective_Hostage = (1<<1), + MapObjective_Vip = (1<<2), + MapObjective_Escape = (1<<3), +}; + +/** + * Called after a client attacks another client. + * + * @note For a list of possible weapon ids see the CSW_* constants in + * amxconst.inc + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * + * @param attacker Attacker client index + * @param victim Victim client index + * @param damage Damage dealt to victim + * @param wpnindex Weapon id + * @param hitplace Body hitplace + * @param ta If nonzero the attack was a team attack + * + * @noreturn + */ +forward client_damage(attacker, victim, damage, wpnindex, hitplace, TA); + +/** + * Called after a client death. + * + * @note For a list of possible weapon ids see the CSW_* constants in + * amxconst.inc + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * + * @param attacker Attacker client index + * @param victim Victim client index + * @param wpnindex Weapon id + * @param hitplace Body hitplace + * @param tk If nonzero the death was a teamkill + * + * @noreturn + */ +forward client_death(killer, victim, wpnindex, hitplace, TK); + +/** + * Called after a grenade was thrown. + * + * @note Weapon id is one of CSW_HEGRENADE, CSW_SMOKEGRENADE or CSW_FLASHBANG. + * + * @param index Client index + * @param greindex Grenade entity index + * @param wId Weapon id + * + * @noreturn + */ +forward grenade_throw(index, greindex, wId); + +/** + * Called after a bomb plant attempt has started. + * + * @param planter Planter client index + * + * @noreturn + */ +forward bomb_planting(planter); + +/** + * Called after a bomb plant has finished. + * + * @param planter Planter client index + * + * @noreturn + */ +forward bomb_planted(planter); + +/** + * Called when the bomb exploded. + * + * @param planter Planter client index + * @param defuser Defuser client index, if applicable + * + * @noreturn + */ +forward bomb_explode(planter, defuser); + +/** + * Called after a bomb defuse attempt has started. + * + * @param defuser Defuser client index + * + * @noreturn + */ +forward bomb_defusing(defuser); + +/** + * Called after a bomb defuse has finished. + * + * @param defuser Defuser client index + * + * @noreturn + */ +forward bomb_defused(defuser); + +/** + * @section Shared natives + */ + +/** + * Adds a custom weapon to the stats system. + * + * @note The weapon name should be the full display name of the gun such as + * "Desert Eagle" while the logname should be "weapon_deagle". + * + * @param wpnname Full weapon name + * @param melee If nonzero the weapon will be considered a melee weapon + * @param logname Weapon short name + * + * @return Cusom weapon id (>0) on success, 0 if no more custom weapons + * can be added + */ +native custom_weapon_add(const wpnname[], melee = 0, const logname[] = ""); + +/** + * Triggers a damage event on a custom weapon, adding it to the internal stats. + * + * @note This will also call the client_damage() and client_kill() forwards if + * applicable. + * @note For a list of possible body hitplaces see the HIT_* constants in + * amxconst.inc + * + * @param weapon Custom weapon id + * @param att Attacker client index + * @param vic Victim client index + * @param damage Damage dealt + * @param hitplace Optional body hitplace + * + * @noreturn + * @error If the weapon id is not a custom weapon, an invalid client + * index, damage value or hitplace is provided, an error will + * be thrown. + */ +native custom_weapon_dmg(weapon, att, vic, damage, hitplace = 0); + +/** + * Adds a shot event on a custom weapon to the internal stats. + * + * @param weapon Custom weapon id + * @param index Client index + * + * @noreturn + * @error If the weapon id is not a custom weapon or an invalid client + * index is provided, an error will be thrown. + */ +native custom_weapon_shot(weapon, index); + +/** + * Returns if the weapon is considered a melee weapon. + * + * @note For a list of default CS weapon ids see the CSW_* constants in + * amxconst.inc, this function also works on custom weapons. + * @note For the default CS weapons this obviously returns true only for + * CSW_KNIFE. + * + * @param wpnindex Weapon id + * + * @return 1 if weapon is a melee weapon, 0 + * @error If an invalid weapon id is provided an error will be thrown. + */ +native xmod_is_melee_wpn(wpnindex); + +/** + * Retrieves the full weapon name of a weapon id. + * + * @note For a list of default CS weapon ids see the CSW_* constants in + * amxconst.inc, this function also works on custom weapons. + * @note For the default CS weapons this obviously returns true only for + * CSW_KNIFE. + * + * @param wpnindex Weapon id + * @param name Buffer to copy weapon name to + * @param len Maximmum buffer size + * + * @return Number of cells written to buffer + * @error If an invalid weapon id is provided an error will be thrown. + */ +native xmod_get_wpnname(wpnindex, name[], len); + +/** + * Retrieves the weapon log name of a weapon id. + * + * @note For a list of default CS weapon ids see the CSW_* constants in + * amxconst.inc, this function also works on custom weapons. + * @note For the default CS weapons this obviously returns true only for + * CSW_KNIFE. + * + * @param wpnindex Weapon id + * @param name Buffer to copy weapon log name to + * @param len Maximmum buffer size + * + * @return Number of cells written to buffer + * @error If an invalid weapon id is provided an error will be thrown. + */ +native xmod_get_wpnlogname(wpnindex, name[], len); + +/** + * Returns the maximum amount of weapons that the stats system supports. + * + * @return Maximum number of weapons supported + */ +native xmod_get_maxweapons(); + +/** + * Returns the number of stats tracked by the stats system. + * + * @return Number of stats tracked + */ +native xmod_get_stats_size(); + +/** + * @endsection Shared natives + */ + +/** + * Returns the current map's objectives as a bitflag value. + * + * @note For a list of possible map objective flags see the MapObjective enum. + * + * @return Bitflag value of map objectives + */ +native MapObjective:get_map_objectives(); diff --git a/amxmodx/scripting/include/curl.inc b/amxmodx/scripting/include/curl.inc new file mode 100644 index 0000000..d42febd --- /dev/null +++ b/amxmodx/scripting/include/curl.inc @@ -0,0 +1,203 @@ +#if defined _curl_included + #endinput +#endif +#define _curl_included + +#include + +#if AMXX_VERSION_NUM >= 175 + #pragma reqlib curl + #if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib curl + #endif +#else + #pragma library curl +#endif + +enum _:curl_off_t { + curl_off_left, + curl_off_right +}; + +enum curl_slist +{ + SList_Empty +}; + +/** + * This function converts the given input string to a URL encoded string. + * All input characters that are not a-z, A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped" version + * (%NN where NN is a two-digit hexadecimal number). + * see also https://curl.haxx.se/libcurl/c/curl_easy_escape.html + * + * @param handle Curl handle + * @param url URL for encoding + * @param buffer Buffer to copy encoded url + * @param maxlen Maximum size of the buffer + * + * @noreturn + * @error If passed curl handle is not a valid + */ +native curl_easy_escape(const CURL:handle, const url[], buffer[], const maxlen); + +/** + * This function converts the given URL encoded input string to a "plain string". + * All input characters that are URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to their binary versions. + * see also https://curl.haxx.se/libcurl/c/curl_easy_unescape.html + * + * @param handle Curl handle + * @param url URL for decoding + * @param buffer Buffer to copy decoded url + * @param maxlen Maximum size of the buffer + * + * @noreturn + * @error If passed curl handle is not a valid + */ +native curl_easy_unescape(const CURL: handle, const url[], buffer[], const maxlen); + +/** + * This function must be the first function to call, and it returns a CURL easy handle that you must + * use as input to other functions in the easy interface. This call MUST have a corresponding call to curl_easy_cleanup + * when the operation is complete. + * see also https://curl.haxx.se/libcurl/c/curl_easy_init.html + * + * @return Curl handle + */ +native CURL: curl_easy_init(); + +/** + * Invoke this function after curl_easy_init and all the curl_easy_setopt calls are made, and will perform the transfer as described in the options. + * It must be called with the same curl handle as input as the curl_easy_init call returned. + * You can do any amount of calls to curl_easy_perform while using the same curl handle. If you intend to transfer more than one file, you are even + * encouraged to do so. libcurl will then attempt to re-use the same connection for the following transfers, thus making the operations faster, + * less CPU intense and using less network resources. Just note that you will have to use curl_easy_setopt between the invokes to set options + * for the following curl_easy_perform. + * see also https://curl.haxx.se/libcurl/c/curl_easy_perform.html + * + * @param handle Curl handle + * @param callback The forward to call after request completed + * @param data Any data to pass to the callback forward + * @param len Maximum size of the data + * + * @noreturn + * @error If passed curl handle is not a valid or or undefined callback function + */ +native curl_easy_perform(const CURL: handle, const callback[], const data[] = {}, const len = 0); + +/** + * This function is used to tell libcurl how to behave. By setting the appropriate options, the application can change libcurl's behavior. + * All options are set with an option followed by a parameter. That parameter can be a long, a function pointer, an object pointer or a curl_off_t, + * depending on what the specific option expects. Read this manual carefully as bad input values may cause libcurl to behave badly! + * You can only set one option in each function call. A typical application uses many curl_easy_setopt calls in the setup phase. + * Options set with this function call are valid for all forthcoming transfers performed using this handle. The options are not in any way reset between + * transfers, so if you want subsequent transfers with different options, you must change them between the transfers. You can optionally reset all options + * back to internal default with curl_easy_reset. + * see also https://curl.haxx.se/libcurl/c/curl_easy_setopt.html + * + * @param handle Curl handle + * @param option Necessary option (see CURLoption enum) + * + * @return If the operation was successful, CURLE_OK is returned. Otherwise an appropriate error code will be returned. + * @error If passed curl handle is not a valid or or undefined option + */ +native CURLcode: curl_easy_setopt(const CURL: handle, const CURLoption: option, any: ...); + +/** + * This function must be the last function to call for an easy session. It is the opposite of the curl_easy_init function and must be called + * with the same handle as input that a curl_easy_init call returned. + * This might close all connections this handle has used and possibly has kept open until now - unless it was attached to a multi handle while + * doing the transfers. Don't call this function if you intend to transfer more files, re-using handles is a key to good performance with libcurl. + * see also https://curl.haxx.se/libcurl/c/curl_easy_cleanup.html + * + * @param handle Curl handle + * + * @noreturn + * @error If passed curl handle is not a valid + */ +native curl_easy_cleanup(const CURL: handle); + +/** + * Re-initializes all options previously set on a specified CURL handle to the default values. This puts back the handle to the same state as it + * was in when it was just created with curl_easy_init. + * It does not change the following information kept in the handle: live connections, the Session ID cache, the DNS cache, the cookies and shares. + * see also https://curl.haxx.se/libcurl/c/curl_easy_reset.html + * + * @param handle Curl handle + * + * @noreturn + * @error If passed curl handle is not a valid + */ +native curl_easy_reset(const CURL: handle); + +/** + * Request internal information from the curl session with this function. The third argument MUST be a buffer for value (num, string, float) + * The data pointed-to will be filled in accordingly and can be relied upon only if the function returns CURLE_OK. Use this function AFTER + * a performed transfer if you want to get transfer related data. + * see also https://curl.haxx.se/libcurl/c/curl_easy_getinfo.html + * + * @param handle Curl handle + * @param info Necessary info (see CURLINFO enum) + * + * @return If the operation was successful, CURLE_OK is returned. Otherwise an appropriate error code will be returned. + * @error If passed curl handle is not a valid or or undefined info + */ +native CURLcode: curl_easy_getinfo(const CURL: handle, const CURLINFO: info, any: ...); + +/** + * The function receives a text description of the specified error code. + * + * @param code Error code (see CURLcode enum) + * @param buffer Buffer to copy error description + * @param maxlen Maximum size of the buffer + * + * @noreturn + */ +native curl_easy_strerror(const CURLcode: code, buffer[], const maxlen); + +/** +* @deprecated This function does not catch all cases. +* #pragma deprecated This function is deprecated. Do not use! +*/ +native CURLFORMcode: curl_formadd(&curl_httppost: first, &curl_httppost: last, any: ...); + +/** +* @deprecated This function does not catch all cases. +* #pragma deprecated This function is deprecated. Do not use! +*/ +native curl_formfree(&curl_httppost: first); + +/** + * This function appends a string to a linked list of strings. + * The existing list should be passed as the first argument and the new list is returned from this function. + * Pass in SList_Empty (0) in the list argument to create a new list. The specified string has been appended when this function returns. + * see also https://curl.haxx.se/libcurl/c/curl_slist_append.html + * + * @param list Existing list + * @param string Some string + * + * @return A null pointer is returned if anything went wrong, otherwise the new list pointer is returned. + * To avoid overwriting an existing non-empty list on failure, the new list should be returned to a + * temporary variable which can be tested for SList_Empty (0) before updating the original list pointer + */ +native curl_slist: curl_slist_append(curl_slist: list, string[]); + +/** + * This function removes all traces of a previously built curl_slist linked list. + * see also https://curl.haxx.se/libcurl/c/curl_slist_free_all.html + * + * @param list Existing list + * + * @noreturn + */ +native curl_slist_free_all(curl_slist: list); + +/** + * Returns a human readable string with the version number of libcurl and some of its important components (like OpenSSL version). + * see also https://curl.haxx.se/libcurl/c/curl_version.html + * + * @param buffer Buffer to copy string with the version number + * @param maxlen Maximum size of the buffer + * + * @noreturn + */ +native curl_version(buffer[], const maxlen); diff --git a/amxmodx/scripting/include/curl_consts.inc b/amxmodx/scripting/include/curl_consts.inc new file mode 100644 index 0000000..ec3eabd --- /dev/null +++ b/amxmodx/scripting/include/curl_consts.inc @@ -0,0 +1,1325 @@ +#if defined _curlconst_included + #endinput +#endif +#define _curlconst_included + +#define CURL_ERROR_SIZE 256 + +/*#if defined(WIN32) +#define CURL_SOCKET_BAD (~0) +#else +#define CURL_SOCKET_BAD -1 +#endif*/ + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_GSSNEGOTIATE - HTTP GSS-Negotiate authentication + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE 0 +#define CURLAUTH_BASIC (1<<0) +#define CURLAUTH_DIGEST (1<<1) +#define CURLAUTH_GSSNEGOTIATE (1<<2) +#define CURLAUTH_NTLM (1<<3) +#define CURLAUTH_DIGEST_IE (1<<4) +#define CURLAUTH_NTLM_WB (1<<5) +#define CURLAUTH_ONLY (1<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +enum curlioerr { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} + +enum curliocmd { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} + +enum curlsocktype { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +} + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + + CURL_SSLVERSION_LAST /* never use, keep last */ +} + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2.0 in the request */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +} + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +} + +enum curl_proxytype { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} /* this enum was added in 7.10 */ + +enum curl_infotype { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +enum CURLFORMcode { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +enum curl_ftpmethod { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +enum curl_ftpccc { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +enum curl_ftpauth { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +enum curl_ftpcreatedir { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} + +/* parameter for the CURLOPT_USE_SSL option */ +enum curl_usessl { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} + +#define CFINIT(%0) CURLFORM_%0 +enum CURLformoption { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + + CURLFORM_LASTENTRY /* the last unused */ +} + +#undef CFINIT /* done */ + +enum CURLcode { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_OBSOLETE16, /* 16 - NOT USED */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURL_LAST /* never use! */ +} + + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +enum CURLINFO { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + //CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 43 +} + +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T + +#define CINIT(%0,%1,%2) CURLOPT_%0 = %1 + %2 + +enum CURLoption { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, OBJECTPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, OBJECTPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, OBJECTPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, OBJECTPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, OBJECTPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, OBJECTPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, OBJECTPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, OBJECTPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, OBJECTPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, OBJECTPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, OBJECTPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, OBJECTPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), + + /* HTTP request, for odd commands like DELETE, TRACE and others */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, OBJECTPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, OBJECTPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, OBJECTPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, OBJECTPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, OBJECTPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, OBJECTPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, OBJECTPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, OBJECTPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, OBJECTPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, OBJECTPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, OBJECTPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, OBJECTPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), + + /* feed cookies into cookie engine */ + CINIT(COOKIELIST, OBJECTPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ +// CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ +// CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, OBJECTPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, OBJECTPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, OBJECTPOINT, 173), + CINIT(PASSWORD, OBJECTPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, OBJECTPOINT, 175), + CINIT(PROXYPASSWORD, OBJECTPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, OBJECTPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, OBJECTPOINT, 186), + + /* set the SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, OBJECTPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of miliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, OBJECTPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, OBJECTPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, OBJECTPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, OBJECTPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, OBJECTPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + CURLOPT_LASTENTRY /* the last unused */ +} + +#undef LONG +#undef OBJECTPOINT +#undef FUNCTIONPOINT +#undef OFF_T +#undef CINIT \ No newline at end of file diff --git a/amxmodx/scripting/include/cvars.inc b/amxmodx/scripting/include/cvars.inc new file mode 100644 index 0000000..74b6333 --- /dev/null +++ b/amxmodx/scripting/include/cvars.inc @@ -0,0 +1,547 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _cvars_included + #endinput +#endif +#define _cvars_included + +/** + * CVAR flags for create_cvar() and register_cvar(). + */ +#define FCVAR_NONE 0 // No special behavior +#define FCVAR_ARCHIVE 1 // Cvar will be saved to vars.rc Set to cause it to be saved to vars.rc +#define FCVAR_USERINFO 2 // Cvar changes the client's info string +#define FCVAR_SERVER 4 // Clients get notified when cvar value is changed +#define FCVAR_EXTDLL 8 // Defined by an external DLL +#define FCVAR_CLIENTDLL 16 // Defined by the client DLL +#define FCVAR_PROTECTED 32 // Cvar value is masked from outside access, should be used for sensitive cvars like passwords +#define FCVAR_SPONLY 64 // Cvar can't be changed by clients connected to a multiplayer server +#define FCVAR_PRINTABLEONLY 128 // The cvar string value can not contain unprintable characters +#define FCVAR_UNLOGGED 256 // If the cvar is FCVAR_SERVER, don't log changes to a file/the console +#define FCVAR_NOEXTRAWHITEPACE 512 // Automatically strips trailing/leading white space from the string value + +/** + * Cvar bound constants used with [get|set]_pcvar_bounds(). + */ +enum CvarBounds +{ + CvarBound_Upper = 0, + CvarBound_Lower +}; + +/** + * Creates a new cvar for the engine. + * + * @note This has the same effect as register_cvar() but provides more options. + * @note For a list of possible cvar flags see FCVAR_* constants above. + * @note If an already existing cvar is registered it will not be duplicated. + * The default value is only set when the cvar is registered for the very + * first time since the server was started. Cvar bounds are overwritten + * by the create_cvar() call just as if they were re-set using + * set_pcvar_bounds(). + * @note The returned cvar pointer should be used with the get_pcvar_* and + * set_pcvar_* set of functions. + * + * @param name Cvar name + * @param string Default cvar value + * @param flags Optional bitsum of flags specifying cvar behavior + * @param description Optional description of the cvar + * @param has_min Optional boolean that specifies if the cvar has a + * minimum value + * @param min_val Minimum floating point value + * @param has_max Optional boolean that specifies if the cvar has a + * maximum value + * @param max_val Maximum floating point value + * + * @return Unique cvar pointer + * @error If invalid bounds are provided (min_val > max_val or + * vice versa), an error will be thrown. + */ +native create_cvar(const name[], const string[], flags = FCVAR_NONE, const description[] = "", bool:has_min = false, Float:min_val = 0.0, bool:has_max = false, Float:max_val = 0.0); + +/** + * Registers a new cvar for the engine. + * + * @note Deprecated. Consider to use create_cvar for more options. + * @note For a list of possible cvar flags see FCVAR_* constants in cvars.inc + * @note If an already existing cvar is registered it will not be duplicated. + * The default value is only set when the cvar is registered for the very + * first time since the server was started. + * @note The returned cvar pointer should be used with the get_pcvar_* and + * set_pcvar_* set of functions. + * + * @param name Cvar name + * @param string Default cvar value + * @param flags Optional bitsum of flags specifying cvar behavior + * @param fvalue Unused + * + * @return Unique cvar pointer + */ +native register_cvar(const name[], const string[], flags = FCVAR_NONE, Float:fvalue = 0.0); + +/** + * Returns if a cvar is registered on the server. + * + * @param cvar Cvar name to check + * + * @return 1 if the cvar exists, 0 otherwise + */ +native cvar_exists(const cvar[]); + +/** + * Returns the cvar pointer of the specified cvar. + * + * @note A pointer is also returned by register_cvar() and create_cvar(). + * Plugins can (and should) retrieve and use pointers for already existing + * mod cvars. + * + * @param cvar Cvar name to find + * + * @return Cvar pointer on success, 0 if cvar was not found + */ +native get_cvar_pointer(const cvar[]); + +/** + * Creates a hook for when a cvar's value is changed. + * + * @note Changing the cvar value from within this forward can lead to infinite + * recursion and should be avoided. + * @note The callback will be called in the following manner: + * + * public cvar_change_callback(pcvar, const old_value[], const new_value[]) + * + * pcvar - Pointer to cvar that was changed + * old_value - Buffer containing the previous value of the cvar + * new_value - Buffer containing the new value of the cvar + * + * The return value is ignored + * + * @param pcvar Pointer to cvar + * @param callback Name of callback function + * + * @return Callback handle that can be used with + * [disable|enable]_cvar_hook + * @error If an invalid cvar pointer or callback function is provided, + * an error will be thrown. + */ +native cvarhook:hook_cvar_change(pcvar, const callback[]); + +/** + * Disables a cvar hook, stopping it from being called. + * + * @note Use the handle returned by hook_cvar_change as the parameter here. + * + * @param handle Forward to disable + * @error If an invalid hook handle is provided, an error will be + * thrown. + */ +native disable_cvar_hook(cvarhook:handle); + +/** + * Enables a cvar hook, restoring it to being called. + * + * @note Use the handle returned by hook_cvar_change as the parameter here. + * + * @param handle Forward to enable + * @error If an invalid hook handle is provided, an error will be + * thrown. + */ +native enable_cvar_hook(cvarhook:handle); + +/** + * Returns flags of a cvar. The cvar is accessed by name. + * + * @note For a list of possible flags see the FCVAR_* constants in amxconst.inc + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent get_pcvar_flags() function should be used + * instead. + * + * @param cvar Cvar name to retrieve flags from + * + * @return Flag value + */ +native get_cvar_flags(const cvar[]); + +/** + * Sets specified flags to a cvar. The cvar is accessed by name. + * + * @note Not permitted for the "amx_version", "amxmodx_version", "fun_version" + * and "sv_cheats" cvars. + * @note For a list of possible flags see the FCVAR_* constants in amxconst.inc + * @note This function just adds the flags using a bitwise-or operation. After + * it has run the flags may not exactly equal the specified bitflag sum. + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent set_pcvar_flags() function should be used + * instead. + * + * @param cvar Cvar name to remove flags from + * @param flags Bitflag sum of flags to set + * + * @return 1 on success, 0 if cvar does not exist or is not permitted + */ +native set_cvar_flags(const cvar[], flags); + +/** + * Removes specified flags from a cvar. The cvar is accessed by name. + * + * @note Not permitted for the "amx_version", "amxmodx_version", "fun_version" + * and "sv_cheats" cvars. + * @note For a list of possible flags see the FCVAR_* constants in amxconst.inc + * @note This function removes the flags using a bitwise-and operation. + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the set_pcvar_flags() function should be used instead. + * + * @param cvar Cvar name to remove flags from + * @param flags Bitflag sum of flags to remove + * + * @return 1 on success, 0 if cvar does not exist or is not permitted + */ +native remove_cvar_flags(const cvar[], flags=-1); + +/** + * Gets a string value from a cvar. The cvar is accessed by name. + * + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent get_pcvar_string() function should be used + * instead. + * + * @param cvar Cvar name to retrieve value from + * @param output Buffer to copy cvar value to + * @param iLen Maximum size of the buffer + * + * @return Number of cells written to buffer. + */ +native get_cvar_string(const cvarname[], output[], iLen); + +/** + * Sets a cvar to a given string value. The cvar is accessed by name. + * + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent set_pcvar_string() function should be used + * instead. + * + * @param cvar Cvar name to set value of + * @param value Value to set cvar to + * + * @noreturn + */ +native set_cvar_string(const cvar[], const value[]); + +/** + * Returns a floating value from a cvar. The cvar is accessed by name. + * + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent get_pcvar_float() function should be used + * instead. + * + * @param cvarname Cvar name to retrieve value from + * + * @return Cvar value, converted to float + */ +native Float:get_cvar_float(const cvarname[]); + +/** + * Sets a cvar to a given float value. The cvar is accessed by name. + * + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent set_pcvar_float() function should be used + * instead. + * + * @param cvar Cvar name to set value of + * @param value Value to set cvar to + * + * @noreturn + */ +native set_cvar_float(const cvar[], Float:value); + +/** + * Returns an integer value from a cvar. The cvar is accessed by name. + * + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent get_pcvar_num() function should be used + * instead. + * + * @param cvarname Cvar name to retrieve value from + * + * @return Cvar value, converted to int + */ +native get_cvar_num(const cvarname[]); + +/** + * Sets a cvar to a given integer value. The cvar is accessed by name. + * + * @note Accessing a Cvar by name is slower than direct pointer access, which is + * why the otherwise equivalent set_pcvar_num() function should be used + * instead. + * + * @param cvar Cvar name to set value of + * @param value Value to set cvar to + * + * @noreturn + */ +native set_cvar_num(const cvarname[], value); + +/** + * Returns flags of a cvar via direct pointer access. + * + * @note For a list of possible flags see the FCVAR_* constants in amxconst.inc + * + * @param pcvar Pointer to cvar to retrieve flags from + * + * @return 1 on success, 0 if cvar pointer is invalid + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native get_pcvar_flags(pcvar); + +/** + * Sets specified flags to a cvar via direct pointer access. + * + * @note For a list of possible flags see the FCVAR_* constants in amxconst.inc + * @note This function directly sets the provided bitflag, unlike set_cvar_flags + * which adds them using a bitwise OR. + * + * @param pcvar Pointer to cvar to set flags of + * @param flags Bitflag sum of flags to set + * + * @return 1 on success, 0 if cvar does not exist or is not permitted + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native set_pcvar_flags(pcvar, flags); + +/** + * Returns an integer value from a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to retrieve value from + * + * @return Cvar value, converted to int + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native get_pcvar_num(pcvar); + +/** + * Returns an boolean value from a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to retrieve value from + * + * @return Cvar value, converted to bool + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native bool:get_pcvar_bool(pcvar); + +/** + * Sets an integer value to a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to set value of + * @param num Value to set cvar to + * + * @noreturn + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native set_pcvar_num(pcvar, num); + +/** + * Sets a boolean value to a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to set value of + * @param num Value to set cvar to + * + * @noreturn + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native set_pcvar_bool(pcvar, bool:num); + +/** + * Returns a float value from a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to retrieve value from + * + * @return Cvar value, converted to float + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native Float:get_pcvar_float(pcvar); + +/** + * Sets a float value to a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to set value of + * @param num Value to set cvar to + * + * @noreturn + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native set_pcvar_float(pcvar, Float:num); + +/** + * Returns a string value from a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to retrieve value from + * @param string Buffer to copy cvar value to + * @param maxlen Maximum size of the buffer + * + * @return Number of cells written to buffer. + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native get_pcvar_string(pcvar, string[], maxlen); + +/** + * Sets a string value to a cvar via direct pointer access. + * + * @param pcvar Pointer to cvar to retrieve value from + * @param string Value to set cvar to + * + * @noreturn + * @error If an invalid cvar pointer is provided, an error will be + * thrown. + */ +native set_pcvar_string(pcvar, const string[]); + +/** + * Retrieves the specified value boundary of a cvar. + * + * @param pcvar Pointer to cvar + * @param type Type of boundary to retrieve + * @param value Variable to store the specified boundary to + * + * @return True if the cvar has a boundary set, false otherwise + * @error If an invalid cvar pointer or boundary type is provided, + * an error will be thrown. + */ +native bool:get_pcvar_bounds(pcvar, CvarBounds:type, &Float:value); + +/** + * Sets the specified boundary of a cvar. + * + * @param pcvar Pointer to cvar + * @param type Type of boundary to set + * @param set If true the cvar boundary will be set, otherwise it will be + * removed (value is ignored) + * @param value Floating point value to use as the boundary + * + * @noreturn + * @error If an invalid cvar pointer or boundary type is provided, an + * error will be thrown. + */ +native set_pcvar_bounds(pcvar, CvarBounds:type, bool:set, Float:value = 0.0); + +/** + * Binds a cvar's integer value to a global variable. The variable will then + * always contain the current cvar value as it is automatically kept up to date. + * + * @note The variable *has* to be a global or a static variable. Local variables + * created within functions can not be used for technical reasons. + * @note Variables can not be bound to multiple cvars. + * + * @param pcvar Pointer to cvar + * @param var Global variable to keep updated + * + * @noreturn + * @error If an invalid cvar pointer or variable is provided, an error + * will be thrown. + */ +native bind_pcvar_num(pcvar, &any:var); + +/** + * Binds a cvar's float value to a global variable. The variable will then + * always contain the current cvar value as it is automatically kept up to date. + * + * @note The variable *has* to be a global or a static variable. Local variables + * created within functions can not be used for technical reasons. + * @note Variables can not be bound to multiple cvars. + * + * @param pcvar Pointer to cvar + * @param var Global variable to keep updated + * + * @noreturn + * @error If an invalid cvar pointer or variable is provided, an error + * will be thrown. + */ +native bind_pcvar_float(pcvar, &Float:var); + +/** + * Binds a cvar's string value to a global array. The array will then + * always contain the current cvar value as it is automatically kept up to date. + * + * @note The array *has* to be a global or a static array. Local arrays + * created within functions can not be used for technical reasons. + * @note Arrays can not be bound to multiple cvars. + * + * @param pcvar Pointer to cvar + * @param var Global array to keep updated + * @param varlen Maximum length of string array + * + * @noreturn + * @error If an invalid cvar pointer or variable is provided, an error + * will be thrown. + */ +native bind_pcvar_string(pcvar, any:var[], varlen); + +/** + * Returns the number of plugin-registered cvars. + * + * @return Number of registered cvars + */ +native get_plugins_cvarsnum(); + +/** + * Retrieves information about a plugin-registered cvar via iterative access. + * + * @note The returned cvar pointer should be used with the get_pcvar_* and + * set_pcvar_* set of functions. + * @note The cvar index does not equal the cvar pointer. It is the internal + * AMXX id of a cvar, incremented for each registered cvar. + * + * @param num Index to retrieve + * @param name Buffer to copy cvar name to + * @param namelen Maximum buffer size + * @param flags Variable to store cvar flags to + * @param plugin_id Variable to store id of the registering plugin to + * @param pcvar_handle Variable to store cvar pointer to + * @param description Variable to store cvar description to + * @param desc_len Maximum length of string buffer + * + * @return 1 on success, 0 if index is invalid + */ +native get_plugins_cvar(num, name[], namelen, &flags = 0, &plugin_id = 0, &pcvar_handle = 0, description[] = "", desc_len = 0); + +/** + * Dispatches a client cvar query, allowing the plugin to query for its value on + * the client. + * + * @note The callback will be called in the following manner: + * + * public cvar_query_callback(id, const cvar[], const value[], const param[]) + * + * id - Client index + * cvar - Cvar queried + * value - Cvar value on the client + * param - Optional extra data + * + * @param id Client index + * @param cvar Cvar to query + * @param resultFunc Callback function + * @param paramlen Size of extra data + * @param params Extra data to pass through to callback + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, the callback + * function is invalid or the querying process encounters + * a problem, an error will be thrown. + */ +native query_client_cvar(id, const cvar[], const resultFunc[], paramlen = 0, const params[] = ""); diff --git a/amxmodx/scripting/include/datapack.inc b/amxmodx/scripting/include/datapack.inc new file mode 100644 index 0000000..8c9f86f --- /dev/null +++ b/amxmodx/scripting/include/datapack.inc @@ -0,0 +1,161 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _datapack_included + #endinput +#endif +#define _datapack_included + +/** + * Datapack tag declaration + * + * @note Datapacks provide a way to store and move around arbitrary amounts (and + * types) of data in AMX Mox X. Data is packed into a single cell value - + * the DataPack handle. This handle can be passed around more easily, can + * be returned by functions and can simulate advanced concepts like string + * consummation. + * @note Plugins are responsible for freeing all datapack handles they acquire. + * Failing to free handles will result in the plugin and AMXX leaking + * memory. + */ +enum DataPack +{ + Invalid_DataPack = 0 +}; + +/** + * Creates a new datapack. + * + * @return New datapack handle, which must be freed via DestroyDataPack(). + */ +native DataPack:CreateDataPack(); + +/** + * Packs a cell value into a datapack. + * + * @param pack Datapack handle + * @param cell Cell value to pack + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native WritePackCell(DataPack:pack, any:cell); + +/** + * Packs a float value into a datapack. + * + * @param pack Datapack handle + * @param val Float value to pack + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native WritePackFloat(DataPack:pack, Float:val); + +/** + * Packs a string into a datapack. + * + * @param pack Datapack handle + * @param str String to pack + * + * @return Length of copied string + * @error If an invalid handle is provided, an error will be thrown. + */ +native WritePackString(DataPack:pack, const str[]); + +/** + * Reads a cell from a Datapack. + * + * @param pack Datapack handle + * + * @return Cell value + * @error If an invalid handle is provided, or not enough data is left + * in the datapack, an error will be thrown. + */ +native any:ReadPackCell(DataPack:pack); + +/** + * Reads a float from a datapack. + * + * @param pack Datapack handle + * + * @return Float value + * @error If an invalid handle is provided, or not enough data is left + * in the datapack, an error will be thrown. + */ +native Float:ReadPackFloat(DataPack:pack); + +/** + * Reads a string from a Datapack. + * + * @param pack Datapack handle + * @param buffer Buffer to copy string to + * @param maxlen Maximum size of buffer + * + * @return Number of cells written to buffer + * @error If an invalid handle is provided, or not enough data is left + * in the datapack, an error will be thrown. + */ +native ReadPackString(DataPack:pack, buffer[], maxlen); + +/** + * Resets the datapack read/write position to the start. + * + * @param pack Datapack handle + * @param clear If true, clears the contained data + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native ResetPack(DataPack:pack, bool:clear = false); + +/** + * Returns the datapack read/write position. + * + * @param pack Datapack handle + * + * @return Position in the datapack, only usable with calls to SetPackPosition + * @error If an invalid handle is provided, an error will be thrown. + */ +native DataPackPos:GetPackPosition(DataPack:pack); + +/** + * Sets the datapack read/write position. + * + * @note This should only ever be used with (known to be valid) positions + * returned by GetPackPosition(). It is not possible for plugins to safely + * compute datapack positions. + * + * @param pack Datapack handle + * @param position New position to set + * + * @noreturn + * @error If an invalid handle is provided, or the new position is + * out of datapack bounds, an error will be thrown. + */ +native SetPackPosition(DataPack:pack, DataPackPos:position); + +/** + * Returns if the datapack has reached its end and no more data can be read. + * + * @param pack Datapack handle + * + * @return True if datapack has reached the end, false otherwise + * @error If an invalid handle is provided, an error will be thrown. + */ +native bool:IsPackEnded(DataPack:pack); + +/** + * Destroys the datapack and frees its memory. + * + * @param pack Datapack handle + * + * @return True if disposed, false otherwise + */ +native DestroyDataPack(&DataPack:pack); diff --git a/amxmodx/scripting/include/dbi.inc b/amxmodx/scripting/include/dbi.inc new file mode 100644 index 0000000..b84ee0f --- /dev/null +++ b/amxmodx/scripting/include/dbi.inc @@ -0,0 +1,154 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// SQL Database API +// + +// +// Notes - Read the comments! Make sure your plugins use +// nice ANSI SQL and don't use database column names like "key" +// otherwise this API will be a nightmare +// +// Never do error checking with the not operator! This is bad: +// if (!dbi_query()) +// You should do: +// ret = dbi_query() +// if (ret < 0) +// This is because DBI functions can and will return negative numbers +// Negative numbers evaluate to "true" in AMX. +// + +#if defined _dbi_included + #endinput +#endif +#define _dbi_included + +// You can't include SQLX first! +// there's really no reason to anyway. +#assert !defined _sqlx_included + +#pragma reqclass dbi + +enum Sql +{ + SQL_FAILED=0, + SQL_OK +}; + +enum Result +{ + RESULT_FAILED=-1, + RESULT_NONE, + RESULT_OK +}; + +/* This will return a number equal to or below 0 on failure. + * If it does fail, the error will be mirrored in dbi_error() + * The return value will otherwise be a resource handle, not an + * OK code or cell pointer. + */ +native Sql:dbi_connect(_host[], _user[], _pass[], _dbname[], _error[]="", _maxlength=0); + +/* This will do a simple query execution on the SQL server. + * If it fails, it will return a number BELOW ZERO (0) + * If zero, it succeeded with NO RETURN RESULT. + * If greater than zero, make sure to call dbi_free_result() on it! + * The return is a handle to the result set + */ +native Result:dbi_query(Sql:_sql, _query[], any:...); + +/* Has the same usage as dbi_query, but this native returns by + * reference the number of rows affected in the query. If the + * query fails rows will be equal to -1. + */ +native Result:dbi_query2(Sql:_sql, &rows, _query[], any:...); + +/* Returns 0 on failure or End of Results. + * Advances result pointer by one row. + */ +native dbi_nextrow(Result:_result); + +/* Gets a field by number. Returns 0 on failure. + * Although internally fields always start from 0, + * This function takes fieldnum starting from 1. + * No extra params: returns int + * One extra param: returns Float: byref + * Two extra param: Stores string with length + */ +native dbi_field(Result:_result, _fieldnum, any:... ); + +/* Gets a field by name. Returns 0 on failure. + * One extra param: returns Float: byref + * Two extra param: Stores string with length + */ +native dbi_result(Result:_result, _field[], any:... ); + +/* Returns the number of rows returned from a query + */ +native dbi_num_rows(Result:_result); + +/* Frees memory used by a result handle. Do this or get memory leaks. + */ +native dbi_free_result(&Result:result); + +/* Closes a database handle. Internally, it will also + * mark the handle as free, so this particular handle may + * be re-used in the future to save time. + */ +native dbi_close(&Sql:_sql); + +/* Returns an error message set. For PGSQL and MySQL, + * this is a direct error return from the database handle/API. + * For MSSQL, it returns the last error message found from a + * thrown exception. + */ +native dbi_error(Sql:_sql, _error[], _len); + +/* Returns the type of database being used. So far: + * "mysql", "pgsql", "mssql", "sqlite" + */ +native dbi_type(_type[], _len); + +/* Returns the number of fields/colums in a result set. + * Unlike dbi_nextrow, you must pass a valid result handle. + */ +native dbi_num_fields(Result:result); + +/* Retrieves the name of a field/column in a result set. + * Requires a valid result handle, and columns are numbered 1 to n. + */ +native dbi_field_name(Result:result, field, name[], maxLength); + +/* This function can be used to find out if a table in a Sqlite database exists. + */ +stock bool:sqlite_table_exists(Sql:sql, table[]) +{ + new bool:exists; + new query[128]; + format(query, 127, "SELECT name FROM sqlite_master WHERE type='table' AND name='%s' LIMIT 1;", table); + + new Result:result = dbi_query(sql, query); + + if (dbi_nextrow(result)) + { + exists = true; + } + else + { + exists = false; + } + + if (result > RESULT_NONE) + { + dbi_free_result(result); + } + + return exists; +} diff --git a/amxmodx/scripting/include/dodconst.inc b/amxmodx/scripting/include/dodconst.inc new file mode 100644 index 0000000..14807e5 --- /dev/null +++ b/amxmodx/scripting/include/dodconst.inc @@ -0,0 +1,152 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _dodconst_included + #endinput +#endif +#define _dodconst_included + +/* DoD teams */ +#define ALLIES 1 +#define AXIS 2 + +#define FT_NEW 1<<0 +#define FT_OLD 1<<1 + +#define STAMINA_SET 0 +#define STAMINA_RESET 1 + +#define FUSE_SET 0 +#define FUSE_RESET 1 + +#define DODMAX_WEAPONS 46 // 5 slots for custom weapons + +// DoD Weapon Types +enum +{ + DODWT_PRIMARY = 0, + DODWT_SECONDARY, + DODWT_MELEE, + DODWT_GRENADE, + DODWT_OTHER +}; + +// Ammo Channels +#define AMMO_SMG 1 // thompson, greasegun, sten, mp40 +#define AMMO_ALTRIFLE 2 // carbine, k43, mg34 +#define AMMO_RIFLE 3 // garand, enfield, scoped enfield, k98, scoped k98 +#define AMMO_PISTOL 4 // colt, webley, luger +#define AMMO_SPRING 5 // springfield +#define AMMO_HEAVY 6 // bar, bren, stg44, fg42, scoped fg42 +#define AMMO_MG42 7 // mg42 +#define AMMO_30CAL 8 // 30cal +#define AMMO_GREN 9 // grenades (should be all 3 types) +#define AMMO_ROCKET 13 // bazooka, piat, panzerschreck +enum { + PS_NOPRONE =0, + PS_PRONE, + PS_PRONEDEPLOY, + PS_DEPLOY, +}; + +/* info types for dod_get_map_info native */ +enum { + MI_ALLIES_TEAM = 0, + MI_ALLIES_PARAS, + MI_AXIS_PARAS, +}; + +/* DoD weapons */ +enum { + DODW_AMERKNIFE = 1, + DODW_GERKNIFE, + DODW_COLT, + DODW_LUGER, + DODW_GARAND, + DODW_SCOPED_KAR, + DODW_THOMPSON, + DODW_STG44, + DODW_SPRINGFIELD, + DODW_KAR, + DODW_BAR, + DODW_MP40, + DODW_HANDGRENADE, + DODW_STICKGRENADE, + DODW_STICKGRENADE_EX, + DODW_HANDGRENADE_EX, + DODW_MG42, + DODW_30_CAL, + DODW_SPADE, + DODW_M1_CARBINE, + DODW_MG34, + DODW_GREASEGUN, + DODW_FG42, + DODW_K43, + DODW_ENFIELD, + DODW_STEN, + DODW_BREN, + DODW_WEBLEY, + DODW_BAZOOKA, + DODW_PANZERSCHRECK, + DODW_PIAT, + DODW_SCOPED_FG42, + DODW_FOLDING_CARBINE, + DODW_KAR_BAYONET, + DODW_SCOPED_ENFIELD, + DODW_MILLS_BOMB, + DODW_BRITKNIFE, + DODW_GARAND_BUTT, + DODW_ENFIELD_BAYONET, + DODW_MORTAR, + DODW_K43_BUTT, +}; + +/* DoD Classes */ +enum { + DODC_GARAND = 1, + DODC_CARBINE, + DODC_THOMPSON, + DODC_GREASE, + DODC_SNIPER, + DODC_BAR, + DODC_30CAL, + DODC_BAZOOKA, + //DODC_ALLIES_MORTAR, + DODC_KAR = 10, + DODC_K43, + DODC_MP40, + DODC_MP44, + DODC_SCHARFSCHUTZE, + DODC_FG42, + DODC_SCOPED_FG42, + DODC_MG34, + DODC_MG42, + DODC_PANZERJAGER, + //DODC_AXIS_MORTAR, + DODC_ENFIELD = 21, + DODC_STEN, + DODC_MARKSMAN, + DODC_BREN, + DODC_PIAT, + //DODC_BRIT_MORTAR, +}; + +/* DoD stats constants */ +enum { + DODX_KILLS = 0, + DODX_DEATHS, + DODX_HEADSHOTS, + DODX_TEAMKILLS, + DODX_SHOTS, + DODX_HITS, + DODX_DAMAGE, + DODX_POINTS, + DODX_RANK, + DODX_MAX_STATS +} diff --git a/amxmodx/scripting/include/dodfun.inc b/amxmodx/scripting/include/dodfun.inc new file mode 100644 index 0000000..cc8ea1e --- /dev/null +++ b/amxmodx/scripting/include/dodfun.inc @@ -0,0 +1,152 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// DoD Fun Functions +// + +#if defined _dodfun_included + #endinput +#endif +#define _dodfun_included + +#include + +#pragma reqlib dodfun +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib dodfun +#endif + +/* Function is called after grenade throw */ +forward grenade_throw(index,greindex,wId); + +/* Function is called after a rocket is shot */ +forward rocket_shoot(index,rocketindex,wId); + +/* Example: for full stamina use dod_player_stamina(1,STAMINA_SET,100,100) */ +/* value is from 0 - 100 */ +native dod_set_stamina(index,set=STAMINA_SET,minvalue=0,maxvalue=100); + +/* Sets fuse for grenades. Valid number is from 0.1-20.0 */ +/* types : new or preprimed */ +native dod_set_fuse(index,set=FUSE_SET,Float:newFuse=5.0, Type=FT_NEW); + +/* Sets player class */ +native dod_set_user_class(index,classId); + +/* Sets player team and random class. Don't work for spectators. */ +native dod_set_user_team(index,teamId,refresh=1); + +/* Returns next player class. Usefull is player is using random class */ +native dod_get_next_class(index); + +/* Returns 1 if player choose random class */ +native dod_is_randomclass(index); + +/* Returns player deaths */ +native dod_get_pl_deaths(index); + +/* Sets player deaths. + * Note if you opt to refresh the scoreboard, it + * will make the player appear as "DEAD" in the scoreboard. + */ +native dod_set_pl_deaths(index,value,refresh=1); + +/* Returns player deaths. */ +native dod_get_user_kills(index); + +/* Sets player kills. */ +native dod_set_user_kills(index,value,refresh=1); + +/* Sets player score. */ +native dod_set_user_score(index,value,refresh=1); + +/* Sets new team name for this player */ +native dod_set_pl_teamname(index,const szName[]); + +/* Gets player team name */ +native dod_get_pl_teamname(index,szName[],len); + +/* Returns 1 is player weapon is deployed (bar,mg..) */ +native dod_is_deployed(index); + +/*Sets the ammo of the specified weapon entity id */ +native dod_set_user_ammo(index,wid,value); + +/*Gets the ammo of the specified weapon entity id */ +native dod_get_user_ammo(index,wid); + +/* called after first InitObj */ +forward controlpoints_init(); + +enum CP_VALUE { + CP_edict = 1, // read only + CP_area, // read only + CP_index, // read only + CP_owner, + CP_default_owner, + CP_visible, // reinit after change + CP_icon_neutral, // reinit after change + CP_icon_allies, // reinit after change + CP_icon_axis, // reinit after change + CP_origin_x, // reinit after change + CP_origin_y, // reinit after change + + CP_can_touch, + CP_pointvalue, + + CP_points_for_cap, + CP_team_points, + + CP_model_body_neutral, + CP_model_body_allies, + CP_model_body_axis, + + // strings + CP_name, + CP_reset_capsound, + CP_allies_capsound, + CP_axis_capsound, + CP_targetname, + + CP_model_neutral, + CP_model_allies, + CP_model_axis, +}; + +/* returns number of objectives */ +native objectives_get_num(); + +/* use this function to update client(s) hud. You need to do this sometimes. Check CP_VALUE comments. + if player is 0 , all clients will get this message */ +native objectives_reinit( player=0 ); + +/* use this function to get info about specified control point */ +native objective_get_data( index, CP_VALUE:key, szValue[]="", len=0 ); + +/* use this function to change control point's data */ +native objective_set_data( index, CP_VALUE:key , iValue=-1, const szValue[]="" ); + +enum CA_VALUE { + CA_edict = 1, + CA_allies_numcap, + CA_axis_numcap, + CA_timetocap, + CA_can_cap, + + // strings + CA_target, + CA_sprite, +}; + +/* use this function to get info about specified control point's area */ +native area_get_data( index, CA_VALUE:key, szValue[]="", len=0 ); + +/* use this function to change control point's area data */ +native area_set_data( index, CA_VALUE:key , iValue=-1, const szValue[]="" ); diff --git a/amxmodx/scripting/include/dodstats.inc b/amxmodx/scripting/include/dodstats.inc new file mode 100644 index 0000000..381496a --- /dev/null +++ b/amxmodx/scripting/include/dodstats.inc @@ -0,0 +1,69 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// DODX Stats Functions +// + +#if defined _dodstats_included + #endinput +#endif +#define _dodstats_included + +/* Gets stats from given weapon index. If wpnindex is 0 +* then the stats are from all weapons. If weapon has not been used function +* returns 0 in other case 1. Fields in stats are: +* 0 - kills +* 1 - deaths +* 2 - headshots +* 3 - teamkilling +* 4 - shots +* 5 - hits +* 6 - damage +* 7 - score +* For body hits fields see amxconst.inc. */ +native get_user_wstats(index,wpnindex,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets round stats from given weapon index.*/ +native get_user_wrstats(index,wpnindex,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets life (from spawn to spawn) stats from given weapon index.*/ +native get_user_wlstats(index,wpnindex,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets overall stats which are stored in file on server +* and updated on every respawn or user disconnect. +* Function returns the position in stats by diff. kills to deaths. */ +native get_user_stats(index,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets round stats of player. */ +native get_user_rstats(index,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets life (from spawn to spawn) stats of player. */ +native get_user_lstats(index,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets stats with which user have killed/hurt his victim. If victim is 0 +* then stats are from all victims. If victim has not been hurt, function +* returns 0 in other case 1. User stats are reset on his respawn. */ +native get_user_vstats(index,victim,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS],wpnname[]="",len=0); + +/* Gets stats with which user have been killed/hurt. If killer is 0 +* then stats are from all attacks. If killer has not hurt user, function +* returns 0 in other case 1. User stats are reset on his respawn. */ +native get_user_astats(index,wpnindex,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS],wpnname[]="",len=0); + +/* Resets life, weapon, victims and attackers user stats. */ +native reset_user_wstats(index); + +/* Gets overall stats which stored in stats.dat file in amx folder +* and updated on every mapchange or user disconnect. +* Function returns next index of stats entry or 0 if no more exists. */ +native get_stats(index,stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS],name[],len); + +/* Returns number of all entries in stats. */ +native get_statsnum(); diff --git a/amxmodx/scripting/include/dodx.inc b/amxmodx/scripting/include/dodx.inc new file mode 100644 index 0000000..42e21da --- /dev/null +++ b/amxmodx/scripting/include/dodx.inc @@ -0,0 +1,161 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// DODX Functions +// + +#if defined _dodx_included + #endinput +#endif +#define _dodx_included + +#include +#include + +#pragma reqclass xstats +#if !defined AMXMODX_NOAUTOLOAD + #pragma defclasslib xstats dodx +#endif + +/************* Shared Natives Start ********************************/ + +/* Forward types */ +enum { + XMF_DAMAGE = 0, + XMF_DEATH, + XMF_SCORE, +}; + +/* Use this function to register forwards */ +native register_statsfwd(ftype); + +/* Function is called after player to player attacks , +* if players were damaged by teammate TA is set to 1 */ +forward client_damage(attacker, victim, damage, wpnindex, hitplace, TA); + +/* Function is called after player death , +* if player was killed by teammate TK is set to 1 */ +forward client_death(killer, victim, wpnindex, hitplace, TK); + +/* Function is called if player scored */ +forward client_score(id, score, total); + +/* This Forward is called when a player changes team */ +forward dod_client_changeteam(id, team, oldteam); + +/* This Forward is called if a player changes class, but just after spawn */ +forward dod_client_changeclass(id, class, oldclass); + +/* This Forward is called when a player spawns */ +forward dod_client_spawn(id); + +/* This will be called whenever a player scopes or unscopes +value = 1 scope up +value = 0 scope down */ +forward dod_client_scope(id, value); + +/* This will be called whenever a player drops a weapon +weapon is weapon dropped or picked up +value = 1 picked up +value = 0 dropped */ +forward dod_client_weaponpickup(id, weapon, value); + +/* Called whenever the the player goes to or comes from prone position +value = 1 going down +value = 0 getting up */ +forward dod_client_prone(id, value); + +/* This will be called whenever a player switches a weapon */ +forward dod_client_weaponswitch(id, wpnew, wpnold); + +/* Forward for when a grenade explodes and its location */ +forward dod_grenade_explosion(id, Float:pos[3], wpnid); + +/* Forward for when a rocket explodes and its location */ +forward dod_rocket_explosion(id, Float:pos[3], wpnid); + +/* Forward for when a player picks up a object */ +forward dod_client_objectpickup(id, objid, Float:pos[3], value); + +/* Forward for when a users stamina decreases */ +forward dod_client_stamina(id, stamina); + +/* We want to get just the weapon of whichever type that the player is on him +Use DODWT_* in dodconst.inc for type */ +native dod_weapon_type(id, type); + +/* This native will change the position of a weapon within the users slots and its ammo ammount */ +native dod_set_weaponlist(id, wpnID, slot, dropslot, totalrds); + +/* Sets the model for a player */ +native dod_set_model(id, const model[]); + +/* Sets the model for a player */ +native dod_set_body_number(id, bodynumber); + +/* Un-Sets the model for a player */ +native dod_clear_model(id); + +/* Custom Weapon Support */ +/* function will return index of new weapon */ +native custom_weapon_add( const wpnname[], melee = 0, const logname[]="" ); + +/* Function will pass damage done by this custom weapon to stats module and other plugins */ +native custom_weapon_dmg( weapon, att, vic, damage, hitplace=0 ); + +/* Function will pass info about custom weapon shot to stats module */ +native custom_weapon_shot( weapon, index ); // weapon id , player id + +/* function will return 1 if true */ +native xmod_is_melee_wpn(wpnindex); + +/* Returns weapon name. */ +native xmod_get_wpnname(wpnindex, name[], len); + +/* Returns weapon logname. */ +native xmod_get_wpnlogname(wpnindex, name[], len); + +/* Returns weapons array size */ +native xmod_get_maxweapons(); + +/* Returns stats array size ex. 8 in TS , 9 in DoD */ +native xmod_get_stats_size(); + +/* Returns 1 if true */ +native xmod_is_custom_wpn(wpnindex); + +/************* Shared Natives End ********************************/ + +/* weapon logname to weapon name convertion */ +native dod_wpnlog_to_name(const logname[],name[],len); + +/* weapon logname to weapon index convertion */ +native dod_wpnlog_to_id(const logname[]); + +native dod_get_map_info( info ); + +/* Returns id of currently carried weapon. Gets also +* ammount of ammo in clip and backpack. */ +native dod_get_user_weapon(index,&clip=0,&ammo=0); + +/* Returns team score */ +native dod_get_team_score(teamId); + +/* Returns player class id */ +native dod_get_user_class(index); + +/* Returns player score */ +native dod_get_user_score(index); + +/* values are: 0-no prone, 1-prone, 2-prone + w_deploy */ +native dod_get_pronestate(index); + +/* It is not as safe as original but player deaths will not be increased */ +native dod_user_kill(index); diff --git a/amxmodx/scripting/include/engine.inc b/amxmodx/scripting/include/engine.inc new file mode 100644 index 0000000..4c9483d --- /dev/null +++ b/amxmodx/scripting/include/engine.inc @@ -0,0 +1,1343 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// Special thanks to Vexd and mahnsawce. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Engine Functions +// + +#if defined _engine_included + #endinput +#endif +#define _engine_included + +#include + +#pragma reqlib engine +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib engine +#endif + +/** + * Retrieves a result from the global engine module trace handle. + * + * @note For a list of trace results available see the TR_* constants in + * engine_const.inc. + * @note Usage examples: + * value = traceresult(TR_AllSolid); + * traceresult(TR_Fraction, floatvalue); + * traceresult(TR_EndPos, vector); + * + * @param type Result to retrieve + * @param ... Depending on the result type a different number of + * additional parameters should be provided: + * int - Returns the result integer value directly, no + * additional parameters required + * float - Stores the result float value into the + * variable provided as the second parameter + * vector - Copies the result vector to the Float:array[3] + * provided in the second parameter + * + * @return Changes depending on the result type: + * int - Returns the result integer value + * float - Returns 1 + * vector - Returns 1 + */ +native traceresult(type, any:...); + +/** + * Registers a function to be called on a client impulse. + * + * @note The function will be called in the following manner: + * + * public impulse_handler(client, impulse) + * + * client - Client index + * impulse - Impulse triggered by the client + * + * @note The callback should return PLUGIN_CONTINUE to ignore the impulse, + * PLUGIN_HANDLED or higher to nullify it (CmdStart() is not blocked). + * @note When returning PLUGIN_HANDLED or higher from the callback, Engine will + * still fire other impulse functions. This includes the client_impulse() + * and client_cmdStart() forwards. + * + * @param impulse Impulse to hook + * @param function Name of callback function + * + * @return Impulse forward id + */ +native register_impulse(impulse, const function[]); + +/** + * Registers a function to be called on a touch action between entities of + * specified classes. + * + * @note The function will be called in the following manner: + * + * public touch_handler(touched, toucher) + * + * touched - Index of entity being touched + * toucher - Index of entity touching + * + * @note The callback should return PLUGIN_CONTINUE to ignore the touch, + * PLUGIN_HANDLED or higher to block it. + * @note When returning PLUGIN_HANDLED from the callback, Engine will still fire + * other touch functions like the pfn_touch() forward before actually + * blocking the touch. To immediately block return PLUGIN_HANDLED_MAIN + * instead. + * + * @param Touched Entity classname being touched, "*" or "" for any class + * @param Toucher Entity classname touching, "*" or "" for any class + * @param function Name of callback function + * + * @return Touch forward id + */ +native register_touch(const Touched[], const Toucher[], const function[]); + +/** + * Registers a function to be called on entity think on all entities of a + * specified class. + * + * @note The function will be called in the following manner: + * + * public think_handler(entity) + * + * entity - Index of entity thinking + * + * @note The callback should return PLUGIN_CONTINUE to ignore the think, + * PLUGIN_HANDLED or higher to block it. + * @note When returning PLUGIN_HANDLED from the callback, Engine will still fire + * other think functions like the pfn_think() forward before actually + * blocking the think. To immediately block return PLUGIN_HANDLED_MAIN + * instead. + * + * @param Classname Entity classname to hook + * @param function Name of callback function + * + * @return Think forward id + */ +native register_think(const Classname[], const function[]); + +/** + * Removes a previously registered impulse hook. + * + * @param registerid Impulse forward id + * + * @return 1 on success, 0 if nothing was removed + */ +native unregister_impulse(registerid); + +/** + * Removes a previously registered touch hook. + * + * @param registerid Touch forward id + * + * @return 1 on success, 0 if nothing was removed + */ +native unregister_touch(registerid); + +/** + * Removes a previously registered think hook. + * + * @param registerid Think forward id + * + * @return 1 on success, 0 if nothing was removed + */ +native unregister_think(registerid); + +/** + * Sets the engine module speak flags on a client. + * + * @note For a list of available flags see the SPEAK_* constants in + * engine_const.inc + * + * @param iIndex Client index + * @param iSpeakFlags New flags to set + * + * @noreturn + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native set_speak(iIndex, iSpeakFlags); + +/** + * Returns the engine module speak flags currently set on a client. + * + * @note For a list of available flags see the SPEAK_* constants in + * engine_const.inc + * + * @param iIndex Client index + * + * @return Client speak flags + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error will be + * thrown. + */ +native get_speak(iIndex); + +/** + * Uses the DROP_TO_FLOOR() engine function on an entity, which attempts to put + * it down on the floor. + * + * @note This engine function traces 256 units straight downwards from the + * entity origin. If the trace hits the floor, the origin is updated to + * the end position of the trace, FL_ONGROUND is added to the flags and + * EV_ENT_groundentity is updated. When the trace does not hit anything or + * the entity would be stuck inside something, the function does nothing + * and returns 0. + * + * @param entity Entity index + * + * @return 1 if entity is on the floor, 0 otherwise + */ +native drop_to_floor(entity); + +/** + * Retrieves keyvalue buffer from a client or the server. + * + * @note There are three different types of keyvalue buffers, depending on the + * index passed: + * -1 - "local" buffer (various server information and config values) + * 0 - server buffer (usually contains "*gamedir" only) + * >0 - client buffer ("name", "rate" and other client info) + * @note The buffer is formatted as "\key1\value1\key2\value2\...\keyN\valueN" + * + * @param id Server/client index + * @param buffer Buffer to copy keybuffer to + * @param length Maximum size of buffer + * + * @return Number of cells written to buffer + * @error If an invalid entity index is provided or, if the index is a + * client index, the client is not connected, an error will be + * thrown. + */ +native get_info_keybuffer(id, buffer[], length); + +/** + * Forces an entity (such as a player) to use another entity (such as a button). + * + * @param entUsed Index of entity being used + * @param entUser Index of entity using + * + * @noreturn + * @error If an invalid entity index is provided or, if either index + * is a client index, that client is not connected, an error + * will be thrown. + */ +native force_use(entUsed, entUser); + +/** + * Returns a float type value from the server globals. + * + * @note For a list of valid float type entries, see the GL_* constants in + * engine_const.inc under the "Float" section. + * + * @param variable Entry to retrieve from + * + * @return Value of specified entry + * @error If an invalid entry is provided, an error will be thrown. + */ +native Float:get_global_float(variable); + +/** + * Returns a integer type value from the server globals. + * + * @note For a list of valid integer type entries, see the GL_* constants in + * engine_const.inc under the "Int" section. + * + * @param variable Entry to retrieve from + * + * @return Value of specified entry + * @error If an invalid entry is provided, an error will be thrown. + */ +native get_global_int(variable); + +/** + * Retrieves a global string type value from the server. + * + * @note For a list of valid string type entries, see the GL_* constants in + * engine_const.inc under the "String" section. + * + * @param variable Entry to retrieve from + * @param string Buffer to copy value to + * @param maxlen Maximum size of buffer + * + * @return Number of cells written to buffer + * @error If an invalid entry is provided, an error will be thrown. + */ +native get_global_string(variable, string[], maxlen); + +/** + * Returns a vector type value from the server globals. + * + * @note For a list of valid vector type entries, see the GL_* constants in + * engine_const.inc under the "Vector" section. + * + * @param variable Entry to retrieve from + * @param vector Array to store vector in + * + * @noreturn + * @error If an invalid entry is provided, an error will be thrown. + */ +native get_global_vector(variable, Float:vector[3]); + +/** + * Returns a edict type value from the server globals. + * + * @note For a list of valid edict type entries, see the GL_* constants in + * engine_const.inc under the "Edict" section. + * @note This native returns 0 as an error value if the edict retrieved is an + * invalid entity. As 0 is an entity index that is considered to be a + * valid value for some globals ("worldspawn"), this native can + * potentially return a misleading value. Use get_global_edict2() for a + * safe version. + * + * @param variable Entry to retrieve from + * + * @return Value of specified entry + * @error If an invalid entry is provided, an error will be thrown. + */ +native get_global_edict(variable); + +/** + * Returns a edict type value from the server globals. + * + * @note For a list of valid edict type entries, see the GL_* constants in + * engine_const.inc under the "Edict" section. + * @note This native returns -1 as a safe error value if the edict retrieved is + * an invalid entity. Otherwise it is identical to get_global_edict(). + * + * @param variable Entry to retrieve from + * + * @return Value of specified entry + * @error If an invalid entry is provided, an error will be thrown. + */ +native get_global_edict2(variable); + +/** + * Sets the size of the entity bounding box, as described by the minimum and + * maximum vectors relative to the origin. + * + * @param index Entity index + * @param mins Vector containing the minimum point relative to the origin + * @param maxs Vector containing the maximum point relative to the origin + * + * @noreturn + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_size(index, const Float:mins[3], const Float:maxs[3]); + +/** + * Returns the index of a decal. + * + * @param szDecalName Decal name + * + * @return Decal index >= 0, or -1 if decal was not found + */ +native get_decal_index(const szDecalName[]); + +/** + * Returns the distance between two entities. + * + * @param ida Entity index 1 + * @param idb Entity index 2 + * + * @return Distance between the entities + * @error If an invalid entity index is provided or, if either index is a + * client index, that client is not connected, an error will be + * thrown. + */ +native Float:entity_range(ida, idb); + +/** + * Returns if two entities bounding boxes intersect by comparing their absolute + * minimum and maximum origins. + * + * @param entity Entity index 1 + * @param other Entity index 2 + * + * @return True if entities intersect, false otherwise + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native bool:entity_intersects(entity, other); + +/** + * Returns an integer type value from an entities entvar struct. + * + * @note For a list of valid integer type entries, see the EV_INT_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * + * @return Value of specified entry + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_int(iIndex, iKey); + +/** + * Sets an integer type value in an entities entvar struct. + * + * @note For a list of valid integer type entries, see the EV_INT_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to write to + * @param iVal Value to set + * + * @return 1 if value was sucessfully set, 0 if an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_int(iIndex, iKey, iVal); + +/** + * Returns a float type value from an entities entvar struct. + * + * @note For a list of valid float type entries, see the EV_FL_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * + * @return Value of specified entry, or 0 if an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native Float:entity_get_float(iIndex, iKey); + +/** + * Sets a float type value in an entities entvar struct. + * + * @note For a list of valid float type entries, see the EV_FL_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to write to + * @param iVal Value to set + * + * @return 1 if value was sucessfully set, 0 if an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_float(iIndex, iKey, Float:iVal); + +/** + * Retrieves a vector type value from an entities entvar struct. + * + * @note For a list of valid vector type entries, see the EV_VEC_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * @param vRetVector Array to store vector in + * + * @return 1 if value was sucessfully retrieved, 0 if an invalid + * entry was specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_vector(iIndex, iKey, Float:vRetVector[3]); + +/** + * Sets a vector type value in an entities entvar struct. + * + * @note For a list of valid vector type entries, see the EV_VEC_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to write to + * @param vNewVector Array to copy to the entity + * + * @return 1 if value was sucessfully set, 0 if an invalid entry + * was specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_vector(iIndex, iKey, const Float:vNewVector[3]); + +/** + * Returns an edict type value from an entities entvar struct. + * + * @note For a list of valid edict type entries, see the EV_ENT_* constants in + * engine_const.inc + * @note This native returns 0 as an error value if the edict retrieved from the + * entvar is an invalid entity. As 0 is an entity index that is + * considered to be a valid value for some entvars ("worldspawn"), this + * native can potentially return a misleading value. Use + * entity_get_edict2() for a safe version. + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * + * @return Entity index in specified entry, 0 if the edict in the + * entvar is not a valid entity or an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_edict(iIndex, iKey); + +/** + * Returns an edict type value from an entities entvar struct. + * + * @note For a list of valid edict type entries, see the EV_ENT_* constants in + * engine_const.inc + * @note This native returns -1 as a safe error value if the edict retrieved + * from the entvar is an invalid entity. Otherwise it is identical to + * entity_get_edict(). + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * + * @return Entity index in specified entry, -1 if the edict in the + * entvar is not a valid entity or an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_edict2(iIndex, iKey); + +/** + * Sets an edict type value in an entities entvar struct. + * + * @note For a list of valid edict type entries, see the EV_ENT_* constants in + * engine_const.inc + * @note This native will crash the server if an invalid entity index is + * provided in iNewIndex. + * + * @param iIndex Entity index + * @param iKey Entry to write to + * @param iNewIndex Entity index to set + * + * @return 1 if value was sucessfully set, 0 if an invalid entry + * was specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_edict(iIndex, iKey, iNewIndex); + +/** + * Retrieves a string type value from an entities entvar struct. + * + * @note For a list of valid string type entries, see the EV_SZ_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * @param szReturn Buffer to copy value to + * @param iRetLen Maximum size of buffer + * + * @return Number of cells written to buffer, 0 if an invalid entry + * was specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_string(iIndex, iKey, szReturn[], iRetLen); + +/** + * Sets a string type value in an entities entvar struct. + * + * @note For a list of valid string type entries, see the EV_SZ_* constants in + * engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * @param szNewVal String to copy to the entity + * + * @return 1 if value was sucessfully set, 0 if an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_string(iIndex, iKey, const szNewVal[]); + +/** + * Returns a bytearray type value from an entities entvar struct. + * + * @note For a list of valid bytearray type entries, see the EV_BYTE_* constants + * in engine_const.inc + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * + * @return Value of specified entry, 0 if an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_byte(iIndex, iKey); + +/** + * Sets a bytearray type value in an entities entvar struct. + * + * @note For a list of valid bytearray type entries, see the EV_BYTE_* constants + * in engine_const.inc + * @note The value is automatically clamped to [0,255]. + * + * @param iIndex Entity index + * @param iKey Entry to write to + * @param iVal Value to set + * + * @return 1 if value was sucessfully set, 0 if an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_byte(iIndex, iKey, iVal); + +/** + * Creates an entity. + * + * @note When creating an entity the classname has to be valid in the mod, as + * the engine needs to link the entity to an existing class internally. + * The classname string that is stored in the entvar struct + * (EV_SZ_classname) is separate from this association and can later be + * freely changed to serve other purposes. + * + * @param szClassname Entity classname + * + * @return Entity index > 0 on success, 0 otherwise + */ +native create_entity(const szClassname[]); + +/** + * Removes an entity from the world. + * + * @param iIndex Entity index + * + * @return 1 if entity was sucessfully removed, 0 if an invalid entity + * was provided + * @error If an entity index in the range of 0 to MaxClients is + * provided, an error will be thrown. + */ +native remove_entity(iIndex); + +/** + * Returns the current number of entities in the world. + * + * @return Number of entities + */ +native entity_count(); + +/** + * Returns if an entity index is valid (as required by other engine natives). + * + * @note Engine considers an entity index valid if it is in the range between 1 + * and the maximum number of entities possible. The index also has to + * point to an existing entity or, if it is a client index, the client has + * to be connected. + * + * @param iIndex Entity index + * + * @return 1 if entity is valid, 0 otherwise + */ +native is_valid_ent(iIndex); + +/** + * Searches entities in the world, starting at a specified index and matching by + * classname. + * + * @param iIndex Entity index to start from + * @param szClass Classname to match + * + * @return Entity index if an entity was found, 0 otherwise + */ +native find_ent_by_class(iIndex, const szClass[]); + +/** + * Searches entities in the world, starting at a specified index, matching by + * owner and a configurable entity field. + * + * @param iIndex Entity index to start from + * @param szClass String to match + * @param iOwner Owner entity index to match + * @param iJghgType Entity field to match string against: + * 0 - Classname + * 1 - Target + * 2 - Targetname + * + * @return Entity index if an entity was found, 0 otherwise + */ +native find_ent_by_owner(iIndex, const szClass[], iOwner, iJghgType = 0); + +/** + * Searches entities in the world, starting at a specified index and matching by + * target. + * + * @param iIndex Entity index to start from + * @param szClass Target to match + * + * @return Entity index if an entity was found, 0 otherwise + */ +native find_ent_by_target(iIndex, const szClass[]); + +/** + * Searches entities in the world, starting at a specified index and matching by + * targetname. + * + * @param iIndex Entity index to start from + * @param szClass Targetname to match + * + * @return Entity index if an entity was found, 0 otherwise + */ +native find_ent_by_tname(iIndex, const szClass[]); + +/** + * Searches entities in the world, starting at a specified index and matching by + * classname and model. + * + * @param iIndex Entity index to start from + * @param szClass Classname to match + * @param szModel Model to match + * + * @return Entity index if an entity was found, 0 otherwise + */ +native find_ent_by_model(iIndex, const szClass[], const szModel[]); + +/** + * Searches for entities inside a sphere, starting at a specified index. + * + * @param start_from_ent Entity index to start from + * @param origin Center of sphere + * @param radius Sphere radius + * + * @return Entity index if an entity was found, 0 otherwise + */ +native find_ent_in_sphere(start_from_ent, const Float:origin[3], Float:radius); + +/** + * Searches for entities inside a sphere around a specified entity or origin, + * matching by classname. + * + * @note This native always starts searching from entity index 0, there is no + * way to specify the starting point. If the entlist array is not big + * enough to accomodate all entities, the results will be truncated. + * + * @param aroundent Entity index to center sphere around, < 1 to use + * origin + * @param _lookforclassname Classname to match + * @param radius Sphere radius + * @param entlist Array to store entities in + * @param maxents Maximum size of array + * @param origin Center of sphere, used if aroundent < 1 + * + * @return Number of entities stored in entlist + * @error If an invalid entity index is provided or, if + * the index is a client index, the client is not + * connected, an error will be thrown. + */ +native find_sphere_class(aroundent, const _lookforclassname[], Float:radius, entlist[], maxents, const Float:origin[3] = {0.0, 0.0, 0.0}); + +/** + * Sets the origin of an entity. + * + * @note This native uses engine functions to set the origin, keeping it + * properly updated with the game. Directly writing to EV_VEC_origin is an + * error and will cause problems. + * + * @param iIndex Entity index + * @param fNewOrigin New origin + * + * @noreturn + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_origin(iIndex, const Float:fNewOrigin[3]); + +/** + * Sets the model of an entity. + * + * @note This native uses an engine function to set the model, keeping it + * properly updated with the game. Simply writing to EV_SZ_model is an + * error and will cause problems. + * + * @param iIndex Entity index + * @param szModel Model to set + * + * @noreturn + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_set_model(iIndex, const szModel[]); + +/** + * Sets rendering options of an entity. + * + * @note For a list of valid rendering effects see the kRenderFx* constants in + * amxconst.inc + * @note For a list of valid rendering modes see the kRender* constants in + * amxconst.inc + * @note Rendering amount has different meanings depending on the rendering + * effect and mode used on the entity. + * + * @param index Entity index + * @param fx Rendering effect + * @param r Red component of rendering color + * @param g Green component of rendering color + * @param b Blue component of rendering color + * @param render Rendering mode + * @param amount Rendering amount + * + * @noreturn + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native set_ent_rendering(index, fx = kRenderFxNone, r = 0, g = 0, b = 0, render = kRenderNormal, amount = 0); + +/** + * Calls the DispatchThink() game DLL function on an entity, triggering it to + * think if applicable. + * + * @note DispatchThink() checks the entity for the FL_DORMANT flag - if it is + * set, the entity will not proceed to think. It will first call the + * class-specific think function and eventually CBaseEntity::Think(), thus + * triggering other think hooks and forwards. + * + * @param entity Entity index + * + * @noreturn + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native call_think(entity); + +/** + * Forces an entity to touch another entity. + * + * @note This calls the game touch function even when the entities do not + * intersect. It doesn't change their origins and/or bounding boxes. + * + * @param entTouched Index of entity being touched + * @param entToucher Index of entity touching + * + * @noreturn + * @error If an invalid entity index is provided or, if the index + * is a client index, the client is not connected, an error + * will be thrown. + */ +native fake_touch(entTouched, entToucher); + +/** + * Calls the spawn function on an entity. + * + * @param iIndex Entity index + * + * @noreturn + * @error If an invalid entity index is provided or, if the index is a + * client index, the client is not connected, an error will be + * thrown. + */ +native DispatchSpawn(iIndex); + +/** + * Fires/sets a keyvalue on an entity. + * + * @param ... (1) To fire a new keyvalue struct, three parameters should be + * provided in the following manner: + * DispatchKeyValue(entity, "KeyName", "Value"); + * The "szClassName" value will automatically use the classname + * of the specified entity, "fHandled" will be set to 0. + * (2) Inside the pfn_keyvalue() forward this native can be used to + * modify the keyvalue struct inline, two parameters should be + * provided in the following manner: + * DispatchKeyValue("KeyName", "Value"); + * The "szClassName" or "fHandled" values can not be changed. + * + * @noreturn + * @error For variant (1), if an invalid entity index is provided, an + * error will be thrown. For variant (2), if it is used outside of + * the pfn_keyvalue() forward, an error will be thrown. + */ +native DispatchKeyValue(...); + +/** + * Retrieves a value from an entities keyvalues. + * + * @param entity Entity index + * @param szKey Key to retrieve value of + * @param value Buffer to copy value to + * @param maxLength Maximum size of buffer + * + * @return Number of cells written to buffer + * @error If an invalid entity index is provided or, if the index + * is a client index, the client is not connected, an error + * will be thrown. + */ +native get_keyvalue(entity, const szKey[], value[], maxLength); + +/** + * Retrieves buffers from the keyvalue structure. + * + * @note Can only be used inside the pfn_keyvalue() forward. + * + * @param szClassName Buffer to copy classname to + * @param sizea Maximum size of classname buffer + * @param szKeyName Buffer to copy keyname to + * @param sizeb Maximum size of keyname buffer + * @param szVlaue Buffer to copy value to + * @param sizec Maximum size of value buffer + * + * @return 1 on success, 0 if used outside the pfn_keyvalue() + * forward + */ +native copy_keyvalue(szClassName[], sizea, szKeyName[], sizeb, szValue[], sizec); + +/** + * Hurts (and kills, if applicable) players in a sphere. + * + * @note Players that have the DAMAGE_NO flag set in EV_INT_flags will be + * ignored. + * @note The sphere has four different damage zones. Below is pseudo-code of the + * algorithm, indicating how damage will be dealt to players: + * if (distance <= 5 * radius) damage(10 + random(1 * dmg_multi)) + * if (distance <= 4 * radius) damage(25 + random(2 * dmg_multi)) + * if (distance <= 3 * radius) damage(50 + random(3 * dmg_multi)) + * if (distance <= 2 * radius) kill() + * + * @param fExplodeAt Center origin of sphere + * @param iDamageMultiplier Damage multiplier + * @param iRadiusMultiplier Sphere radius + * + * @noreturn + */ +native radius_damage(const Float:fExplodeAt[3], iDamageMultiplier, iRadiusMultiplier); + +/** + * Returns the contents value of an origin. + * + * @note For a list of valid contents values see the CONTENTS_* constants in + * hlsdk_const.inc + * + * @param fCheckAt Origin to retrieve contents of + * + * @return Contents value + */ +native point_contents(const Float:fCheckAt[3]); + +/** + * Returns if an origin is in an entities view cone. Derived from SDK. + * + * @note This uses the entities EV_FL_fov value in the calculations and applies + * it on all axes. It might be unreliable depending on the use-case. + * + * @param entity Entity index + * @param origin Origin + * @param use3d If zero the calculation will ignore the z axis (height), if + * nonzero it is done in 3D + * + * @return 1 if origin is in view code, 0 otherwise + */ +native is_in_viewcone(entity, const Float:origin[3], use3d = 0); + +/** + * Returns if an entity is visible to another entity. Derived from SDK. + * + * @note If the target entity has the FL_NOTARGET flag set, this native always + * returns 0. + * @note This native fires a traceline between the view-offset origins of the + * entities. If the traceline is unobstructed it returns true. This is not + * a full 3D visibility check. + * + * @param entity Entity index + * @param target Target entity index + * + * @return 1 if entity is visible, 0 otherwise + * @error If an invalid entity index is provided or, if the index is a + * client index, the client is not connected, an error will be + * thrown. + */ +native is_visible(entity, target); + +/** + * Fires a trace line between two origins, retrieving the end point and entity + * hit. + * + * @note This native writes to the global engine module trace handle. Additional + * trace results can be retrieved using traceresult(). + * @note This native returns 0 if the trace did not hit anything. As 0 is an + * entity index that is considered to be a valid value for a trace hit + * ("worldspawn"), this native can potentially return a misleading value. + * Check other components of the trace result to verify the entity index. + * + * @param iIgnoreEnt Entity index that trace will ignore, -1 if trace should + * not ignore any entities + * @param fStart Trace starting point + * @param fEnd Trace target point + * @param vReturn Vector to copy trace end point to + * + * @return Entity index if trace hit an entity, 0 otherwise + */ +native trace_line(iIgnoreEnt, const Float:fStart[3], const Float:fEnd[3], Float:vReturn[3]); + +/** + * Fires a trace line between two origins, retrieving the trace normal. + * + * @note This native writes to the global engine module trace handle. Additional + * trace results can be retrieved using traceresult(). + * + * @param iIgnoreEnt Entity index that trace will ignore, -1 if trace should + * not ignore any entities + * @param fStart Trace starting point + * @param fEnd Trace target point + * @param vReturn Vector to copy trace normal to + * + * @return 1 if a normal is available (trace hit something), 0 + * otherwise + */ +native trace_normal(iIgnoreEnt, const Float:fStart[3], const Float:fEnd[3], Float:vReturn[3]); + +/** + * Fires a trace hull on a specified origin or between two origins. + * + * @note This native writes to the global engine module trace handle. Additional + * trace results can be retrieved using traceresult(). + * @note For a list of valid hull types see the HULL_* constants in + * hlsdk_const.inc + * @note For a list of valid ignore types see the *IGNORE_* constants in + * hlsdk_const.inc + * + * @param origin Trace start point (and end point if not specified) + * @param hull Hull type + * @param ignoredent Entity index that trace will ignore + * @param ignoremonsters Entity ignore type + * @param end Trace end point, pass NULL_VECTOR to use start point + * + * @return Custom bitflag sum of relevant trace results + * StartSolid (1), AllSolid (2) and InOpen (4) + */ +native trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0, const Float:end[3] = NULL_VECTOR); + +/** + * Attempts to describe an obstacle by firing trace lines in a specified + * direction, offset on the z-axis around an origin. + * + * @note The functionality of this native can mostly be replaced by a single + * hull trace. This native does not write to the global engine module + * trace handle. + * @note This native is intended to examine an obstacle in front of a standing + * player. Start should usually be the origin of a client while angle + * should be its forward angle vector. 73 traces are fired, each offset by + * one unit on the z-axis from the last, starting at -36 and moving up to + * +36. This is because a standing player model is 72 units high, so 73 + * units of clearance are required to fit them. The values stored in the + * various parameters then attempt to describe the obstacle. + * @note To fully understand the nuances of the algorithm it is necessary to + * view its source code located in engine.cpp of the engine module. + * + * @param start Starting origin + * @param angle Trace line direction + * @param give Units that a trace line can be longer than the + * shortest trace line to still be considered hitting + * the same obstacle + * @param ignoreEnt Entity index that traces will ignore, -1 if traces + * should not ignore any entities + * @param hitX Variable to store X axis value of shortest trace + * line endpoint in + * @param hitY Variable to store Y axis value of shortest trace + * line endpoint in + * @param shortestDistance Variable to store length of shortest trace line in + * @param shortestDistLow Variable to store Z axis offset of shortest trace + * line in + * @param shortestDistHigh Variable to store Z axis offset of highest trace + * line that satisfies "give" condition in + * + * @noreturn + */ +native trace_forward(const Float:start[3], const Float:angle[3], Float:give, ignoreEnt, &Float:hitX, &Float:hitY, &Float:shortestDistance, &Float:shortestDistLow, &Float:shortestDistHigh); + +/** + * Finds a grenade entity, matching by owner. + * + * @param id Owner entity index to match + * @param model Buffer to copy grenade model to + * @param len Maximum length of buffer + * @param grenadeid Entity index to start searching from + * + * @return Grenade entity index > 0 if found, 0 otherwise + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native get_grenade_id(id, model[], len, grenadeid = 0); + +/** + * Returns the game time based on the game tick. + * + * @note This time is counted up from map start. If the engine is not processing + * this function will return the same value between calls, which makes it + * unusable for profiling purposes. + * + * @return Game time, in seconds + */ +native Float:halflife_time(); + +/** + * Sets the map lighting level. + * + * @note After setting the map lighting level, the engine module enforces it by + * continuously re-applying it until it is reset. + * + * @param Lighting Map lighting level (described by a character a-z), #OFF to + * reset + * + * @noreturn + */ +native set_lights(const Lighting[]); + +/** + * Attaches a clients viewport to an entity. + * + * @note To reset the clients viewport, call this function with the client index + * as the target entity. + * + * @param iIndex Client index + * @param iTargetIndex Index of entity to attach to + * + * + * @error If the client index is not within the range of 1 to + * MaxClients, or the client is not connected, an error + * will be thrown. + */ +native attach_view(iIndex, iTargetIndex); + +/** + * Sets the engine module view mode on a client. + * + * @note For a list of valid view modes see the CAMERA_* constants in + * engine_const.inc + * @note The engine module uses a custom entity to achieve the camera effects + * and requires "models/rpgrocket.mdl" to be precached by the plugin. + * + * @param iIndex Client index + * @param ViewType View mode + */ +native set_view(iIndex, ViewType); + +/** + * Plays back an event on the client. Most prominently used for gun firing + * animations. + * + * @note Event indexes can be acquired using precache_event() with the sc dummy + * files in the events folder. + * + * @param flags Event flags + * @param invoker Index of entity to invoke event on + * @param eventindex Index of event in the precache table + * @param delay Time until the event is played + * @param origin Origin to play event from + * @param angles Angles to play event with + * @param fparam1 Float parameter 1 to pass along into/with the event + * @param fparam2 Float parameter 2 to pass along into/with the event + * @param iparam1 Integer parameter 1 to pass along into/with the event + * @param iparam2 Integer parameter 2 to pass along into/with the event + * @param bparam1 Boolean parameter 1 to pass along into/with the event + * @param bparam2 Boolean parameter 2 to pass along into/with the event + * + * @noreturn + */ +native playback_event(flags, invoker, eventindex, Float:delay, const Float:origin[3], const Float:angles[3], Float:fparam1, Float:fparam2, iparam1, iparam2, bparam1, bparam2); + +/** + * Retrieves a value from a usercmd struct. + * + * @note This native can only be used inside the client_cmdStart() forward. If + * it is used outside this forward it will not retrieve any results and + * always return 0. + * @note For a list of valid usercmd entries see the usercmd_* constants in + * engine_const.inc + * + * @param type Entry to retrieve from + * @param ... Depending on the entry type a different number of + * additional parameters should be provided: + * int - Returns the entry integer value directly, no + * additional parameters required + * float - Stores the entry float value into the + * variable provided as the second parameter + * vector - Copies the entry vector to the Float:array[3] + * provided in the second parameter + * + * @return Changes depending on the entry type: + * int - Returns the entry integer value + * float - Returns 1 + * vector - Returns 1 + */ +native get_usercmd(type, any:...); + +/** + * Sets a value in a usercmd struct. + * + * @note This native can only be used inside the client_cmdStart() forward. + * @note For a list of valid usercmd entries see the usercmd_* constants in + * engine_const.inc + * @note Changes will be immediately reflected in get_usercmd() for all plugins. + * + * @param type Entry to write to + * @param ... Depending on the entry type a different additional parameter + * should be provided: + * int - Second parameter should be an integer variable + * float - Second parameter should be a float variable + * vector - Second parameter should be a Float:array[3] + * + * @noreturn + */ +native set_usercmd(type, any:...); + +/** + * Retrieves a string from the engine string table. + * + * @param _string String table index + * @param _returnString Buffer to copy string to + * @param _len Maximum size of buffer + * + * @return Number of cells written to buffer + */ +native eng_get_string(_string, _returnString[], _len); + +/** + * @section Forwards + */ + +/** + * Called when two entities touch. + * + * @param ptr Index of entity being touched + * @param ptd Index of entity touching + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward pfn_touch(ptr, ptd); + +/** + * Called at the start of every server frame. + * + * @note Using his forward can easily become performance-critical. More specific + * hooks and forwards should be used whenever possible. + * + * @noreturn + */ +forward server_frame(); + +/** + * Called when a client types kill in console. + * + * @param id Client index + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward client_kill(id); + +/** + * Called at the start of each client think. + * + * @note Using his forward can easily become performance-critical. More specific + * hooks and forwards should be used whenever possible. + * + * @param id Client index + * + * @noreturn + */ +forward client_PreThink(id); + +/** + * Called after each client think. + * + * @note Using his forward can easily become performance-critical. More specific + * hooks and forwards should be used whenever possible. + * + * @param id Client index + * + * @noreturn + */ +forward client_PostThink(id); + +/** + * Called when a client triggers an impulse. + * + * @param id Client index + * @param impulse Impulse triggered by client + * + * @param PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to + * nullify impulse (CmdStart() is not blocked) + */ +forward client_impulse(id, impulse); + +/** + * Called for CmdStart() on a client. + * + * @note Use [get|set]_usercmd() to read and modify information in the usercmd + * struct. + * + * @param id Client index + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward client_cmdStart(id); + +/** + * Called when an entity thinks. + * + * @param entid Entity index + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward pfn_think(entid); + +/** + * Called when an event is played. + * + * @param flags Event flags + * @param entid Index of entity to invoke event on + * @param eventid Index of event in the precache table + * @param delay Time until the event is played + * @param Origin Origin to play event from + * @param Angles Angles to play event with + * @param fparam1 Float parameter 1 to pass along into/with the event + * @param fparam2 Float parameter 2 to pass along into/with the event + * @param iparam1 Integer parameter 1 to pass along into/with the event + * @param iparam2 Integer parameter 2 to pass along into/with the event + * @param bparam1 Boolean parameter 1 to pass along into/with the event + * @param bparam2 Boolean parameter 2 to pass along into/with the event + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward pfn_playbackevent(flags, entid, eventid, Float:delay, Float:Origin[3], Float:Angles[3], Float:fparam1, Float:fparam2, iparam1, iparam2, bparam1, bparam2); + +/** + * Called when a keyvalue pair is sent to an entity. + * + * @note Use copy_keyvalue() to retrieve the keyvalue information, and + * DispatchKeyVaue() to modify it. + * + * @param entid Entity index + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward pfn_keyvalue(entid); + +/** + * Called when an entity is spawned. + * + * @param entid Entity index + * + * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block + */ +forward pfn_spawn(entid); + +/** + * @endsection + */ + +#include diff --git a/amxmodx/scripting/include/engine_const.inc b/amxmodx/scripting/include/engine_const.inc new file mode 100644 index 0000000..389a776 --- /dev/null +++ b/amxmodx/scripting/include/engine_const.inc @@ -0,0 +1,310 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Engine Constants +// + +#if defined _engine_const_included + #endinput +#endif +#define _engine_const_included + +#include + +/** + * Flags for the [set|get]_speak() natives. + * + * @note These do not correspond to any HLSDK constants and are only relevant to + * the custom functionality provided by the engine module. + */ +#define SPEAK_NORMAL 0 // Normal behavior, client follows alltalk rules +#define SPEAK_MUTED 1 // Client can not talk +#define SPEAK_ALL 2 // Client can talk to every other client +#define SPEAK_LISTENALL 4 // Client can listen to every other client + +/** + * View types for the set_view() native. + * + * @note These do not correspond to any HLSDK constants and are only relevant to + * the custom functionality provided by the engine module. + */ +#define CAMERA_NONE 0 +#define CAMERA_3RDPERSON 1 +#define CAMERA_UPLEFT 2 +#define CAMERA_TOPDOWN 3 + +/** + * @section Entvar constants used with entity_[get|set]_* functions. + */ + +/** + * Integers, use with entity_[get|set]_int() + */ +enum { + EV_INT_gamestate = 0, + EV_INT_oldbuttons, + EV_INT_groupinfo, + EV_INT_iuser1, + EV_INT_iuser2, + EV_INT_iuser3, + EV_INT_iuser4, + EV_INT_weaponanim, + EV_INT_pushmsec, + EV_INT_bInDuck, + EV_INT_flTimeStepSound, + EV_INT_flSwimTime, + EV_INT_flDuckTime, + EV_INT_iStepLeft, + EV_INT_movetype, + EV_INT_solid, + EV_INT_skin, + EV_INT_body, + EV_INT_effects, + EV_INT_light_level, + EV_INT_sequence, + EV_INT_gaitsequence, + EV_INT_modelindex, + EV_INT_playerclass, + EV_INT_waterlevel, + EV_INT_watertype, + EV_INT_spawnflags, + EV_INT_flags, + EV_INT_colormap, + EV_INT_team, + EV_INT_fixangle, + EV_INT_weapons, + EV_INT_rendermode, + EV_INT_renderfx, + EV_INT_button, + EV_INT_impulse, + EV_INT_deadflag, +}; + +/** + * Floats, use with entity_[get|set]_float() + */ +enum { + EV_FL_impacttime = 0, + EV_FL_starttime, + EV_FL_idealpitch, + EV_FL_pitch_speed, + EV_FL_ideal_yaw, + EV_FL_yaw_speed, + EV_FL_ltime, + EV_FL_nextthink, + EV_FL_gravity, + EV_FL_friction, + EV_FL_frame, + EV_FL_animtime, + EV_FL_framerate, + EV_FL_health, + EV_FL_frags, + EV_FL_takedamage, + EV_FL_max_health, + EV_FL_teleport_time, + EV_FL_armortype, + EV_FL_armorvalue, + EV_FL_dmg_take, + EV_FL_dmg_save, + EV_FL_dmg, + EV_FL_dmgtime, + EV_FL_speed, + EV_FL_air_finished, + EV_FL_pain_finished, + EV_FL_radsuit_finished, + EV_FL_scale, + EV_FL_renderamt, + EV_FL_maxspeed, + EV_FL_fov, + EV_FL_flFallVelocity, + EV_FL_fuser1, + EV_FL_fuser2, + EV_FL_fuser3, + EV_FL_fuser4, +}; + +/** + * Vectors, use with entity_[get|set]_vector() + */ +enum { + EV_VEC_origin = 0, + EV_VEC_oldorigin, + EV_VEC_velocity, + EV_VEC_basevelocity, + EV_VEC_clbasevelocity, + EV_VEC_movedir, + EV_VEC_angles, + EV_VEC_avelocity, + EV_VEC_punchangle, + EV_VEC_v_angle, + EV_VEC_endpos, + EV_VEC_startpos, + EV_VEC_absmin, + EV_VEC_absmax, + EV_VEC_mins, + EV_VEC_maxs, + EV_VEC_size, + EV_VEC_rendercolor, + EV_VEC_view_ofs, + EV_VEC_vuser1, + EV_VEC_vuser2, + EV_VEC_vuser3, + EV_VEC_vuser4, +}; + +/** + * Edicts, use with entity_[get|set]_edict() + */ +enum { + EV_ENT_chain = 0, + EV_ENT_dmg_inflictor, + EV_ENT_enemy, + EV_ENT_aiment, + EV_ENT_owner, + EV_ENT_groundentity, + EV_ENT_pContainingEntity, + EV_ENT_euser1, + EV_ENT_euser2, + EV_ENT_euser3, + EV_ENT_euser4, +}; + +/** + * Strings, use with entity_[get|set]_string() + */ +enum { + EV_SZ_classname = 0, + EV_SZ_globalname, + EV_SZ_model, + EV_SZ_target, + EV_SZ_targetname, + EV_SZ_netname, + EV_SZ_message, + EV_SZ_noise, + EV_SZ_noise1, + EV_SZ_noise2, + EV_SZ_noise3, + EV_SZ_viewmodel, + EV_SZ_weaponmodel, +}; + +/** + * Bytearrays, use with entity_[get|set]_byte() + */ +enum { + EV_BYTE_controller1 = 0, + EV_BYTE_controller2, + EV_BYTE_controller3, + EV_BYTE_controller4, + EV_BYTE_blending1, + EV_BYTE_blending2, +}; + +/** + * @endsection + */ + +#if defined _jghg_enums + #endinput +#endif +#define _jghg_enums + +/** + * Used by get_global_[edict/float/int/string/vector]() + */ +enum { + + // Edict + GL_trace_ent = 0, + + // Float + GL_coop, + GL_deathmatch, + GL_force_retouch, + GL_found_secrets, + GL_frametime, + GL_serverflags, + GL_teamplay, + GL_time, + GL_trace_allsolid, + GL_trace_fraction, + GL_trace_inopen, + GL_trace_inwater, + GL_trace_plane_dist, + GL_trace_startsolid, + + // Int + GL_cdAudioTrack, + GL_maxClients, + GL_maxEntities, + GL_msg_entity, + GL_trace_flags, + GL_trace_hitgroup, + + // String + GL_pStringBase, + GL_mapname, + GL_startspot, + + // Vector + GL_trace_endpos, + GL_trace_plane_normal, + GL_v_forward, + GL_v_right, + GL_v_up, + GL_vecLandmarkOffset, + + // Void (not supported) + GL_pSaveData +}; + + +/** + * Used by [get/set]_usercmd() + */ +enum +{ + usercmd_float_start, + usercmd_forwardmove, // Float + usercmd_sidemove, // Float + usercmd_upmove, // Float + usercmd_float_end, + usercmd_int_start, + usercmd_lerp_msec, // short + usercmd_msec, // byte + usercmd_lightlevel, // byte + usercmd_buttons, // unsigned short + usercmd_impulse, // byte + usercmd_weaponselect, // byte + usercmd_impact_index, // int + usercmd_int_end, + usercmd_vec_start, + usercmd_viewangles, // Vector + usercmd_impact_position, // vec + usercmd_vec_end +}; + +/** + * Used by the traceresult() + */ +enum +{ + TR_AllSolid, // (int) if true, plane is not valid + TR_StartSolid, // (int) if true, the initial point was in a solid area + TR_InOpen, // (int) + TR_InWater, // (int) + TR_Fraction, // (float) time completed, 1.0 = didn't hit anything + TR_EndPos, // (vector) final position + TR_PlaneDist, // (float) + TR_PlaneNormal, // (vector) surface normal at impact + TR_Hit, // (entity) entity the surface is on + TR_Hitgroup // (int) 0 == generic, non zero is specific body part +}; + diff --git a/amxmodx/scripting/include/engine_stocks.inc b/amxmodx/scripting/include/engine_stocks.inc new file mode 100644 index 0000000..baa386f --- /dev/null +++ b/amxmodx/scripting/include/engine_stocks.inc @@ -0,0 +1,248 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// Special thanks to AssKicR, Freecode, and T(+)rget. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Engine Stocks +// + +#if defined _engine_stocks_included + #endinput +#endif +#define _engine_stocks_included + +#if !defined _amxmodx_included + #include +#endif + +#if !defined _engine_included + #include +#endif + +stock fakedamage(idvictim,const szClassname[],Float:takedmgdamage,damagetype) +{ + new entity = create_entity("trigger_hurt"); + if (entity) + { + DispatchKeyValue(entity,"classname","trigger_hurt"); + new szDamage[16]; + // Takedamages only do half damage per attack (damage is damage per second, and it's triggered in 0.5 second intervals). + // Compensate for that. + format(szDamage,15,"%f",takedmgdamage * 2); + DispatchKeyValue(entity,"dmg",szDamage); + format(szDamage,15,"%i",damagetype); + DispatchKeyValue(entity,"damagetype",szDamage); + DispatchKeyValue(entity,"origin","8192 8192 8192"); + DispatchSpawn(entity); + entity_set_string(entity, EV_SZ_classname, szClassname); + fake_touch(entity,idvictim); + remove_entity(entity); + return 1; + } + return 0; +} + +//wrapper for find_ent_by_class +stock find_ent(iStart, const szClassname[]) +{ + return find_ent_by_class(iStart, szClassname); +} + +/* Get the Button(s) user is pressing */ +stock get_user_button(id) +{ + return entity_get_int(id, EV_INT_button); +} + +stock get_user_oldbutton(id) +{ + return entity_get_int(id, EV_INT_oldbuttons); +} + +/* Get flags an entity is flagged with */ +stock get_entity_flags(ent) +{ + return entity_get_int(ent, EV_INT_flags); +} + +/* Get the distance between two entities */ +stock get_entity_distance(ent1, ent2) +{ + return floatround(entity_range(ent1, ent2)); +} + +/* Get grenade thrown by this user */ +stock get_grenade(id) +{ + new iGrenade = find_ent_by_class(-1, "grenade"); + while(iGrenade > 0) + { + if(entity_get_edict(iGrenade, EV_ENT_owner) == id) + return iGrenade; + + iGrenade = find_ent_by_class(iGrenade, "grenade"); + } + + return 0; +} + +/* Get origin of a brush entity */ +stock get_brush_entity_origin(ent, Float:orig[3]) +{ + new Float:Min[3], Float:Max[3]; + + entity_get_vector(ent, EV_VEC_origin, orig); + entity_get_vector(ent, EV_VEC_mins, Min); + entity_get_vector(ent, EV_VEC_maxs, Max); + + orig[0] += (Min[0] + Max[0]) * 0.5; + orig[1] += (Min[1] + Max[1]) * 0.5; + orig[2] += (Min[2] + Max[2]) * 0.5; + + return 1; +} + +/* Remove entity by name */ +stock remove_entity_name(const eName[]) +{ + new iEntity = find_ent_by_class(-1, eName); + while (iEntity > 0) + { + remove_entity(iEntity); + iEntity = find_ent_by_class(-1, eName); + } + + return 1; +} + +/* Get the contents of the point a user is aiming at */ +stock ViewContents(id) +{ + new origin[3], Float:Orig[3]; + get_user_origin(id, origin, Origin_AimEndEyes); + Orig[0] = float(origin[0]); + Orig[1] = float(origin[1]); + Orig[2] = float(origin[2]); + + return point_contents(Orig); +} + +stock get_speed(ent) +{ + new Float:Vel[3]; + entity_get_vector(ent, EV_VEC_velocity, Vel); + + return floatround(vector_length(Vel)); +} + +/* Set rendering of an entity */ +stock set_rendering(index, fx=kRenderFxNone, r=255, g=255, b=255, render=kRenderNormal, amount=16) +{ + entity_set_int(index,EV_INT_renderfx,fx); + new Float:RenderColor[3]; + RenderColor[0] = float(r); + RenderColor[1] = float(g); + RenderColor[2] = float(b); + entity_set_vector(index,EV_VEC_rendercolor,RenderColor); + entity_set_int(index,EV_INT_rendermode,render); + entity_set_float(index,EV_FL_renderamt,float(amount)); + + return 1; +} + +/* Set flags on an entity */ +stock set_entity_flags(ent,flag,onoff) +{ + new iFlags = entity_get_int(ent, EV_INT_flags); + if(iFlags & flag) + { + if(onoff == 1) return 2; + iFlags &= ~flag; + } + else + { + if(onoff == 0) return 2; + iFlags |= flag; + } + entity_set_int(ent, EV_INT_flags, iFlags); + return 1; +} + +/* If visible = 1, entity will be set to be visible, else invisible. */ +stock set_entity_visibility(entity, visible = 1) +{ + entity_set_int(entity, EV_INT_effects, visible == 1 ? entity_get_int(entity, EV_INT_effects) & ~EF_NODRAW : entity_get_int(entity, EV_INT_effects) | EF_NODRAW); + + return 1; +} + +/* Returns 1 if entity is visible. */ +stock get_entity_visibility(entity) +{ + return !(entity_get_int(entity, EV_INT_effects) & EF_NODRAW); +} + +stock set_user_velocity(entity, const Float:vec[3]) +{ + return entity_set_vector(entity, EV_VEC_velocity, vec); +} + +stock get_user_velocity(entity, Float:vec[3]) +{ + return entity_get_vector(entity, EV_VEC_velocity, vec); +} + +/* Backwards compatible */ +/* Hurts/Kills players in a sphere, like an explosion, Multiplier determines damage. */ +stock RadiusDamage(const Float:fExplodeAt[3], iDamageMultiplier, iRadiusMultiplier) +{ + return radius_damage(fExplodeAt, iDamageMultiplier, iRadiusMultiplier); +} +/* Gives you a velocity in the direction a player is looking, iVelocity is the multiplier. */ +stock VelocityByAim(iIndex,iVelocity, Float:vRetValue[3]) +{ + return velocity_by_aim(iIndex,iVelocity,vRetValue); +} +/* Will return the contents of a point (inside map? in sky? outside map? etc.). */ +stock PointContents(const Float:fCheckAt[3]) +{ + return point_contents(fCheckAt); +} + +stock set_size(index, const Float:mins[3], const Float:maxs[3]) +{ + return entity_set_size(index,mins,maxs); +} + +//by Twilight Suzuka, request addition at29428 +//"Lifted from HLSDK" +stock IsInWorld( ent ) +{ + new Float:origin[3]; + entity_get_vector(ent,EV_VEC_origin,origin); + + if (origin[0] >= 4096.0) return 0; + if (origin[1] >= 4096.0) return 0; + if (origin[2] >= 4096.0) return 0; + if (origin[0] <= -4096.0) return 0; + if (origin[1] <= -4096.0) return 0; + if (origin[2] <= -4096.0) return 0; + + new Float:velocity[3]; + entity_get_vector(ent,EV_VEC_velocity,velocity); + + if (velocity[0] >= 2000) return 0; + if (velocity[1] >= 2000) return 0; + if (velocity[2] >= 2000) return 0; + if (velocity[0] <= -2000) return 0; + if (velocity[1] <= -2000) return 0; + if (velocity[2] <= -2000) return 0; + + return 1; +} diff --git a/amxmodx/scripting/include/esf.inc b/amxmodx/scripting/include/esf.inc new file mode 100644 index 0000000..cd67903 --- /dev/null +++ b/amxmodx/scripting/include/esf.inc @@ -0,0 +1,70 @@ +/*********************************************** + +[ Corona-Bytes.NET ] EvolutionX Core Plugin + + (c) Corona - Bytes .NET coders :: coders@corona-bytes.net + + > 2005 Corona Bytes :: http://www.corona-bytes.net + +***********************************************/ + +#if defined __EVOLUTION_CORE__ + #endinput +#endif +#define __EVOLUTION_CORE__ + +#pragma library EvolutionXCore + +native setClientPL ( Client, PowerLevel ); +native getClientPL ( Client ); +native setClientACPL ( Client, ActualPowerLevel ); +native getClientACPL ( Client ); +native setClientADPL ( Client, AfterDeathPowerLevel ); +native getClientADPL ( Client ); +native setClientSPL ( Client, PowerLevel ); +native setClientPLtoADPL ( Client ); + +native setClientKI ( Client, Ki ); +native getClientKI ( Client ); + +native setClientHP ( Client, Health ); +native getClientHP ( Client ); +native setClientMHP ( Client, MaximumHealth ); +native getClientMHP ( Client ); + +native setClientSPEED ( Client, Speed ); +native getClientSPEED ( Client ); +native setClientSWOOPSPEED ( Client, SwoopSpeed ); +native getClientSWOOPSPEED ( Client ); + +native setClientPROTECT ( Client, bool:Enable = true ); +native getClientPROTECT ( Client ); + +native setClientFROZEN ( Client, bool:Enable = true ); +native getClientFROZEN ( Client ); + +native setClientGOD ( Client, bool:Enable = true ); +native getClientGOD ( Client ); + +native getClientFLY ( Client ); + +native setClientHiddenTURBO ( Client, bool:Enable = true ); +native getClientTURBO ( Client ); + +native getClientBLOCK ( Client ); + +native setClientHiddenPOWERUP ( Client, bool:Enable = true ); +native getClientPOWERUP ( Client ); + +native getClientSWOOPING ( Client ); +native getClientATKSHOOT ( Client ); +native getClientATKCHARGE ( Client ); +native getClientMELEE ( Client ); +native getClientTHROWAWAY ( Client ); +native getClientTHROW ( Client ); +native getClientWALLGND ( Client ); +native getClientINFREEFALL ( Client ); +native getClientBEAMJUMP ( Client ); + +// kills a player without score/death msg +native silentClientKILL ( Client ); \ No newline at end of file diff --git a/amxmodx/scripting/include/esf_const.inc b/amxmodx/scripting/include/esf_const.inc new file mode 100644 index 0000000..0b2615b --- /dev/null +++ b/amxmodx/scripting/include/esf_const.inc @@ -0,0 +1,74 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// Based on stocks and information provided by LynX. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _esfconst_included + #endinput +#endif +#define _esfconst_included + +enum +{ + Character_Buu = 1, + Character_Goku = 2, + Character_Gohan = 3, //my favorite :) + Character_Krillin = 4, + Character_Frieza = 5, + Character_Piccolo = 6, + Character_Trunks = 7, + Character_Vegeta = 8, + Character_Cell = 9, +}; + +enum +{ + Explosion_Blue = 0, + Explosion_Green, + Explosion_Orange, + Explosion_Purple, + Explosion_Yellow, + Explosion_Red, + Explosion_White, + Explosions_Total, +}; + +enum +{ + Attack_Kamehameha=1, + Attack_SpiritBomb, + Attack_GalletGun, + Attack_FinalFlash, + Attack_Renzoku, + Attack_Kametorpedo, + Attack_GenericBeam, + Attack_Throw, +}; + +enum +{ + Direction_Left=1, + Direction_Right, + Direction_Up, + Direction_Down, + Direction_Forward, + Direction_Backward, +}; + +enum +{ + Recovery_Kicked=1, + Recovery_Tumbled, + Recovery_Lying, + Recovery_Thrown, +}; + +#define ESF_CHARGING 1 +#define ESF_CONTROLLING 2 +#define ESF_SHOOTING 3 +#define ESF_SHOT 4 diff --git a/amxmodx/scripting/include/fakemeta.inc b/amxmodx/scripting/include/fakemeta.inc new file mode 100644 index 0000000..35171a8 --- /dev/null +++ b/amxmodx/scripting/include/fakemeta.inc @@ -0,0 +1,1127 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Fakemeta Functions +// + +#if defined _fakemeta_included + #endinput +#endif +#define _fakemeta_included + +#include + +#pragma reqlib fakemeta +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib fakemeta +#endif + +/** + * Returns entvar data from an entity. Use the pev_* enum (in fakemeta_const.inc) to specify which data you want retrieved. + * + * @note This function uses "read_data" style data syntax. It returns integer values, + * by-references float data, and sets a buffer for string data. + * + * @note If retrieving strings, you may optionally get a pointer into the global string table. Depending on + * your situation, there are two ways to do this. + * 1: This simply gets the pointer. + * new ptr = pev(entid, pev_classname) + * 2: The pointer will be stored in ptr AND the actual string is retrieved. + * new ptr, classname[32] + * pev(entid, pev_classname, ptr, classname, 31) + * + * @param _index The entity index to lookup. + * @param _value The pev field to lookup (look in fakemeta_const.inc) + */ +native pev(_index,_value,any:...); + +/** + * Sets entvar data for an entity. Use the pev_* enum from fakemeta_const.inc for reference. + * + * @note Setting string data will automatically allocate a new string (via AllocString) + * If you have a string already allocated with your own call to AllocString, use + * set_pev_string_ptr instead. + * + * @param _index The entity index to set the value on. + * @param _value The pev field to set, (look in fakemeta_const.inc) + */ +native set_pev(_index,_value,any:...); + +/** + * Use this native to set a pev field to a string that is already allocated (via a function such + * as EngFunc_AllocString). + * + * @note If you specify _value as anything other than string fields, an error will be thrown. + * @note Pass 0 as the _string field to set it to an empty string. + * + * @param _index The entity index to set the value on. + * @param _value The pev field to set - MUST be a string field. + * @param _string The string handle, retrieved from places like AllocString. + */ +native set_pev_string(_index, _value, _string); + + +/** + * Checks the validity of an entity. + * + * @param entindex The entity id to check. + * + * @return 0 on invalid entity + * 1 on entity is valid + * 2 on entity is valid and it has private data (safe to use pdata natives on). + */ +native pev_valid(entindex); + +/** + * Returns the serial number for each entity. The serial number is a unique identity + * generated when an entity is created. + * + * @param entindex The entity id. + * + * @return The serial number for the entity. + */ +native pev_serial(entindex); + +/* Returns any global variable inside globalvars_t structure. Use the glb_* enum. + * + * When returning data from glb_pStringBase (the global string table), you may give a pointer into that table + * in order to get different strings. + * Example: + * new model[128] + * new ptr = pev(id, pev_viewmodel) + * global_get(glb_pStringBase, ptr, model, 127) + */ +native global_get(_value, any:...); + +/** + * Returns a integer from an entity's private data. + * + * _linuxdiff value is what to add to the _Offset for linux servers. + * _macdiff value is what to add to the _Offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _Offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return An integer value is returned. + */ +native get_pdata_int(_index, _Offset, _linuxdiff = 5, _macdiff = 5); + +/** + * Sets an integer to an entity's private data. + * + * _linuxdiff value is what to add to the _Offset for linux servers. + * _macdiff value is what to add to the _Offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _Offset Offset to search. + * @param _Value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_int(_index, _Offset, _Value, _linuxdiff = 5, _macdiff = 5); + +/** + * Returns a float from an entity's private data. + * + * _linuxdiff value is what to add to the _Offset for linux servers. + * _macdiff value is what to add to the _Offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _Offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return An float value is returned. + */ +native Float:get_pdata_float(_index, _Offset, _linuxdiff = 5, _macdiff = 5); + +/** + * Sets a float to an entity's private data. + * + * _linuxdiff value is what to add to the _Offset for linux servers. + * _macdiff value is what to add to the _Offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _Offset Offset to search. + * @param _Value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_float(_index, _Offset, Float:_Value, _linuxdiff = 5, _macdiff = 5); + +/** + * Tries to retrieve an edict pointer from an entity's private data. + * + * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, + * get_pdata_ent searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return -2 if an invalid entity was found. + * -1 if an empty entity was found. + * Otherwise, an entity index is returned. + */ +native get_pdata_ent(_index, _offset, _linuxdiff = 20, _macdiff = 20); + +/** + * Sets an edict pointer to an entity's private data. + * + * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, + * set_pdata_ent searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_ent(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); + +/** + * Returns a boolean from an entity's private data. + * + * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, + * get_pdata_bool searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return An boolean value is returned. + */ +native bool:get_pdata_bool(_index, _offset, _linuxdiff = 20, _macdiff = 20); + +/** + * Sets a boolean to an entity's private data. + * + * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, + * set_pdata_bool searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_bool(_index, _offset, bool:_value, _linuxdiff = 20, _macdiff = 20); + +/** + * Returns a byte value from an entity's private data. + * + * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, + * get_pdata_byte searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return A byte value is returned. + */ +native get_pdata_byte(_index, _offset, _linuxdiff = 20, _macdiff = 20); + +/** + * Sets a byte value to an entity's private data. + * + * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, + * set_pdata_byte searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_byte(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); + +/** + * Returns a short value from an entity's private data. + * + * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, + * get_pdata_short searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return A short value is returned. + */ +native get_pdata_short(_index, _offset, _linuxdiff = 20, _macdiff = 20); + +/** + * Sets a short value to an entity's private data. + * + * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, + * set_pdata_short searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_short(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); + +/** + * Returns a vector from an entity's private data. + * + * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, + * get_pdata_vector searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _output Vector returned by reference. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native get_pdata_vector(_index, _offset, Float:_output[3], _linuxdiff = 20, _macdiff = 20); + +/** + * Sets a vector to an entity's private data. + * + * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, + * set_pdata_vector searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _origin Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_vector(_index, _offset, Float:_origin[3], _linuxdiff = 20, _macdiff = 20); + +/** + * Tries to retrieve an edict (entity encapsulation) pointer from an entity's private data. + * + * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, + * get_pdata_ehandle searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return -2 if an invalid entity was found. + * -1 if an empty entity was found. + * 0 if serialnumber is not matching. + * Otherwise, an entity index is returned. + */ +native get_pdata_ehandle(_index, _offset, _linuxdiff = 20, _macdiff = 20); + +/** + * Sets an edict (entity encapsulation) pointer to an entity's private data. + * + * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, + * set_pdata_ehandle searches in increments of 1. + * + * _linuxdiff value is what to add to the _offset for linux servers. + * _macdiff value is what to add to the _offset for os x servers. + * + * A log error is thrown on invalid _index and _Offset. + * + * @param _index Entity index. + * @param _offset Offset to search. + * @param _value Value to set. + * @param _linuxdiff Linux difference. + * @param _macdiff Mac OS X difference. + * @return 1 on success. + */ +native set_pdata_ehandle(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); + +/* Registers a forward. + * Returns an id you can pass to unregister_forward + */ +native register_forward(_forwardType,const _function[],_post=0); + +/* Unregisters a forward. + * The registerId must be from register_forward, and + * post/forwardtype must match what you registered the forward as. + */ +native unregister_forward(_forwardType, registerId, post=0); + +/* Returns data for metamod */ +native forward_return(type,any:...); + +/* Returns the original return value of an engine function. + * This is only valid in forwards that were registered as post. + * + * get_orig_retval() - no params, retrieves integer return value + * get_orig_retval(&Float:value) - retrieves float return value by reference + * get_orig_retval(value[], len) - retrives string return value + */ +native get_orig_retval(any:...); + +native engfunc(type,any:...); +native dllfunc(type,any:...); + +//only use this with functions that pass a Trace +// get: zero extra params - return int, one extra param = byref float or vector +// set: use anything +native get_tr(TraceResult:tr_member, any:...); +native set_tr(TraceResult:tr_member, any:...); + +//Upgraded version takes in a TraceResult handle, optionally passed in as the last parameter to the +//TraceResult forward. Use 0 to specify the global traceresult handle set from calling +// some of the Engfucs. +native get_tr2(tr_handle, any:tr_member, any:...); +native set_tr2(tr_handle, any:tr_member, any:...); + +/** + * Creates a traceresult handle. This value should never be altered. + * The handle can be used in get/set_tr2 and various traceresult engine functions. + * + * NOTE: You must call free_tr2() on every handle made with create_tr2(). + * + * @return A new TraceResult handle. + */ +native create_tr2(); + +/** + * Frees a traceresult handle created with free_tr2(). Do not call + * this more than once per handle, or on handles not created through + * create_tr2(). + * + * @param tr_handle TraceResult handle created via create_tr2(). + * @noreturn + */ +native free_tr2(tr_handle); + +//Same as above, use either a kvd_handle or 0 for global reserved kvd data +//kvd_handle is passed by the kvd hook, last param +native get_kvd(kvd_handle, KeyValueData:member, any:...); + +//Using set_kvd with the handle from the hook for anything under KV_fHandled +// is considered an undefined operation (it could crash). You should fire a new +// keyvalues structure rather than changing the internal engine strings. +native set_kvd(kvd_handle, KeyValueData:member, any:...); + +/** + * Creates a KeyValueData handle. + * + * @note Handles should be freed using free_kvd(). + * + * @return New KeyValueData handle + */ +native create_kvd(); + +/** + * Frees a KeyValueData handle. + * + * @param kvd_handle KeyValueData handle + * + * @noreturn + */ +native free_kvd(kvd_handle); + +// These functions are used with the clientdata data structure (FM_UpdateClientData) +// Get: 0 extra params - Return integer; 1 extra param - by ref float or vector; 2 extra params - string and length +// Set: Use anything +// Use 0 for cd_handle to specify the global clientdata handle +native get_cd(cd_handle, ClientData:member, any:...); +native set_cd(cd_handle, ClientData:member, any:...); + +// These functions are used with the entity_state data structure (FM_AddToFullPack) +// Get: 0 extra params - Return integer; 1 extra param - by ref float or vector or array +// Set: Use anything +// Use 0 for es_handle to specify the global entity_state handle +native get_es(es_handle, EntityState:member, any:...); +native set_es(es_handle, EntityState:member, any:...); + +// These functions are used with the usercmd data structure (FM_CmdStart) +// Get: 0 extra params - Return integer; 1 extra param - by ref float or vector +// Set: Use anything +// Use 0 for uc_handle to specify the global usercmd handle +native get_uc(uc_handle, UserCmd:member, any:...); +native set_uc(uc_handle, UserCmd:member, any:...); + +//NOTE that for the string offsets below, on AMD64, a byref (char **) offset is NOT the same as an int offset +//In fact it's QWORD aligned rather than DWORD aligned, so the offset will be exactly half. +//Gets a string from a private offset. If byref is false, the string is treated as static rather than dynamic. +//linux value is what to add to the offset for linux servers. +//mac value is what to add to the offset for os x servers. Default (cellmin) means that linux value will be used. +//this cannot use a default value due to older version using an awkward default value. +native get_pdata_string(entity, offset, dest[], maxlength, byref=1, linux, mac=cellmin); + +//Sets a string in a private offset. +//realloc = -1 - nonbyref copy (static +//realloc = 0 - copy byref, no realloc *(char **) +//realloc = 1 - reallocate new string with free+malloc +//realloc = 2 - reallocate new string with delete[]+new[] +//linux value is what to add to the offset for linux servers. +//mac value iswhat to add to the offset for os x servers. +//this cannot use a default value due to older version using an awkward default value. +native set_pdata_string(entity, offset, const source[], realloc=2, linux, mac=cellmin); + +// Copies the given infoBuffer pointer into out[] +// An infoBuffer pointer is returned by EngFunc_GetInfoKeyBuffer +native copy_infokey_buffer(infoBuffer, out[], maxlen); + + +/** + * Looks up the sequence for the entity. + * + * @param entity The entity id to lookup. + * @param name The sequence name to lookup, case insensitive. ("JUMP" would match "jump") + * @param framerate The framerate of the sequence, if found. + * @param loops Whether or not the sequence loops. + * @param groundspeed The groundspeed setting of the sequence. + * @return -1 on failed lookup, the sequence number on successful lookup. + */ +native lookup_sequence(entity, const name[], &Float:framerate = 0.0, &bool:loops = false, &Float:groundspeed = 0.0); + +/** + * Sets a bone controller with the specified value. + * + * @param entity The entity id to set the value on. + * @param controller Which controller to set (0 through 3). + * @param value The value to set it to. + * @return The percentage that the controller is extended (0.0 through 1.0) + */ +native Float:set_controller(entity, controller, Float:value); + +/** + * Retrieves an integer value from an entity's private data based off a class + * and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * @note This native is used to access the following (C++/engine) data types: + * integer, boolean, short, character, pointer, structure, class, + * stringint and function. Unsigned variants (if applicable) are supported + * and will be converted automatically. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Integer value + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native any:get_ent_data(entity, const class[], const member[], element = 0); + +/** + * Sets an integer value to an entity's private data based off a class + * and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * @note This native is used to access the following (C++/engine) data types: + * integer, boolean, short, character, pointer, stringint and function. + * Unsigned variants (if applicable) are supported and will be converted + * automatically. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value Value to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native set_ent_data(entity, const class[], const member[], any:value, element = 0); + +/** + * Retrieves a float value from an entity's private data based off a class + * and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Float value + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native Float:get_ent_data_float(entity, const class[], const member[], element = 0); + +/** + * Sets a float value to an entity's private data based off a class + * and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value Value to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native set_ent_data_float(entity, const class[], const member[], Float:value, element = 0); + +/** + * Retrieves a vector from an entity's private data based off a class and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value Vector buffer to store data in + * @param element Element to retrieve (starting from 0) if member is an array + * + * @noreturn + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native get_ent_data_vector(entity, const class[], const member[], Float:value[3], element = 0); + +/** + * Sets a vector to an entity's private data based off a class and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value Vector to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native set_ent_data_vector(entity, const class[], const member[], Float:value[3], element = 0); + +/** + * Retrieves an entity index from an entity's private data based off a class + * and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * @note This native is used to access the following (C++/engine) data types: + * classptr, entvars, edict and ehandle. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Entity index if found, -1 otherwise + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native get_ent_data_entity(entity, const class[], const member[], element = 0); + +/** + * Sets an entity index to an entity's private data based off a class + * and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * @note This native is used to access the following (C++/engine) data types: + * classptr, entvars, edict and ehandle. + * @note Pass -1 as value to act as C++ NULL. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value Entity index to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If an invalid entity or value is provided, either class or member + * is empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native set_ent_data_entity(entity, const class[], const member[], value, element = 0); + +/** + * Retrieves a string from an entity's private data based off a class and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * @note This native is used to access the following (C++/engine) data types: + * string, stringptr. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value Buffer to store data in + * @param maxlen Maximum size of the buffer + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Number of cells written to buffer + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native get_ent_data_string(entity, const class[], const member[], value[], maxlen, element = 0); + +/** + * Sets a string to an entity's private data based off a class and member name. + * + * @note Unlike the [get|set]_pdata_* natives that require compiling the class + * member offset into the plugin, this native instead retrieves the + * necessary offset from the AMXX gamedata files at runtime, based on the + * provided class and member name. + * @note This native is safer than [get|set]_pdata_* as it can perform stricter + * offset and typing checks. + * @note This native is used to access the following (C++/engine) data types: + * string, stringptr. + * + * @param entity Entity index + * @param class Class name + * @param member Member name + * @param value String to set + * @param element Element to set (starting from 0) if member is an array + * + * @return Number of cells written to buffer + * @error If an invalid entity is provided, either class or member is + * empty, no offset is found or an invalid offset is retrieved, + * or the data type does not match, an error will be thrown. + */ +native set_ent_data_string(entity, const class[], const member[], const value[], element = 0); + +/** + * Retrieves the size of array of n entity class member. + * + * @param class Class name + * @param member Member name + * + * @return Size of array (in elements), otherwise 1 if member is not an array + * @error If either class or member is empty, no offset is found or an invalid + * offset is retrieved, an error will be thrown. + */ +native get_ent_data_size(const class[], const member[]); + +/** + * Finds a offset based off an entity class and member name. + * + * @param class Class name + * @param member Member name + * @param type Optional variable to store member type in (FIELD_* constants) + * @param arraysize Optional variable to store array size in, if member is an array + * @param unsigned Optional variable to store whether member is unsigned (short and char types only) + * + * @return Class member offset + * @error If either class or member is empty, no offset is found or an invalid + * offset is retrieved, an error will be thrown. + */ +native find_ent_data_info(const class[], const member[], &FieldType:type = FIELD_NONE, &arraysize = 0, &bool:unsigned = false); + + +/** + * Retrieves an integer value from the gamerules object based off a class + * and member name. + * + * @note This native is used to access the following (C++/engine) data types: + * integer, boolean, short, character, pointer, structure, class, + * stringint and function. Unsigned variants (if applicable) are supported + * and will be converted automatically. + * + * @param class Class name + * @param member Member name + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Integer value + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native any:get_gamerules_int(const class[], const member[], element = 0); + +/** + * Sets an integer value to the gamerules objecta based off a class + * and member name. + * + * @note This native is used to access the following (C++/engine) data types: + * integer, boolean, short, character, pointer, stringint and function. + * Unsigned variants (if applicable) are supported and will be converted + * automatically. + * + * @param class Class name + * @param member Member name + * @param value Value to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native set_gamerules_int(const class[], const member[], any:value, element = 0); + +/** + * Retrieves a float value from the gamerules object based off a class + * and member name. + * + * @param class Class name + * @param member Member name + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Float value + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native Float:get_gamerules_float(const class[], const member[], element = 0); + +/** + * Sets a float value to the gamerules object based off a class + * and member name. + * + * @param class Class name + * @param member Member name + * @param value Value to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native set_gamerules_float(const class[], const member[], Float:value, element = 0); + +/** + * Retrieves a vector from the gamerules object based off a class and member name. + * + * @param class Class name + * @param member Member name + * @param value Vector buffer to store data in + * @param element Element to retrieve (starting from 0) if member is an array + * + * @noreturn + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native get_gamerules_vector(const class[], const member[], Float:value[3], element = 0); + +/** + * Sets a vector to the gamerules object based off a class and member name. + * + * @param class Class name + * @param member Member name + * @param value Vector to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native set_gamerules_vector(const class[], const member[], Float:value[3], element = 0); + +/** + * Retrieves an entity index from the gamerules object based off a class + * and member name. + * + * @note This native is used to access the following (C++/engine) data types: + * classptr, entvars, edict and ehandle. + * + * @param class Class name + * @param member Member name + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Entity index if found, -1 otherwise + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native get_gamerules_entity(const class[], const member[], element = 0); + +/** + * Sets an entity index to the gamerules object based off a class + * and member name. + * + * @note This native is used to access the following (C++/engine) data types: + * classptr, entvars, edict and ehandle. + * @note Pass -1 as value to act as C++ NULL. + * + * @param class Class name + * @param member Member name + * @param value Entity index to set + * @param element Element to set (starting from 0) if member is an array + * + * @noreturn + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native set_gamerules_entity(const class[], const member[], value, element = 0); + +/** + * Retrieves a string from the gamerules object based off a class and member name. + * + * @note This native is used to access the following (C++/engine) data types: + * string, stringptr. + * + * @param class Class name + * @param member Member name + * @param value Buffer to store data in + * @param maxlen Maximum size of the buffer + * @param element Element to retrieve (starting from 0) if member is an array + * + * @return Number of cells written to buffer + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native get_gamerules_string(const class[], const member[], value[], maxlen, element = 0); + +/** + * Sets a string to the gamerules object based off a class and member name. + * + * @note This native is used to access the following (C++/engine) data types: + * string, stringptr. + * + * @param class Class name + * @param member Member name + * @param value String to set + * @param element Element to set (starting from 0) if member is an array + * + * @return Number of cells written to buffer + * @error If member is empty, no offset is found or an invalid offset + * is retrieved, or the data type does not match, an error will + * be thrown. + */ +native set_gamerules_string(const class[], const member[], const value[], element = 0); + +/** + * Retrieves the size of array of a gamerules class member. + * + * @param class Class name + * @param member Member name + * + * @return Size of array (in elements), otherwise 1 if member is not an array + * @error If either class or member is empty, no offset is found or an invalid + * offset is retrieved, an error will be thrown. + */ +native get_gamerules_size(const class[], const member[]); + +/** + * Finds a gamerules offset based off a class and member name. + * + * @param class Class name + * @param member Member name + * @param type Optional variable to store member type in (FIELD_* constants) + * @param arraysize Optional variable to store array size in, if member is an array + * @param unsigned Optional variable to store whether member is unsigned (short and char types only) + * + * @return Class member offset + * @error If either class or member is empty, no offset is found or an invalid + * offset is retrieved, an error will be thrown. + */ +native find_gamerules_info(const class[], const member[], &FieldType:type = FIELD_NONE, &arraysize = 0, &bool:unsigned = false); + +/** + * Returns the data field base type based off a specific field type. + * + * @note From an AMXX plugin perspective, the (C++/engine) data types can be grouped + * in five base types: integer, float, vector, entity and string. This stock is + * essentially for convenience and debug purpose. + * + * @param type Class member type (FIELD_* constants) + * @param type_name Optional buffer to store base type name in + * @param maxlen Maximum size of the buffer + * + * @return Base field type (BASEFIELD_* constants) + */ +stock BaseFieldType:get_field_basetype(FieldType:type, type_name[] = "", maxlen = 0) +{ + static const baseFieldTypeNames[BaseFieldType][] = + { + "none", + "integer", + "float", + "vector", + "entity", + "string", + }; + + new BaseFieldType:baseType = BASEFIELD_NONE; + + switch (type) + { + case FIELD_INTEGER, FIELD_STRINGINT, FIELD_SHORT , FIELD_CHARACTER, + FIELD_CLASS , FIELD_STRUCTURE, FIELD_POINTER, FIELD_FUNCTION, + FIELD_BOOLEAN: + { + baseType = BASEFIELD_INTEGER; + } + case FIELD_FLOAT: + { + baseType = BASEFIELD_FLOAT; + } + case FIELD_VECTOR: + { + baseType = BASEFIELD_VECTOR; + } + case FIELD_CLASSPTR, FIELD_ENTVARS, FIELD_EDICT, FIELD_EHANDLE: + { + baseType = BASEFIELD_ENTITY; + } + case FIELD_STRINGPTR, FIELD_STRING: + { + baseType = BASEFIELD_STRING; + } + } + + if (maxlen > 0) + { + copy(type_name, maxlen, baseFieldTypeNames[baseType]); + } + + return baseType; +} + + +enum +{ + Model_DefaultSize = -2, + Model_CurrentSequence = -1, +}; + +/** + * Gets size of a model bounding box. + * + * @param entity The entity index to use. + * @param mins The local negative bounding box distance. + * @param maxs The local positive bounding box distance. + * @param sequence The animation sequence to retrieve. + * Model_DefaultSize retrieves ideal moevement hull size. + * Model_CurrentSequence retrieves hull size of the current sequence. + * Values >= 0 will specify which sequence to retrieve size from. + * + * @return 1 on success, 0 on faillure. + * + * @error Invalid entity. + * Invalid model pointer. + */ +native GetModelBoundingBox(entity, Float:mins[3], Float:maxs[3], sequence = Model_DefaultSize); diff --git a/amxmodx/scripting/include/fakemeta_const.inc b/amxmodx/scripting/include/fakemeta_const.inc new file mode 100644 index 0000000..eba34b6 --- /dev/null +++ b/amxmodx/scripting/include/fakemeta_const.inc @@ -0,0 +1,793 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Fakemeta Constants +// + +#if defined _fakemeta_const_included + #endinput +#endif +#define _fakemeta_const_included + +// For forward_return +#define FMV_STRING 1 +#define FMV_FLOAT 2 +#define FMV_CELL 3 + +#include + +/* The actual return value of the function, use these instead of PLUGIN_HANDLED etc when + * returning from registered forwards. + */ +#define FMRES_IGNORED 1 // Calls target function, returns normal value +#define FMRES_HANDLED 2 // Tells metamod you did something, still calls target function and returns normal value +#define FMRES_OVERRIDE 3 // Supposed to still call the target function but return your value instead + // however this does not work properly with metamod; use supercede instead. +#define FMRES_SUPERCEDE 4 // Block the target call, and use your return value (if applicable) + +// Use this with GetInfoKeyBuffer if you want the server's localinfo buffer +#define FM_NULLENT -1 + + +/* Used with engfunc() + */ +enum { + EngFunc_PrecacheModel, // int ) (char *s); + EngFunc_PrecacheSound, // int ) (char *s); + EngFunc_SetModel, // void ) (edict_t *e, const char *m); + EngFunc_ModelIndex, // int ) (const char *m); + EngFunc_ModelFrames, // int ) (int modelIndex); + EngFunc_SetSize, // void ) (edict_t *e, const float *rgflMin, const float *rgflMax); + EngFunc_ChangeLevel, // void ) (char* s1, char* s2); + EngFunc_VecToYaw, // float) (const float *rgflVector); + EngFunc_VecToAngles, // void ) (const float *rgflVectorIn, float *rgflVectorOut); + EngFunc_MoveToOrigin, // void ) (edict_t *ent, const float *pflGoal, float dist, int iMoveType); + EngFunc_ChangeYaw, // void ) (edict_t* ent); + EngFunc_ChangePitch, // void ) (edict_t* ent); + EngFunc_FindEntityByString, // edict) (edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); + EngFunc_GetEntityIllum, // int ) (edict_t* pEnt); + EngFunc_FindEntityInSphere, // edict) (edict_t *pEdictStartSearchAfter, const float *org, float rad); + EngFunc_FindClientInPVS, // edict) (edict_t *pEdict); + EngFunc_EntitiesInPVS, // edict) (edict_t *pplayer); + EngFunc_MakeVectors, // void ) (const float *rgflVector); + EngFunc_AngleVectors, // void ) (const float *rgflVector, float *forward, float *right, float *up); + EngFunc_CreateEntity, // edict) (void); + EngFunc_RemoveEntity, // void ) (edict_t *e); + EngFunc_CreateNamedEntity, // edict) (int className); + EngFunc_MakeStatic, // void ) (edict_t *ent); + EngFunc_EntIsOnFloor, // int ) (edict_t *e); + EngFunc_DropToFloor, // int ) (edict_t *e); + EngFunc_WalkMove, // int ) (edict_t *ent, float yaw, float dist, int iMode); + EngFunc_SetOrigin, // void ) (edict_t *e, const float *rgflOrigin); + EngFunc_EmitSound, // void ) (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch); + EngFunc_EmitAmbientSound, // void ) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); + + //With 1.71 you can pass an optional TraceLine ptr for trace natives + // it can be 0, for meaning "global tr handle" (for get/set_tr2), or + // it can be any other TR handle (such as one from a TR hook) + EngFunc_TraceLine, // void ) (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); + EngFunc_TraceToss, // void ) (edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); + EngFunc_TraceMonsterHull, // int ) (edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); + EngFunc_TraceHull, // void ) (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); + EngFunc_TraceModel, // void ) (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); + EngFunc_TraceTexture, // const char *) (edict_t *pTextureEntity, const float *v1, const float *v2 ); + EngFunc_TraceSphere, // void ) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); + + EngFunc_GetAimVector, // void ) (edict_t *ent, float speed, float *rgflReturn); + EngFunc_ParticleEffect, // void ) (const float *org, const float *dir, float color, float count); + EngFunc_LightStyle, // void ) (int style, char *val); + EngFunc_DecalIndex, // int ) (const char *name); + EngFunc_PointContents, // int ) (const float *rgflVector); + EngFunc_FreeEntPrivateData, // void ) (edict_t *pEdict); + EngFunc_SzFromIndex, // const char *) (int iString); + EngFunc_AllocString, // int ) (const char *szValue); + EngFunc_RegUserMsg, // int ) (const char *pszName, int iSize); + EngFunc_AnimationAutomove, // void ) (const edict_t *pEdict, float flTime); + EngFunc_GetBonePosition, // void ) (const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles); + EngFunc_GetAttachment, // void ) (const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles); + EngFunc_SetView, // void ) (const edict_t *pClient, const edict_t *pViewent); + EngFunc_Time, // float) ( void ); + EngFunc_CrosshairAngle, // void ) (const edict_t *pClient, float pitch, float yaw); + EngFunc_FadeClientVolume, // void ) (const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); + EngFunc_SetClientMaxspeed, // void ) (const edict_t *pEdict, float fNewMaxspeed); + EngFunc_CreateFakeClient, // edict) (const char *netname); // returns NULL if fake client can't be created + EngFunc_RunPlayerMove, // void ) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec); + EngFunc_NumberOfEntities, // int ) ( void ); + EngFunc_StaticDecal, // void ) (const float *origin, int decalIndex, int entityIndex, int modelIndex); + EngFunc_PrecacheGeneric, // int ) (char* s); + EngFunc_BuildSoundMsg, // void ) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); + EngFunc_GetPhysicsKeyValue, // const char *) (const edict_t *pClient, const char *key); + EngFunc_SetPhysicsKeyValue, // void ) (const edict_t *pClient, const char *key, const char *value); + EngFunc_GetPhysicsInfoString, // const char *) (const edict_t *pClient); + EngFunc_PrecacheEvent, // unsigned short) (int type, const char*psz); + EngFunc_PlaybackEvent, // void ) (int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); + EngFunc_CheckVisibility, // int ) (const edict_t *entity, unsigned char *pset); + EngFunc_GetCurrentPlayer, // int ) ( void ); + EngFunc_CanSkipPlayer, // int ) (const edict_t *player); + EngFunc_SetGroupMask, // void ) (int mask, int op); + EngFunc_GetClientListening, // bool ) (int iReceiver, int iSender) + EngFunc_SetClientListening, // bool ) (int iReceiver, int iSender, bool Listen) + EngFunc_MessageBegin, // void ) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) + EngFunc_WriteCoord, // void ) (float flValue) + EngFunc_WriteAngle, // void ) (float flValue) + EngFunc_InfoKeyValue, // char*) (char *infobuffer, char *key); + EngFunc_SetKeyValue, // void ) (char *infobuffer, char *key, char *value); + EngFunc_SetClientKeyValue, // void ) (int clientIndex, char *infobuffer, char *key, char *value); + EngFunc_CreateInstBaseline, // int ) (int classname, struct entity_state_s *baseline); + + // Returns pointer to info buffer that can be used with the infobuffer param of InfoKeyValue, SetKeyValue, and SetClientKeyValue + EngFunc_GetInfoKeyBuffer, // char*) (edict_t *e); + EngFunc_AlertMessage, // void ) (ALERT_TYPE atype, char *szFmt, ...); + EngFunc_ClientPrintf, // void ) (edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg); + EngFunc_ServerPrint // void ) (const char *szMsg); +}; + +/* Used with dllfunc() + */ +enum +{ + DLLFunc_GameInit, // void ) ( void ); + DLLFunc_Spawn, // int ) (edict_t *pent); + DLLFunc_Think, // void ) (edict_t *pent); + DLLFunc_Use, // void ) (edict_t *pentUsed, edict_t *pentOther); + DLLFunc_Touch, // void ) (edict_t *pentTouched, edict_t *pentOther); + DLLFunc_Blocked, // void ) (edict_t *pentBlocked, edict_t *pentOther); + + //You can pass in 0 for glb kvd handle or a kvd handle here + DLLFunc_KeyValue, // void ) (edict_t *pentKeyvalue, KeyValueData *pkvd); + DLLFunc_SetAbsBox, // void ) (edict_t *pent); + DLLFunc_ClientConnect, // bool ) (edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]); + + DLLFunc_ClientDisconnect, // void ) (edict_t *pEntity); + DLLFunc_ClientKill, // void ) (edict_t *pEntity); + DLLFunc_ClientPutInServer, // void ) (edict_t *pEntity); + DLLFunc_ClientCommand, // void ) (edict_t *pEntity); + + DLLFunc_ServerDeactivate, // void ) ( void ); + + DLLFunc_PlayerPreThink, // void ) (edict_t *pEntity); + DLLFunc_PlayerPostThink, // void ) (edict_t *pEntity); + + DLLFunc_StartFrame, // void ) ( void ); + DLLFunc_ParmsNewLevel, // void ) ( void ); + DLLFunc_ParmsChangeLevel, // void ) ( void ); + + // Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life + // This also gets called when the server is queried for information (for example, by a server browser tool) + DLLFunc_GetGameDescription, // const char *) ( void ); + + // Spectator funcs + DLLFunc_SpectatorConnect, // void ) (edict_t *pEntity); + DLLFunc_SpectatorDisconnect, // void ) (edict_t *pEntity); + DLLFunc_SpectatorThink, // void ) (edict_t *pEntity); + + // Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. + DLLFunc_Sys_Error, // void ) (const char *error_string); + + DLLFunc_PM_FindTextureType, // char ) (char *name); + DLLFunc_RegisterEncoders, // void ) ( void ); + + // Enumerates player hulls. Returns 0 if the hull number doesn't exist, 1 otherwise + DLLFunc_GetHullBounds, // int ) (int hullnumber, float *mins, float *maxs); + + // Create baselines for certain "unplaced" items. + DLLFunc_CreateInstBaselines, // void ) ( void ); + DLLFunc_pfnAllowLagCompensation, // int ) ( void ); + // I know this does not fit with DLLFUNC(), but I don't want another native just for it. + MetaFunc_CallGameEntity, // bool ) (plid_t plid, const char *entStr,entvars_t *pev); + DLLFunc_ClientUserInfoChanged, // void ) (edict *pEntity, char *infobuffer); + // You can pass in 0 for global cd handle or another cd handle here + DLLFunc_UpdateClientData, // void ) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd); + // You can pass in 0 for global entity state handle or another entity state handle here + DLLFunc_AddToFullPack, // int ) (struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet); + // You can pass in 0 for global usercmd handle or another usercmd handle here + DLLFunc_CmdStart, // void ) (const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed); + DLLFunc_CmdEnd, // void ) (const edict_t *player); + DLLFunc_CreateBaseline // void ) (int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs); +}; + +enum { + pev_string_start = 0, + pev_classname, + pev_globalname, + pev_model, + pev_target, + pev_targetname, + pev_netname, + pev_message, + pev_noise, + pev_noise1, + pev_noise2, + pev_noise3, + pev_string_end, + pev_edict_start, + pev_chain, + pev_dmg_inflictor, + pev_enemy, + pev_aiment, + pev_owner, + pev_groundentity, + pev_euser1, + pev_euser2, + pev_euser3, + pev_euser4, + pev_edict_end, + pev_float_start, + pev_impacttime, + pev_starttime, + pev_idealpitch, + pev_ideal_yaw, + pev_pitch_speed, + pev_yaw_speed, + pev_ltime, + pev_nextthink, + pev_gravity, + pev_friction, + pev_frame, + pev_animtime, + pev_framerate, + pev_scale, + pev_renderamt, + pev_health, + pev_frags, + pev_takedamage, + pev_max_health, + pev_teleport_time, + pev_armortype, + pev_armorvalue, + pev_dmg_take, + pev_dmg_save, + pev_dmg, + pev_dmgtime, + pev_speed, + pev_air_finished, + pev_pain_finished, + pev_radsuit_finished, + pev_maxspeed, + pev_fov, + pev_flFallVelocity, + pev_fuser1, + pev_fuser2, + pev_fuser3, + pev_fuser4, + pev_float_end, + pev_int_start, + pev_fixangle, + pev_modelindex, + pev_viewmodel, + pev_weaponmodel, + pev_movetype, + pev_solid, + pev_skin, + pev_body, + pev_effects, + pev_light_level, + pev_sequence, + pev_gaitsequence, + pev_rendermode, + pev_renderfx, + pev_weapons, + pev_deadflag, + pev_button, + pev_impulse, + pev_spawnflags, + pev_flags, + pev_colormap, + pev_team, + pev_waterlevel, + pev_watertype, + pev_playerclass, + pev_weaponanim, + pev_pushmsec, + pev_bInDuck, + pev_flTimeStepSound, + pev_flSwimTime, + pev_flDuckTime, + pev_iStepLeft, + pev_gamestate, + pev_oldbuttons, + pev_groupinfo, + pev_iuser1, + pev_iuser2, + pev_iuser3, + pev_iuser4, + pev_int_end, + pev_byte_start, + pev_controller_0, + pev_controller_1, + pev_controller_2, + pev_controller_3, + pev_blending_0, + pev_blending_1, + pev_byte_end, + pev_bytearray_start, + pev_controller, + pev_blending, + pev_bytearray_end, + pev_vecarray_start, + pev_origin, + pev_oldorigin, + pev_velocity, + pev_basevelocity, + pev_clbasevelocity, + pev_movedir, + pev_angles, + pev_avelocity, + pev_v_angle, + pev_endpos, + pev_startpos, + pev_absmin, + pev_absmax, + pev_mins, + pev_maxs, + pev_size, + pev_rendercolor, + pev_view_ofs, + pev_vuser1, + pev_vuser2, + pev_vuser3, + pev_vuser4, + pev_punchangle, + pev_vecarray_end, + pev_string2_begin, /* anything after here are string corrections */ + pev_weaponmodel2, + pev_viewmodel2, + pev_string2_end, + pev_edict2_start, /* edict corrections */ + pev_pContainingEntity, + pev_absolute_end +}; + +/* Used with global_get() + */ +enum +{ + glb_start_int = 0, + glb_trace_hitgroup, + glb_trace_flags, + glb_msg_entity, + glb_cdAudioTrack, + glb_maxClients, + glb_maxEntities, + glb_end_int, + glb_start_float, + glb_time, + glb_frametime, + glb_force_retouch, + glb_deathmatch, + glb_coop, + glb_teamplay, + glb_serverflags, + glb_found_secrets, + glb_trace_allsolid, + glb_trace_startsolid, + glb_trace_fraction, + glb_trace_plane_dist, + glb_trace_inopen, + glb_trace_inwater, + glb_end_float, + glb_start_edict, + glb_trace_ent, + glb_end_edict, + glb_start_vector, + glb_v_forward, + glb_v_up, + glb_v_right, + glb_trace_endpos, + glb_trace_plane_normal, + glb_vecLandmarkOffset, + glb_end_vector, + glb_start_string, + glb_mapname, + glb_startspot, + glb_end_string, + glb_start_pchar, + glb_pStringBase, + glb_end_pchar +}; + +/* Used with register_forward() + */ +enum { + FM_PrecacheModel = 1, + FM_PrecacheSound, + FM_SetModel, + FM_ModelIndex, + FM_ModelFrames, + FM_SetSize, + FM_ChangeLevel, + FM_VecToYaw, + FM_VecToAngles, + FM_MoveToOrigin, + FM_ChangeYaw, + FM_ChangePitch, + FM_FindEntityByString, + FM_GetEntityIllum, + FM_FindEntityInSphere, + FM_FindClientInPVS, + FM_EntitiesInPVS, + FM_MakeVectors, + FM_AngleVectors, + FM_CreateEntity, + FM_RemoveEntity, + FM_CreateNamedEntity, + FM_MakeStatic, + FM_EntIsOnFloor, + FM_DropToFloor, + FM_WalkMove, + FM_SetOrigin, + FM_EmitSound, + FM_EmitAmbientSound, + FM_TraceLine, + FM_TraceToss, + FM_TraceMonsterHull, + FM_TraceHull, + FM_TraceModel, + FM_TraceTexture, + FM_TraceSphere, + FM_GetAimVector, + FM_ParticleEffect, + FM_LightStyle, + FM_DecalIndex, + FM_PointContents, + FM_MessageBegin, + FM_MessageEnd, + FM_WriteByte, + FM_WriteChar, + FM_WriteShort, + FM_WriteLong, + FM_WriteAngle, + FM_WriteCoord, + FM_WriteString, + FM_WriteEntity, + FM_CVarGetFloat, + FM_CVarGetString, + FM_CVarSetFloat, + FM_CVarSetString, + FM_FreeEntPrivateData, + FM_SzFromIndex, + FM_AllocString, + FM_RegUserMsg, + FM_AnimationAutomove, + FM_GetBonePosition, + FM_GetAttachment, + FM_SetView, + FM_Time, + FM_CrosshairAngle, + FM_FadeClientVolume, + FM_SetClientMaxspeed, + FM_CreateFakeClient, + FM_RunPlayerMove, + FM_NumberOfEntities, + FM_StaticDecal, + FM_PrecacheGeneric, + FM_BuildSoundMsg, + FM_GetPhysicsKeyValue, + FM_SetPhysicsKeyValue, + FM_GetPhysicsInfoString, + FM_PrecacheEvent, + FM_PlaybackEvent, + FM_CheckVisibility, + FM_GetCurrentPlayer, + FM_CanSkipPlayer, + FM_SetGroupMask, + FM_Voice_GetClientListening, + FM_Voice_SetClientListening, + FM_InfoKeyValue, + FM_SetKeyValue, + FM_SetClientKeyValue, + FM_GetPlayerAuthId, + FM_GetPlayerWONId, + FM_IsMapValid, + + FM_Spawn, + FM_Think, + FM_Use, + FM_Touch, + FM_Blocked, + FM_KeyValue, + FM_SetAbsBox, + FM_ClientConnect, + + FM_ClientDisconnect, + FM_ClientKill, + FM_ClientPutInServer, + FM_ClientCommand, + + FM_ServerDeactivate, + + FM_PlayerPreThink, + FM_PlayerPostThink, + + FM_StartFrame, + FM_ParmsNewLevel, + FM_ParmsChangeLevel, + + // Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life + // This also gets called when the server is queried for information (for example, by a server browser tool) + FM_GetGameDescription, + + // Spectator funcs + FM_SpectatorConnect, + FM_SpectatorDisconnect, + FM_SpectatorThink, + + // Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. + FM_Sys_Error, + + FM_PM_FindTextureType, + FM_RegisterEncoders, + + // Create baselines for certain "unplaced" items. + FM_CreateInstBaselines, + + FM_AllowLagCompensation, + FM_AlertMessage, + + // NEW_DLL_FUNCTIONS: + FM_OnFreeEntPrivateData, + FM_GameShutdown, + FM_ShouldCollide, + + // LATE ADDITIONS (v1.71) + FM_ClientUserInfoChanged, + + // LATE ADDITIONS (v1.75) + FM_UpdateClientData, + FM_AddToFullPack, + FM_CmdStart, + FM_CmdEnd, + FM_CreateInstBaseline, + FM_CreateBaseline, + FM_GetInfoKeyBuffer, + FM_ClientPrintf, + + // LATE ADDITIONS (v1.80) + FM_ServerPrint +}; + +enum TraceResult +{ + TR_AllSolid, // int + TR_StartSolid, // int + TR_InOpen, // int + TR_InWater, // int + TR_flFraction, // float + TR_vecEndPos, // float array[3] + TR_flPlaneDist, // float + TR_vecPlaneNormal, // float array[3] + TR_pHit, // int (edict_t*) + TR_iHitgroup, // int +}; + +enum KeyValueData +{ + KV_ClassName, // string + KV_KeyName, // string + KV_Value, // string + KV_fHandled // int +}; + +enum ClientData +{ + CD_Origin, // float array[3] + CD_Velocity, // float array[3] + CD_ViewModel, // int + CD_PunchAngle, // float array[3] + CD_Flags, // int + CD_WaterLevel, // int + CD_WaterType, // int + CD_ViewOfs, // float array[3] + CD_Health, // float + CD_bInDuck, // int + CD_Weapons, // int + CD_flTimeStepSound, // int + CD_flDuckTime, // int + CD_flSwimTime, // int + CD_WaterJumpTime, // int + CD_MaxSpeed, // float + CD_FOV, // float + CD_WeaponAnim, // int + CD_ID, // int + CD_AmmoShells, // int + CD_AmmoNails, // int + CD_AmmoCells, // int + CD_AmmoRockets, // int + CD_flNextAttack, // float + CD_tfState, // int + CD_PushMsec, // int + CD_DeadFlag, // int + CD_PhysInfo, // string[256] + CD_iUser1, // int + CD_iUser2, // int + CD_iUser3, // int + CD_iUser4, // int + CD_fUser1, // float + CD_fUser2, // float + CD_fUser3, // float + CD_fUser4, // float + CD_vUser1, // float array[3] + CD_vUser2, // float array[3] + CD_vUser3, // float array[3] + CD_vUser4 // float array[3] +}; + +enum EntityState +{ + // Fields which are filled in by routines outside of delta compression + ES_EntityType, // int + // Index into cl_entities array for this entity + ES_Number, // int + ES_MsgTime, // float + + // Message number last time the player/entity state was updated + ES_MessageNum, // int + + // Fields which can be transitted and reconstructed over the network stream + ES_Origin, // float array[3] + ES_Angles, // float array[3] + + ES_ModelIndex, // int + ES_Sequence, // int + ES_Frame, // float + ES_ColorMap, // int + ES_Skin, // short + ES_Solid, // short + ES_Effects, // int + ES_Scale, // float + ES_eFlags, // byte + + // Render information + ES_RenderMode, // int + ES_RenderAmt, // int + ES_RenderColor, // byte array[3], RGB value + ES_RenderFx, // int + + ES_MoveType, // int + ES_AnimTime, // float + ES_FrameRate, // float + ES_Body, // int + ES_Controller, // byte array[4] + ES_Blending, // byte array[4] + ES_Velocity, // float array[3] + + // Send bbox down to client for use during prediction + ES_Mins, // float array[3] + ES_Maxs, // float array[3] + + ES_AimEnt, // int + // If owned by a player, the index of that player (for projectiles) + ES_Owner, // int + + // Friction, for prediction + ES_Friction, // float + // Gravity multiplier + ES_Gravity, // float + + // PLAYER SPECIFIC + ES_Team, // int + ES_PlayerClass, // int + ES_Health, // int + ES_Spectator, // bool + ES_WeaponModel, // int + ES_GaitSequence, // int + // If standing on conveyor, e.g. + ES_BaseVelocity, // float array[3] + // Use the crouched hull, or the regular player hull + ES_UseHull, // int + // Latched buttons last time state updated + ES_OldButtons, // int + // -1 = in air, else pmove entity number + ES_OnGround, // int + ES_iStepLeft, // int + // How fast we are falling + ES_flFallVelocity, // float + + ES_FOV, // float + ES_WeaponAnim, // int + + // Parametric movement overrides + ES_StartPos, // float array[3] + ES_EndPos, // float array[3] + ES_ImpactTime, // float + ES_StartTime, // float + + // For mods + ES_iUser1, // int + ES_iUser2, // int + ES_iUser3, // int + ES_iUser4, // int + ES_fUser1, // float + ES_fUser2, // float + ES_fUser3, // float + ES_fUser4, // float + ES_vUser1, // float array[3] + ES_vUser2, // float array[3] + ES_vUser3, // float array[3] + ES_vUser4 // float array[3] +}; + +enum UserCmd +{ + // Interpolation time on client + UC_LerpMsec, // short + // Duration in ms of command + UC_Msec, // byte + // Command view angles + UC_ViewAngles, // float array[3] + + // Intended velocities + // Forward velocity + UC_ForwardMove, // float + // Sideways velocity + UC_SideMove, // float + // Upward velocity + UC_UpMove, // float + // Light level at spot where we are standing + UC_LightLevel, // byte + // Attack buttons + UC_Buttons, // unsigned short + // Impulse command issued + UC_Impulse, // byte + // Current weapon id + UC_WeaponSelect, // byte + + // Experimental player impact stuff + UC_ImpactIndex, // int + UC_ImpactPosition // float array[3] +}; + +enum AlertType +{ + at_notice = 0, + at_console, // same as at_notice, but forces a ConPrintf, not a message box + at_aiconsole, // same as at_console, but only shown if developer level is 2! + at_warning, + at_error, + at_logged // Server print to console (only in multiplayer games) +}; + +/** + * Data field types for use with find_ent_data_info(). + */ +enum FieldType +{ + FIELD_NONE, + FIELD_FLOAT, // Floating point value + FIELD_STRINGINT, // String ID (return from ALLOC_STRING) + FIELD_STRINGPTR, // String, pointer-to-char + FIELD_STRING, // String, fixed size + FIELD_CLASSPTR, // Classes pointer derived of CBaseEntity + FIELD_CLASS, // Arbitrary classes, direct + FIELD_STRUCTURE, // Arbitrary structures, direct + FIELD_EHANDLE, // Entity handle + FIELD_ENTVARS, // entvars_t* + FIELD_EDICT, // edict_t* + FIELD_VECTOR, // Vector + FIELD_POINTER, // Arbitrary data pointer + FIELD_INTEGER, // Integer or enum + FIELD_FUNCTION, // Class function pointer (Think, Use, etc) + FIELD_BOOLEAN, // Boolean + FIELD_SHORT, // 2 bytes integer + FIELD_CHARACTER, // 1 byte +}; + +/** + * Base data field types for use with get_ent_data_basetype(). + */ +enum BaseFieldType +{ + BASEFIELD_NONE, + BASEFIELD_INTEGER, + BASEFIELD_FLOAT, + BASEFIELD_VECTOR, + BASEFIELD_ENTITY, + BASEFIELD_STRING, +}; diff --git a/amxmodx/scripting/include/fakemeta_stocks.inc b/amxmodx/scripting/include/fakemeta_stocks.inc new file mode 100644 index 0000000..088f951 --- /dev/null +++ b/amxmodx/scripting/include/fakemeta_stocks.inc @@ -0,0 +1,395 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Fakemeta Stocks +// + +#if !defined _fakemeta_included + #include +#endif + +#if defined _fakemeta_stocks_included + #endinput +#endif +#define _fakemeta_stocks_included + +// EngFuncs +stock EF_PrecacheModel(const string[]) { + return engfunc(EngFunc_PrecacheModel, string); +} + +stock EF_PrecacheSound(const string[]) { + return engfunc(EngFunc_PrecacheSound, string); +} +stock EF_SetModel(const ID, const STRING[]) { + return engfunc(EngFunc_SetModel, ID, STRING); +} +stock EF_ModelIndex(const STRING[]) { + return engfunc(EngFunc_ModelIndex, STRING); +} +stock EF_ModelFrames(modelIndex) { + return engfunc(EngFunc_ModelFrames, modelIndex); +} + +stock EF_SetSize(const ENTITY, const Float:MIN[3], const Float:MAX[3]) { + return engfunc(EngFunc_SetSize, ENTITY, MIN, MAX); +} +stock EF_ChangeLevel(const S1[], const S2[]) { + return engfunc(EngFunc_ChangeLevel, S1, S2); +} +stock EF_VecToYaw(const Float:VECTOR[3], &Float:returnValue) { + return engfunc(EngFunc_VecToYaw, VECTOR, returnValue); +} +stock EF_VecToAngles(const Float:VECTORIN[3], const Float:VECTOROUT[3]) { + return engfunc(EngFunc_VecToAngles, VECTORIN, VECTOROUT); +} +stock EF_MoveToOrigin(const ENTITY, const Float:GOAL[3], const Float:DISTANCE, const MOVETYPE) { + return engfunc(EngFunc_MoveToOrigin, ENTITY, GOAL, DISTANCE, MOVETYPE); +} + +stock EF_ChangeYaw(const ENTITY) { + return engfunc(EngFunc_ChangeYaw, ENTITY); +} +stock EF_ChangePitch(const ENTITY) { + return engfunc(EngFunc_ChangePitch, ENTITY); +} +stock EF_FindEntityByString(const STARTSEARCHAFTER, const FIELD[], const VALUE[]) { + return engfunc(EngFunc_FindEntityByString, STARTSEARCHAFTER, FIELD, VALUE); +} +stock EF_GetEntityIllum(const ENTITY) { + return engfunc(EngFunc_GetEntityIllum, ENTITY); +} +stock EF_FindEntityInSphere(const STARTSEARCHAFTER, const Float:ORIGIN[3], Float:radius) { + return engfunc(EngFunc_FindEntityInSphere, STARTSEARCHAFTER, ORIGIN, radius); +} + +stock EF_FindClientInPVS(const CLIENT) { + return engfunc(EngFunc_FindClientInPVS, CLIENT); +} +stock EF_EntitiesInPVS(const CLIENT) { + return engfunc(EngFunc_EntitiesInPVS, CLIENT); +} +stock EF_MakeVectors(const Float:VECTOR[3]) { + return engfunc(EngFunc_MakeVectors, VECTOR); +} +stock EF_AngleVectors(const Float:VECTOR[3], Float:forward_[3], Float:right[3], Float:up[3]) { + return engfunc(EngFunc_AngleVectors, VECTOR, forward_, right, up); +} +stock EF_CreateEntity() { + return engfunc(EngFunc_CreateEntity); +} + +stock EF_RemoveEntity(const ENTITY) { + return engfunc(EngFunc_RemoveEntity, ENTITY); +} +stock EF_CreateNamedEntity(const CLASSNAME) { + return engfunc(EngFunc_CreateNamedEntity, CLASSNAME); +} +stock EF_MakeStatic(const ENTITY) { + return engfunc(EngFunc_MakeStatic, ENTITY); +} +stock EF_EntIsOnFloor(const ENTITY) { + return engfunc(EngFunc_EntIsOnFloor, ENTITY); +} +stock EF_DropToFloor(const ENTITY) { + return engfunc(EngFunc_DropToFloor, ENTITY); +} + +stock EF_WalkMove(const ENTITY, Float:yaw, Float:distance, iMode) { + return engfunc(EngFunc_WalkMove, ENTITY, yaw, distance, iMode); +} +stock EF_SetOrigin(const ENTITY, const Float:ORIGIN[3]) { + return engfunc(EngFunc_SetOrigin, ENTITY, ORIGIN); +} +stock EF_EmitSound(const ENTITY, channel, const SAMPLE[], Float:volume, Float:attenuation, fFlags, pitch) { + return engfunc(EngFunc_EmitSound, ENTITY, channel, SAMPLE, volume, attenuation, fFlags, pitch); +} +stock EF_EmitAmbientSound(const ENTITY, Float:pos[3], const SAMPLE[], Float:volume, Float:attenuation, fFlags, pitch) { + return engfunc(EngFunc_EmitAmbientSound, ENTITY, pos, SAMPLE, volume, attenuation, fFlags, pitch); +} +stock EF_TraceLine(const Float:V1[3], const Float:V2[3], fNoMonsters, const ENT_TO_SKIP) { + return engfunc(EngFunc_TraceLine, V1, V2, fNoMonsters, ENT_TO_SKIP); +} + +stock EF_TraceToss(const ENTITY, const ENTITY_TO_IGNORE) { + return engfunc(EngFunc_TraceToss, ENTITY, ENTITY_TO_IGNORE); +} +stock EF_TraceMonsterHull(const ENTITY, const Float:V1[3], const Float:V2[3], fNoMonsters, const ENTITY_TO_SKIP) { + return engfunc(EngFunc_TraceMonsterHull, ENTITY, V1, V2, fNoMonsters, ENTITY_TO_SKIP); +} +stock EF_TraceHull(const Float:V1[3], const Float:V2[3], fNoMonsters, hullNumber, const ENTITY_TO_SKIP) { + return engfunc(EngFunc_TraceHull, V1, V2, fNoMonsters, hullNumber, ENTITY_TO_SKIP); +} +stock EF_TraceModel(const Float:V1[3], const Float:V2[3], hullNumber, const ENTITY) { + return engfunc(EngFunc_TraceModel, V1, V2, hullNumber, ENTITY); +} +stock EF_TraceTexture(const TEXTURE_ENTITY, const Float:V1[3], const Float:V2[3]) { + return engfunc(EngFunc_TraceTexture, TEXTURE_ENTITY, V1, V2); +} + +stock EF_TraceSphere(const Float:V1[3], const Float:V2[3], fNoMonsters, Float:radius, const ENTITY_TO_SKIP) { + return engfunc(EngFunc_TraceSphere, V1, V2, fNoMonsters, radius, ENTITY_TO_SKIP); +} +stock EF_GetAimVector(const ENTITY, Float:speed, Float:returnVector[3]) { + return engfunc(EngFunc_GetAimVector, ENTITY, speed, returnVector); +} +stock EF_ParticleEffect(const Float:ORIGIN[3], const Float:DIRECTION[3], Float:color, Float:count) { + return engfunc(EngFunc_ParticleEffect, ORIGIN, DIRECTION, color, count); +} +stock EF_LightStyle(style, val[]) { + return engfunc(EngFunc_LightStyle, style, val); +} +stock EF_DecalIndex(const NAME[]) { + return engfunc(EngFunc_DecalIndex, NAME); +} + +stock EF_PointContents(const Float:VECTOR[3]) { + return engfunc(EngFunc_PointContents, VECTOR); +} +stock EF_FreeEntPrivateData(const ENTITY) { + return engfunc(EngFunc_FreeEntPrivateData, ENTITY); +} +stock EF_SzFromIndex(iString) { + return engfunc(EngFunc_SzFromIndex, iString); +} +stock EF_AllocString(const STRING[]) { + return engfunc(EngFunc_AllocString, STRING); +} +stock EF_RegUserMsg(const NAME[], iSize) { + return engfunc(EngFunc_RegUserMsg, NAME, iSize); +} + +stock EF_AnimationAutomove(const ENTITY, Float:flTime) { + return engfunc(EngFunc_AnimationAutomove, ENTITY, flTime); +} +stock EF_GetBonePosition(const ENTITY, iBone, Float:origin[3], Float:angles[3]) { + return engfunc(EngFunc_GetBonePosition, ENTITY, iBone, origin, angles); +} +stock EF_GetAttachment(const ENTITY, iAttachment, Float:origin[3], Float:angles[3]) { + return engfunc(EngFunc_GetAttachment, ENTITY, iAttachment, origin, angles); +} +stock EF_SetView(const CLIENT, const VIEW_ENTITY) { + return engfunc(EngFunc_SetView, CLIENT, VIEW_ENTITY); +} +stock EF_Time(&Float:returnValue) { + return engfunc(EngFunc_Time, returnValue); +} + +stock EF_CrosshairAngle(const CLIENT, Float:pitch, Float:yaw) { + return engfunc(EngFunc_CrosshairAngle, CLIENT, pitch, yaw); +} +stock EF_FadeClientVolume(const ENTITY, fadePercent, fadeOutSeconds, holdTime, fadeInSeconds) { + return engfunc(EngFunc_FadeClientVolume, ENTITY, fadePercent, fadeOutSeconds, holdTime, fadeInSeconds); +} +stock EF_SetClientMaxspeed(const ENTITY, Float:newMaxspeed) { + return engfunc(EngFunc_SetClientMaxspeed, ENTITY, newMaxspeed); +} +stock EF_CreateFakeClient(const NETNAME[]) { + return engfunc(EngFunc_CreateFakeClient, NETNAME); +} +stock EF_RunPlayerMove(const FAKECLIENT, const Float:VIEWANGLES[3], Float:forwardmove, Float:sidemove, Float:upmove, buttons, impulse, msec) { + return engfunc(EngFunc_RunPlayerMove, FAKECLIENT, VIEWANGLES, forwardmove, sidemove, upmove, buttons, impulse, msec); +} + +stock EF_NumberOfEntities() { + return engfunc(EngFunc_NumberOfEntities); +} +stock EF_StaticDecal(const Float:ORIGIN[3], decalIndex, entityIndex, modelIndex) + return engfunc(EngFunc_StaticDecal, ORIGIN, decalIndex, entityIndex, modelIndex); +stock EF_PrecacheGeneric(const STRING[]) { + return engfunc(EngFunc_PrecacheGeneric, STRING); +} +stock EF_BuildSoundMSG(const ENTITY, channel, const SAMPLE[], Float:volume, Float:attenuation, fFlags, pitch, msg_dest, msg_type, const Float:ORIGIN[3], const ED) { + return engfunc(EngFunc_BuildSoundMsg, ENTITY, channel, SAMPLE, volume, attenuation, fFlags, pitch, msg_dest, msg_type, ORIGIN, ED); +} +stock EF_GetPhysicsKeyValue(const CLIENT, const KEY[]) { + return engfunc(EngFunc_GetPhysicsKeyValue, CLIENT, KEY); +} + +stock EF_SetPhysicsKeyValue(const CLIENT, const KEY[], const VALUE[]) { + return engfunc(EngFunc_SetPhysicsKeyValue, CLIENT, KEY, VALUE); +} +stock EF_GetPhysicsInfoString(const CLIENT, returnString[], maxLength) { + return engfunc(EngFunc_GetPhysicsInfoString, CLIENT, returnString, maxLength); +} +stock EF_PrecacheEvent(type, const STRING[]) { + return engfunc(EngFunc_PrecacheEvent, type, STRING); +} +stock EF_PlaybackEvent(flags, const INVOKER, eventindex, Float:delay, Float:origin[3], Float:angles[3], Float:fparam1, Float:fparam2, iparam1, iparam2, bparam1, bparam2) { + return engfunc(EngFunc_PlaybackEvent, flags, INVOKER, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2); +} +stock EF_CheckVisibility(const ENTITY, set) { + return engfunc(EngFunc_CheckVisibility, ENTITY, set); +} + +stock EF_GetCurrentPlayer() { + return engfunc(EngFunc_GetCurrentPlayer); +} +stock EF_CanSkipPlayer(const PLAYER) { + return engfunc(EngFunc_CanSkipPlayer, PLAYER); +} +stock EF_SetGroupMask(mask, op) { + return engfunc(EngFunc_SetGroupMask, mask, op); +} +stock EF_GetClientListening(receiver, sender) { + return engfunc(EngFunc_GetClientListening, receiver, sender); +} +stock EF_SetClientListening(receiver, sender, bool:listen) { + return engfunc(EngFunc_SetClientListening, receiver, sender, listen); +} + +stock EF_MessageBegin(msg_dest, msg_type, const Float:ORIGIN[3], const ED) { + return engfunc(EngFunc_MessageBegin, msg_dest, msg_type, ORIGIN, ED); +} +stock EF_WriteCoord(Float:value) { + return engfunc(EngFunc_WriteCoord, value); +} +stock EF_WriteAngle(Float:value) { + return engfunc(EngFunc_WriteAngle, value); +} +stock EF_InfoKeyValue(const INFOBUFFER, const KEY[], returnValue[], maxLength) { + return engfunc(EngFunc_InfoKeyValue, INFOBUFFER, KEY, returnValue, maxLength); +} +stock EF_SetKeyValue(const INFOBUFFER, const KEY[], const VALUE[]) { + return engfunc(EngFunc_SetKeyValue, INFOBUFFER, KEY, VALUE); +} + +stock EF_SetClientKeyValue(const ID, const INFOBUFFER, const KEY[], const VALUE[]) { + return engfunc(EngFunc_SetClientKeyValue, ID, INFOBUFFER, KEY, VALUE); +} + +stock EF_CreateInstBaseline(CLASSNAME, baseline) { + return engfunc(EngFunc_CreateInstBaseline, CLASSNAME, baseline); +} + +// Returns pointer to info buffer that can be used with the INFOBUFFER param +// of EF_InfoKeyValue, EF_SetKeyValue, and EF_SetClientKeyValue +stock EF_GetInfoKeyBuffer(const ENTITY) { + return engfunc(EngFunc_GetInfoKeyBuffer, ENTITY); +} +stock EF_ClientPrintf(const ENTITY, const printType, const MESSAGE[]) { + return engfunc(EngFunc_ClientPrintf, ENTITY, printType, MESSAGE); +} +stock EF_ServerPrint(const MESSAGE[]) { + return engfunc(EngFunc_ServerPrint, MESSAGE); +} + +// DLLFuncs +stock DF_GameInit() { + return dllfunc(DLLFunc_GameInit); +} +stock DF_Spawn(const ENTITY) { + return dllfunc(DLLFunc_Spawn, ENTITY); +} +stock DF_Think(const ENTITY) { + return dllfunc(DLLFunc_Think, ENTITY); +} +stock DF_Use(const ENT_Used, const ENT_User) { + return dllfunc(DLLFunc_Use, ENT_Used, ENT_User); +} +stock DF_Touch(const ENT_Touched, const ENT_Toucher) { + return dllfunc(DLLFunc_Touch, ENT_Touched, ENT_Toucher); +} + +stock DF_Blocked(const ENT_Blocked, const ENT_Other) { + return dllfunc(DLLFunc_Blocked, ENT_Blocked, ENT_Other); +} +stock DF_SetAbsBox(const ENTITY) { + return dllfunc(DLLFunc_SetAbsBox, ENTITY); +} +stock DF_ClientConnect(const ENTITY, const NAME[], const ADDRESS[], RejectReason[128]) { + return dllfunc(DLLFunc_ClientConnect, ENTITY, NAME, ADDRESS, RejectReason); +} +stock DF_ClientDisconnect(const ENTITY) { + return dllfunc(DLLFunc_ClientDisconnect, ENTITY); +} +stock DF_ClientKill(const ENTITY) { + return dllfunc(DLLFunc_ClientKill, ENTITY); +} + +stock DF_ClientPutInServer(const ENTITY) { + return dllfunc(DLLFunc_ClientPutInServer, ENTITY); +} +stock DF_ClientCommand(const ENTITY) { + return dllfunc(DLLFunc_ClientCommand, ENTITY); +} +stock DF_ServerDeactivate() { + return dllfunc(DLLFunc_ServerDeactivate); +} +stock DF_PlayerPreThink(const ENTITY) { + return dllfunc(DLLFunc_PlayerPreThink, ENTITY); +} +stock DF_PlayerPostThink(const ENTITY) { + return dllfunc(DLLFunc_PlayerPostThink, ENTITY); +} + +stock DF_StartFrame() { + return dllfunc(DLLFunc_StartFrame); +} +stock DF_ParmsNewLevel() { + return dllfunc(DLLFunc_ParmsNewLevel); +} +stock DF_ParmsChangeLevel() { + return dllfunc(DLLFunc_ParmsChangeLevel); +} +stock DF_GetGameDescription() { + return dllfunc(DLLFunc_GetGameDescription); +} +stock DF_SpectatorConnect(const ENTITY) { + return dllfunc(DLLFunc_SpectatorConnect, ENTITY); +} + +stock DF_SpectatorDisconnect(const ENTITY) { + return dllfunc(DLLFunc_SpectatorDisconnect, ENTITY); +} +stock DF_SpectatorThink(const ENTITY) { + return dllfunc(DLLFunc_SpectatorThink, ENTITY); +} +stock DF_Sys_Error(const ERROR_STRING[]) { + return dllfunc(DLLFunc_Sys_Error, ERROR_STRING); +} +stock DF_PM_FindTextureType(name[]) { + return dllfunc(DLLFunc_PM_FindTextureType, name); +} +stock DF_RegisterEncoders() { + return dllfunc(DLLFunc_RegisterEncoders); +} + +stock DF_GetHullBounds(hullnumber, Float:mins[3], Float:maxs[3]) { + return dllfunc(DLLFunc_GetHullBounds, hullnumber, mins, maxs); +} +stock DF_CreateInstBaselines() { + return dllfunc(DLLFunc_CreateInstBaselines); +} +stock DF_pfnAllowLagCompensation() { + return dllfunc(DLLFunc_pfnAllowLagCompensation); +} +stock DF_MetaFunc_CallGameEntity(const STRING[], const ENTITY) { + return dllfunc(MetaFunc_CallGameEntity, STRING, ENTITY); +} +stock DF_ClientUserInfoChanged(const IDPLAYER) { + return dllfunc(DLLFunc_ClientUserInfoChanged, IDPLAYER); +} + +stock DF_UpdateClientData(const ENTITY, sendweapons, const cd/* = 0*/) { + return dllfunc(DLLFunc_UpdateClientData, ENTITY, sendweapons, cd); +} +stock DF_AddToFullPack(const STATE/* = 0*/, e, ENT, HOST, hostflags, player, set) { + return dllfunc(DLLFunc_AddToFullPack, STATE, e, ENT, HOST, hostflags, player, set); +} +stock DF_CmdStart(const PLAYER, const CMD/* = 0*/, randomSeed) { + return dllfunc(DLLFunc_CmdStart, PLAYER, CMD, randomSeed); +} +stock DF_CmdEnd(const PLAYER) { + return dllfunc(DLLFunc_CmdEnd, PLAYER); +} +stock DF_CreateBaseline(PLAYER, eIndex, baseline, playerModelIndex, Float:playerMins[3], Float:playerMaxs[3]) { + return dllfunc(DLLFunc_CreateBaseline, PLAYER, eIndex, baseline, playerModelIndex, playerMins, playerMaxs); +} diff --git a/amxmodx/scripting/include/fakemeta_util.inc b/amxmodx/scripting/include/fakemeta_util.inc new file mode 100644 index 0000000..4c66231 --- /dev/null +++ b/amxmodx/scripting/include/fakemeta_util.inc @@ -0,0 +1,882 @@ +/** + * This file provides various utility functions that use the Fakemeta module. + * This file is created and maintained by VEN. + * For support and issues, see: + * http://forums.alliedmods.net/showthread.php?t=28284 + */ + + +/* Fakemeta Utilities +* +* by VEN +* +* This file is provided as is (no warranties). +*/ + +#if !defined _fakemeta_included + #include +#endif + +#if defined _fakemeta_util_included + #endinput +#endif +#define _fakemeta_util_included + +#include + + +/* Engine functions */ + +#define fm_precache_generic(%1) engfunc(EngFunc_PrecacheGeneric, %1) +/* stock fm_precache_generic(const file[]) + return engfunc(EngFunc_PrecacheGeneric, file) */ + +#define fm_precache_event(%1,%2) engfunc(EngFunc_PrecacheEvent, %1, %2) +/* stock fm_precache_event(type, const name[]) + return engfunc(EngFunc_PrecacheEvent, type, name) */ + +// ported by v3x +#define fm_drop_to_floor(%1) engfunc(EngFunc_DropToFloor, %1) +/* stock fm_drop_to_floor(entity) + return engfunc(EngFunc_DropToFloor, entity) */ + +#define fm_force_use(%1,%2) dllfunc(DLLFunc_Use, %2, %1) +/* stock fm_force_use(user, used) + return dllfunc(DLLFunc_Use, used, user) */ + +#define fm_entity_set_size(%1,%2,%3) engfunc(EngFunc_SetSize, %1, %2, %3) +/* stock fm_entity_set_size(index, const Float:mins[3], const Float:maxs[3]) + return engfunc(EngFunc_SetSize, index, mins, maxs) */ + +#define fm_get_decal_index(%1) engfunc(EngFunc_DecalIndex, %1) +/* stock fm_get_decal_index(const decalname[]) + return engfunc(EngFunc_DecalIndex, decalname) */ + +stock Float:fm_entity_range(ent1, ent2) { + new Float:origin1[3], Float:origin2[3]; + pev(ent1, pev_origin, origin1); + pev(ent2, pev_origin, origin2); + + return get_distance_f(origin1, origin2); +} + +// based on KoST's port, upgraded version fits into the macros +#define fm_create_entity(%1) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, %1)) +/* stock fm_create_entity(const classname[]) + return engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, classname)) */ + +#define fm_find_ent_by_class(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2) +/* stock fm_find_ent_by_class(index, const classname[]) + return engfunc(EngFunc_FindEntityByString, index, "classname", classname) */ + +stock fm_find_ent_by_owner(index, const classname[], owner, jghgtype = 0) { + new strtype[11] = "classname", ent = index; + switch (jghgtype) { + case 1: strtype = "target"; + case 2: strtype = "targetname"; + } + + while ((ent = engfunc(EngFunc_FindEntityByString, ent, strtype, classname)) && pev(ent, pev_owner) != owner) {} + + return ent; +} + +#define fm_find_ent_by_target(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "target", %2) +/* stock fm_find_ent_by_target(index, const target[]) + return engfunc(EngFunc_FindEntityByString, index, "target", target) */ + +#define fm_find_ent_by_tname(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "targetname", %2) +/* stock fm_find_ent_by_tname(index, const targetname[]) + return engfunc(EngFunc_FindEntityByString, index, "targetname", targetname) */ + +stock fm_find_ent_by_model(index, const classname[], const model[]) { + new ent = index, mdl[72]; + while ((ent = fm_find_ent_by_class(ent, classname))) { + pev(ent, pev_model, mdl, sizeof mdl - 1); + if (equal(mdl, model)) + return ent; + } + + return 0; +} + +#define fm_find_ent_in_sphere(%1,%2,%3) engfunc(EngFunc_FindEntityInSphere, %1, %2, %3) +/* stock fm_find_ent_in_sphere(index, const Float:origin[3], Float:radius) + return engfunc(EngFunc_FindEntityInSphere, index, origin, radius) */ + +#define fm_call_think(%1) dllfunc(DLLFunc_Think, %1) +/* stock fm_call_think(entity) + return dllfunc(DLLFunc_Think, entity) */ + +#define fm_is_valid_ent(%1) pev_valid(%1) +/* stock fm_is_valid_ent(index) + return pev_valid(index) */ + +stock fm_entity_set_origin(index, const Float:origin[3]) { + new Float:mins[3], Float:maxs[3]; + pev(index, pev_mins, mins); + pev(index, pev_maxs, maxs); + engfunc(EngFunc_SetSize, index, mins, maxs); + + return engfunc(EngFunc_SetOrigin, index, origin); +} + +#define fm_entity_set_model(%1,%2) engfunc(EngFunc_SetModel, %1, %2) +/* stock fm_entity_set_model(index, const model[]) + return engfunc(EngFunc_SetModel, index, model) */ + +// ported by v3x +#define fm_remove_entity(%1) engfunc(EngFunc_RemoveEntity, %1) +/* stock fm_remove_entity(index) + return engfunc(EngFunc_RemoveEntity, index) */ + +#define fm_entity_count() engfunc(EngFunc_NumberOfEntities) +/* stock fm_entity_count() + return engfunc(EngFunc_NumberOfEntities) */ + +#define fm_fake_touch(%1,%2) dllfunc(DLLFunc_Touch, %1, %2) +/* stock fm_fake_touch(toucher, touched) + return dllfunc(DLLFunc_Touch, toucher, touched) */ + +#define fm_DispatchSpawn(%1) dllfunc(DLLFunc_Spawn, %1) +/* stock fm_DispatchSpawn(entity) + return dllfunc(DLLFunc_Spawn, entity) */ + +// ported by v3x +#define fm_point_contents(%1) engfunc(EngFunc_PointContents, %1) +/* stock fm_point_contents(const Float:point[3]) + return engfunc(EngFunc_PointContents, point) */ + +stock fm_trace_line(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) { + engfunc(EngFunc_TraceLine, start, end, ignoreent == -1 ? 1 : 0, ignoreent, 0); + + new ent = get_tr2(0, TR_pHit); + get_tr2(0, TR_vecEndPos, ret); + + return pev_valid(ent) ? ent : 0; +} + +stock fm_trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0) { + new result = 0; + engfunc(EngFunc_TraceHull, origin, origin, ignoremonsters, hull, ignoredent > 0 ? ignoredent : 0, 0); + + if (get_tr2(0, TR_StartSolid)) + result += 1; + if (get_tr2(0, TR_AllSolid)) + result += 2; + if (!get_tr2(0, TR_InOpen)) + result += 4; + + return result; +} + +stock fm_trace_normal(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) { + engfunc(EngFunc_TraceLine, start, end, 0, ignoreent, 0); + get_tr2(0, TR_vecPlaneNormal, ret); + + new Float:fraction; + get_tr2(0, TR_flFraction, fraction); + if (fraction >= 1.0) + return 0; + + return 1; +} + +// note that for CS planted C4 has a "grenade" classname as well +stock fm_get_grenade_id(id, model[], len, grenadeid = 0) { + new ent = fm_find_ent_by_owner(grenadeid, "grenade", id); + if (ent && len > 0) + pev(ent, pev_model, model, len); + + return ent; +} + +#define fm_halflife_time() get_gametime() +/* stock Float:fm_halflife_time() + return get_gametime() */ + +#define fm_attach_view(%1,%2) engfunc(EngFunc_SetView, %1, %2) +/* stock fm_attach_view(index, entity) + return engfunc(EngFunc_SetView, index, entity) */ + +stock fm_playback_event(flags, invoker, eventindex, Float:delay, const Float:origin[3], const Float:angles[3], Float:fparam1, Float:fparam2, iparam1, iparam2, bparam1, bparam2) { + return engfunc(EngFunc_PlaybackEvent, flags, invoker, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2); +} + +#define fm_eng_get_string(%1,%2,%3) engfunc(EngFunc_SzFromIndex, %1, %2, %3) +/* stock fm_eng_get_string(istring, string[], len) + return engfunc(EngFunc_SzFromIndex, istring, string, len) */ + + +/* HLSDK functions */ + +// the dot product is performed in 2d, making the view cone infinitely tall +stock bool:fm_is_in_viewcone(index, const Float:point[3]) { + new Float:angles[3]; + pev(index, pev_angles, angles); + engfunc(EngFunc_MakeVectors, angles); + global_get(glb_v_forward, angles); + angles[2] = 0.0; + + new Float:origin[3], Float:diff[3], Float:norm[3]; + pev(index, pev_origin, origin); + xs_vec_sub(point, origin, diff); + diff[2] = 0.0; + xs_vec_normalize(diff, norm); + + new Float:dot, Float:fov; + dot = xs_vec_dot(norm, angles); + pev(index, pev_fov, fov); + if (dot >= floatcos(fov * M_PI / 360)) + return true; + + return false; +} + +stock bool:fm_is_visible(index, const Float:point[3], ignoremonsters = 0) { + new Float:start[3], Float:view_ofs[3]; + pev(index, pev_origin, start); + pev(index, pev_view_ofs, view_ofs); + xs_vec_add(start, view_ofs, start); + + engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0); + + new Float:fraction; + get_tr2(0, TR_flFraction, fraction); + if (fraction == 1.0) + return true; + + return false; +} + + +/* Engine_stocks functions */ + +stock fm_fakedamage(victim, const classname[], Float:takedmgdamage, damagetype) { + new class[] = "trigger_hurt"; + new entity = fm_create_entity(class); + if (!entity) + return 0; + + new value[16]; + float_to_str(takedmgdamage * 2, value, sizeof value - 1); + fm_set_kvd(entity, "dmg", value, class); + + num_to_str(damagetype, value, sizeof value - 1); + fm_set_kvd(entity, "damagetype", value, class); + + fm_set_kvd(entity, "origin", "8192 8192 8192", class); + fm_DispatchSpawn(entity); + + set_pev(entity, pev_classname, classname); + fm_fake_touch(entity, victim); + fm_remove_entity(entity); + + return 1; +} + +#define fm_find_ent(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2) +/* stock fm_find_ent(index, const classname[]) + return engfunc(EngFunc_FindEntityByString, index, "classname", classname) */ + +#define fm_get_user_button(%1) pev(%1, pev_button) +/* stock fm_get_user_button(index) + return pev(index, pev_button) */ + +#define fm_get_user_oldbutton(%1) pev(%1, pev_oldbuttons) +/* stock fm_get_user_oldbutton(index) + return pev(index, pev_oldbuttons) */ + +#define fm_get_entity_flags(%1) pev(%1, pev_flags) +/* stock fm_get_entity_flags(index) + return pev(index, pev_flags) */ + +#define fm_get_entity_distance(%1,%2) floatround(fm_entity_range(%1, %2)) +/* stock fm_get_entity_distance(ent1, ent2) + return floatround(fm_entity_range(ent1, ent2)) */ + +#define fm_get_grenade(%1) fm_get_grenade_id(%1, "", 0) +/* stock fm_get_grenade(id) + return fm_get_grenade_id(id, "", 0) */ + +// optimization idea by Orangutanz +stock fm_get_brush_entity_origin(index, Float:origin[3]) { + new Float:mins[3], Float:maxs[3]; + + pev(index, pev_origin, origin); + pev(index, pev_mins, mins); + pev(index, pev_maxs, maxs); + + origin[0] += (mins[0] + maxs[0]) * 0.5; + origin[1] += (mins[1] + maxs[1]) * 0.5; + origin[2] += (mins[2] + maxs[2]) * 0.5; + + return 1; +} + +// based on v3x's port, upgraded version returns number of removed entities +stock fm_remove_entity_name(const classname[]) { + new ent = -1, num = 0; + while ((ent = fm_find_ent_by_class(ent, classname))) + num += fm_remove_entity(ent); + + return num; +} + +stock fm_ViewContents(id) { + new origin[3], Float:Orig[3]; + get_user_origin(id, origin, Origin_AimEndEyes); + IVecFVec(origin, Orig); + + return fm_point_contents(Orig); +} + +stock fm_get_speed(entity) { + new Float:Vel[3]; + pev(entity, pev_velocity, Vel); + + return floatround(vector_length(Vel)); +} + +stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) { + new Float:RenderColor[3]; + RenderColor[0] = float(r); + RenderColor[1] = float(g); + RenderColor[2] = float(b); + + set_pev(entity, pev_renderfx, fx); + set_pev(entity, pev_rendercolor, RenderColor); + set_pev(entity, pev_rendermode, render); + set_pev(entity, pev_renderamt, float(amount)); + + return 1; +} + +stock fm_set_entity_flags(index, flag, onoff) { + new flags = pev(index, pev_flags); + if ((flags & flag) > 0) + return onoff == 1 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags - flag); + else + return onoff == 0 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags + flag); + + return 0; +} + +stock fm_set_entity_visibility(index, visible = 1) { + set_pev(index, pev_effects, visible == 1 ? pev(index, pev_effects) & ~EF_NODRAW : pev(index, pev_effects) | EF_NODRAW); + + return 1; +} + +#define fm_get_entity_visibility(%1) (!(pev(%1, pev_effects) & EF_NODRAW)) +/* stock fm_get_entity_visibility(index) + return !(pev(index, pev_effects) & EF_NODRAW) */ + +stock fm_set_user_velocity(entity, const Float:vector[3]) { + set_pev(entity, pev_velocity, vector); + + return 1; +} + +#define fm_get_user_velocity(%1,%2) pev(%1, pev_velocity, %2) +/* stock fm_get_user_velocity(entity, Float:vector[3]) + return pev(entity, pev_velocity, vector) */ + + +/* Fun functions */ + +#define fm_get_client_listen(%1,%2) engfunc(EngFunc_GetClientListening, %1, %2) +/* stock fm_get_client_listen(receiver, sender) + return engfunc(EngFunc_GetClientListening, receiver, sender) */ + +#define fm_set_client_listen(%1,%2,%3) engfunc(EngFunc_SetClientListening, %1, %2, %3) +/* stock fm_set_client_listen(receiver, sender, listen) + return engfunc(EngFunc_SetClientListening, receiver, sender, listen) */ + +stock fm_get_user_godmode(index) { + new Float:val; + pev(index, pev_takedamage, val); + + return (val == DAMAGE_NO); +} + +stock fm_set_user_godmode(index, godmode = 0) { + set_pev(index, pev_takedamage, godmode == 1 ? DAMAGE_NO : DAMAGE_AIM); + + return 1; +} + +stock fm_set_user_armor(index, armor) { + set_pev(index, pev_armorvalue, float(armor)); + + return 1; +} + +stock fm_set_user_health(index, health) { + health > 0 ? set_pev(index, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, index); + + return 1; +} + +stock fm_set_user_origin(index, /* const */ origin[3]) { + new Float:orig[3]; + IVecFVec(origin, orig); + + return fm_entity_set_origin(index, orig); +} + +stock fm_set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) { + return fm_set_rendering(index, fx, r, g, b, render, amount); +} + +stock fm_give_item(index, const item[]) { + if (!equal(item, "weapon_", 7) && !equal(item, "ammo_", 5) && !equal(item, "item_", 5) && !equal(item, "tf_weapon_", 10)) + return 0; + + new ent = fm_create_entity(item); + if (!pev_valid(ent)) + return 0; + + new Float:origin[3]; + pev(index, pev_origin, origin); + set_pev(ent, pev_origin, origin); + set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN); + dllfunc(DLLFunc_Spawn, ent); + + new save = pev(ent, pev_solid); + dllfunc(DLLFunc_Touch, ent, index); + if (pev(ent, pev_solid) != save) + return ent; + + engfunc(EngFunc_RemoveEntity, ent); + + return -1; +} + +stock fm_set_user_maxspeed(index, Float:speed = -1.0) { + engfunc(EngFunc_SetClientMaxspeed, index, speed); + set_pev(index, pev_maxspeed, speed); + + return 1; +} + +stock Float:fm_get_user_maxspeed(index) { + new Float:speed; + pev(index, pev_maxspeed, speed); + + return speed; +} + +stock fm_set_user_gravity(index, Float:gravity = 1.0) { + set_pev(index, pev_gravity, gravity); + + return 1; +} + +stock Float:fm_get_user_gravity(index) { + new Float:gravity; + pev(index, pev_gravity, gravity); + + return gravity; +} + +/* interferes with FM_Spawn enum, just use fm_DispatchSpawn +stock fm_spawn(entity) { + return dllfunc(DLLFunc_Spawn, entity) +} +*/ + +stock fm_set_user_noclip(index, noclip = 0) { + set_pev(index, pev_movetype, noclip == 1 ? MOVETYPE_NOCLIP : MOVETYPE_WALK); + + return 1; +} + +#define fm_get_user_noclip(%1) (pev(%1, pev_movetype) == MOVETYPE_NOCLIP) +/* stock fm_get_user_noclip(index) + return (pev(index, pev_movetype) == MOVETYPE_NOCLIP) */ + +// note: get_user_weapon will still return former weapon index +stock fm_strip_user_weapons(index) { + new ent = fm_create_entity("player_weaponstrip"); + if (!pev_valid(ent)) + return 0; + + dllfunc(DLLFunc_Spawn, ent); + dllfunc(DLLFunc_Use, ent, index); + engfunc(EngFunc_RemoveEntity, ent); + + return 1; +} + +stock fm_set_user_frags(index, frags) { + set_pev(index, pev_frags, float(frags)); + + return 1; +} + + +/* Cstrike functions */ + +stock fm_cs_user_spawn(index) { + set_pev(index, pev_deadflag, DEAD_RESPAWNABLE); + dllfunc(DLLFunc_Spawn, index); + set_pev(index, pev_iuser1, 0); + + return 1; +} + + +/* Custom functions */ + +// based on Basic-Master's set_keyvalue, upgraded version accepts an optional classname (a bit more efficient if it is passed) +stock fm_set_kvd(entity, const key[], const value[], const classname[] = "") { + if (classname[0]) + set_kvd(0, KV_ClassName, classname); + else { + new class[32]; + pev(entity, pev_classname, class, sizeof class - 1); + set_kvd(0, KV_ClassName, class); + } + + set_kvd(0, KV_KeyName, key); + set_kvd(0, KV_Value, value); + set_kvd(0, KV_fHandled, 0); + + return dllfunc(DLLFunc_KeyValue, entity, 0); +} + +stock fm_find_ent_by_integer(index, pev_field, value) { + static maxents; + if (!maxents) + maxents = global_get(glb_maxEntities); + + for (new i = index + 1; i < maxents; ++i) { + if (pev_valid(i) && pev(i, pev_field) == value) + return i; + } + + return 0; +} + +stock fm_find_ent_by_flags(index, pev_field, flags) { + static maxents; + if (!maxents) + maxents = global_get(glb_maxEntities); + + for (new i = index + 1; i < maxents; ++i) { + if (pev_valid(i) && (pev(i, pev_field) & flags) == flags) + return i; + } + + return 0; +} + +stock Float:fm_distance_to_box(const Float:point[3], const Float:mins[3], const Float:maxs[3]) { + new Float:dist[3]; + for (new i = 0; i < 3; ++i) { + if (point[i] > maxs[i]) + dist[i] = point[i] - maxs[i]; + else if (mins[i] > point[i]) + dist[i] = mins[i] - point[i]; + } + + return vector_length(dist); +} + +stock Float:fm_boxes_distance(const Float:mins1[3], const Float:maxs1[3], const Float:mins2[3], const Float:maxs2[3]) { + new Float:dist[3]; + for (new i = 0; i < 3; ++i) { + if (mins1[i] > maxs2[i]) + dist[i] = mins1[i] - maxs2[i]; + else if (mins2[i] > maxs1[i]) + dist[i] = mins2[i] - maxs1[i]; + } + + return vector_length(dist); +} + +stock Float:fm_distance_to_boxent(entity, boxent) { + new Float:point[3]; + pev(entity, pev_origin, point); + + new Float:mins[3], Float:maxs[3]; + pev(boxent, pev_absmin, mins); + pev(boxent, pev_absmax, maxs); + + return fm_distance_to_box(point, mins, maxs); +} + +stock Float:fm_boxents_distance(boxent1, boxent2) { + new Float:mins1[3], Float:maxs1[3]; + pev(boxent1, pev_absmin, mins1); + pev(boxent1, pev_absmax, maxs1); + + new Float:mins2[3], Float:maxs2[3]; + pev(boxent2, pev_absmin, mins2); + pev(boxent2, pev_absmax, maxs2); + + return fm_boxes_distance(mins1, maxs1, mins2, maxs2); +} + +// projects a center of a player's feet base (originally by P34nut, improved) +stock Float:fm_distance_to_floor(index, ignoremonsters = 1) { + new Float:start[3], Float:dest[3], Float:end[3]; + pev(index, pev_origin, start); + dest[0] = start[0]; + dest[1] = start[1]; + dest[2] = -8191.0; + + engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0); + get_tr2(0, TR_vecEndPos, end); + + pev(index, pev_absmin, start); + new Float:ret = start[2] - end[2]; + + return ret > 0 ? ret : 0.0; +} + +// potential to crash (?) if used on weaponbox+weapon_* entity pair (use fm_remove_weaponbox instead) +stock fm_kill_entity(index) { + set_pev(index, pev_flags, pev(index, pev_flags) | FL_KILLME); + + return 1; +} + +// if weapon index isn't passed then assuming that it's the current weapon +stock fm_get_user_weapon_entity(id, wid = 0) { + new weap = wid, clip, ammo; + if (!weap && !(weap = get_user_weapon(id, clip, ammo))) + return 0; + + new class[32]; + get_weaponname(weap, class, sizeof class - 1); + + return fm_find_ent_by_owner(-1, class, id); +} + +// only weapon index or its name can be passed, if neither is passed then the current gun will be stripped +stock bool:fm_strip_user_gun(index, wid = 0, const wname[] = "") { + new ent_class[32]; + if (!wid && wname[0]) + copy(ent_class, sizeof ent_class - 1, wname); + else { + new weapon = wid, clip, ammo; + if (!weapon && !(weapon = get_user_weapon(index, clip, ammo))) + return false; + + get_weaponname(weapon, ent_class, sizeof ent_class - 1); + } + + new ent_weap = fm_find_ent_by_owner(-1, ent_class, index); + if (!ent_weap) + return false; + + engclient_cmd(index, "drop", ent_class); + + new ent_box = pev(ent_weap, pev_owner); + if (!ent_box || ent_box == index) + return false; + + dllfunc(DLLFunc_Think, ent_box); + + return true; +} + +// only weapon index or its name can be passed, if neither is passed then the current gun will be transferred +stock bool:fm_transfer_user_gun(index1, index2, wid = 0, const wname[] = "") { + new ent_class[32]; + if (!wid && wname[0]) + copy(ent_class, sizeof ent_class - 1, wname); + else { + new weapon = wid, clip, ammo; + if (!weapon && !(weapon = get_user_weapon(index1, clip, ammo))) + return false; + + get_weaponname(weapon, ent_class, sizeof ent_class - 1); + } + + new ent_weap = fm_find_ent_by_owner(-1, ent_class, index1); + if (!ent_weap) + return false; + + engclient_cmd(index1, "drop", ent_class); + + new ent_box = pev(ent_weap, pev_owner); + if (!ent_box || ent_box == index1) + return false; + + set_pev(ent_box, pev_flags, pev(ent_box, pev_flags) | FL_ONGROUND); + dllfunc(DLLFunc_Touch, ent_box, index2); + if (pev(ent_weap, pev_owner) != index2) + return false; + + return true; +} + +stock bool:fm_is_ent_visible(index, entity, ignoremonsters = 0) { + new Float:start[3], Float:dest[3]; + pev(index, pev_origin, start); + pev(index, pev_view_ofs, dest); + xs_vec_add(start, dest, start); + + pev(entity, pev_origin, dest); + engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0); + + new Float:fraction; + get_tr2(0, TR_flFraction, fraction); + if (fraction == 1.0 || get_tr2(0, TR_pHit) == entity) + return true; + + return false; +} + +// ported from AMXX's core get_user_origin(..., 3) (suggested by Greenberet) +stock fm_get_aim_origin(index, Float:origin[3]) { + new Float:start[3], Float:view_ofs[3]; + pev(index, pev_origin, start); + pev(index, pev_view_ofs, view_ofs); + xs_vec_add(start, view_ofs, start); + + new Float:dest[3]; + pev(index, pev_v_angle, dest); + engfunc(EngFunc_MakeVectors, dest); + global_get(glb_v_forward, dest); + xs_vec_mul_scalar(dest, 9999.0, dest); + xs_vec_add(start, dest, dest); + + engfunc(EngFunc_TraceLine, start, dest, 0, index, 0); + get_tr2(0, TR_vecEndPos, origin); + + return 1; +} + +stock bool:fm_get_user_longjump(index) { + new value[2]; + engfunc(EngFunc_GetPhysicsKeyValue, index, "slj", value, 1); + switch (value[0]) { + case '1': return true; + } + + return false; +} + +stock fm_set_user_longjump(index, bool:longjump = true, bool:tempicon = true) { + if (longjump == fm_get_user_longjump(index)) + return; + + if (longjump) { + engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "1"); + if (tempicon) { + static msgid_itempickup; + if (!msgid_itempickup) + msgid_itempickup = get_user_msgid("ItemPickup"); + + message_begin(MSG_ONE, msgid_itempickup, _, index); + write_string("item_longjump"); + message_end(); + } + } + else + engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "0"); +} + +#define WEAPON_SUIT 31 + +stock bool:fm_get_user_suit(index) { + return bool:(!(!(pev(index, pev_weapons) & (1<_lv/_addon/_/_hd + * and itself + * GAMECONFIG The default writable directory () + * GAMEDOWNLOAD The download directory (_download) + * GAME_FALLBACK All paths related to fallback game, same as GAME + * DEFAULTGAME All paths related to the default game which is "valve", same as GAME + * BASE The base path where server is installed + * + * Note that some paths are non-writable. It includes all _* (expect _download) + * and DEFAULTGAME. Any file inside a non-writable path will be ignored if you try to open + * it in writing mode. + * + * @param filename File to open + * @param mode Open mode + * @param use_valve_fs If true, the Valve file system will be used instead + * This can be used to finred files existing in valve + * search paths, rather than solely files existing directly + * in the gamedir. + * @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths + * + * @return A file handle, or null if the file could not be opened. + */ +native fopen(const filename[], const mode[], bool:use_valve_fs = false, const valve_path_id[] = "GAME"); + +/** + * Closes a file handle. + * + * @param file File handle + */ +native fclose(file); + +/** + * Reads a single binary data from a file. + * + * @param file Handle to the file + * @param data Variable to store item read + * @param mode Size of each element, in bytes, to be read + * See BLOCK_* constants + * + * @return Number of elements read + */ +native fread(file, &any:data, mode); + +/** + * Reads binary data from a file. + * + * @param file Handle to the file + * @param data Array to store each item read + * @param blocks Number of items to read into the array + * @param mode Size of each element, in bytes, to be read + * Valid sizes are 1, 2, or 4. See BLOCK_* constants. + * + * @return Number of elements read + */ +native fread_blocks(file, any:data[], blocks, mode); + +/** + * Reads raw binary data from a file. + * + * @param file Handle to the file + * @param stream Array to store each item read + * @param blocksize Number of items to read into the array + * @param blocks Size of each element, in bytes. The data is read directly. + * That is, in 1 or 2-byte mode, the lower byte(s) in + * each cell are used directly, rather than performing + * any casts from a 4-byte number to a smaller number. + * + * @return Number of elements read + */ +native fread_raw(file, any:stream[], blocksize, blocks); + +/** + * Writes a single binary data to a file. + * + * @param file Handle to the file + * @param data Item to write + * @param mode Size of each item in the array in bytes + * Valid sizes are 1, 2, or 4. See BLOCK_* constants + * + * @return Number of elements written + */ +native fwrite(file, any:data, mode); + +/** + * Writes binary data to a file. + * + * @param file Handle to the file + * @param data Array of items to write + * @param blocks Number of items in the array + * @param mode Size of each item in the array in bytes + * Valid sizes are 1, 2, or 4. See BLOCK_* constants + * + * @return Number of elements written + */ +native fwrite_blocks(file, const any:data[], blocks, mode); + +/** + * Writes raw binary data to a file. + * + * @param file Handle to the file. + * @param stream Array of items to write. The data is written directly. + * That is, in 1 or 2-byte mode, the lower byte(s) in + * each cell are used directly, rather than performing + * any casts from a 4-byte number to a smaller number. + * @param blocks Size of each item in the array in bytes. + * @param mode Number of items in the array. + * + * @return Number of elements written + */ +native fwrite_raw(file, const any:stream[], blocks, mode); + +/** + * Tests if the end of file has been reached. + * + * @param file Handle to the file + * + * @return 1 if end of file has been reached, 0 otherwise. + */ +native feof(file); + +/** + * Reads a line from a text file. + * + * @param file Handle to the file. + * @param buffer String buffer to hold the line + * @param maxlength Maximum size of string buffer + * + * @return Total number of characters written on success, 0 otherwise + */ +native fgets(file, buffer[], maxlength); + +/** + * Writes a line of text to a text file. + * + * @param file Handle to the file + * @param text String to write + * @param null_term True to append NULL terminator, false otherwise + * + * @return 0 on success, -1 otherwise + */ +native fputs(file, const text[], bool:null_term = false); + +/** + * Writes a line of formatted text to a text file. + * + * @param file Handle to the file + * @param format Formatting rules + * @param ... Variable number of format parameters + * + * @return Total number of characters written on success, 0 otherwise + */ +native fprintf(file, const fmt[], any:...); + +/** + * Sets the file position indicator. + * + * @param file Handle to the file + * @param position Position relative to what is specified in whence + * @param start SEEK_ constant value of where to see from + * + * @return 0 on success, a non-zero value otherwise + */ +native fseek(file, position, start); + +/** + * Gets current position in the file. + * + * @param file Handle to the file + * + * @return Value for the file position indicator + */ +native ftell(file); + +/** + * Gets character from file. + * + * @param file Handle to the file + * + * @return Character read on success, -1 otherwise + */ +native fgetc(file); + +/** + * Writes character to file + * + * @param file Handle to the file + * @param data Character to put + * + * @return Character written on success, -1 otherwise + */ +native fputc(file, data); + +/** + * Ungets character from file. + * + * @param file Handle to the file + * @param data Character to unget + * + * @return On success, the character put back is returned, -1 otherwise + */ +native fungetc(file, data); + +/** + * Flushes a buffered output stream. + * + * @param file File handle, or 0 for all open streams + * + * @return 0 on success, -1 on failure + */ +native fflush(file); + +/** + * Gets the formatted file size in bytes. + * + * @param filename Path to the file + * @param ... Variable number of format parameters + * + * @return File size in bytes, otherwise -1 if file not found + */ +native filesize(const filename[], any:...); + +/** + * Removes a directory. + * + * @note On most Operating Systems you cannot remove a directory which has files inside it. + * + * @param path Path to the directory + * + * @return 1 on success, 0 otherwise + */ +native rmdir(const path[]); + +/** + * Creates a directory. + * + * @param path Path to create + * @param mode Permissions (default is o=rx,g=rx,u=rwx). Note that folders must have + * the execute bit set on Linux. On Windows, the mode is ignored. + * @param use_valve_fs If true, the Valve file system will be used instead + * This can be used to create folders in the game's + * Valve search paths, rather than directly in the gamedir. + * @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for default + * In this case, mode is ignored + * + * @return 0 on success, -1 otherwise + */ +native mkdir(const dirname[], mode = FPERM_DIR_DEFAULT, bool:use_valve_fs = false, const valve_path_id[] = "GAMECONFIG"); + +/** + * Deletes a file (delete_file macro) + * + * @param filename Path of the file to delete + * @param use_valve_fs If true, the Valve file system will be used instead. + * This can be used to delete files existing in the Valve + * search path, rather than solely files existing directly + * in the gamedir. + * @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths + * + * @return 1 on success, 0 on failure or if file not immediately removed + */ +native unlink(const filename[], bool:use_valve_fs = false, const valve_path_id[] = "GAMECONFIG"); + +/** + * Opens a directory/folder for contents enumeration. + * + * @note Directories are closed with close_dir(). + * + * @param dir Path to open. + * @param firstfile String buffer to hold first file name + * @param length Maximum size of the string buffer + * @param type Optional variable to store the file type + * @param use_valve_fs If true, the Valve file system will be used instead. + * This can be used to find files existing in any of + * the Valve search paths, rather than solely files + * existing directly in the gamedir. + * @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths. + * + * @return Handle to the directory, 0 otherwise + */ +native open_dir(const dir[], firstfile[], length, &FileType:type = FileType_Unknown, bool:use_valve_fs = false, const valve_path_id[] = "GAME"); + +/** + * Reads the next directory entry as a local filename. + * + * @note Contents of buffers are undefined when returning false. + * @note Both the '.' and '..' automatic directory entries will be retrieved for Windows and Linux. + * + * @param dirh Handle to a directory + * @param buffer String buffer to hold directory name + * @param length Maximum size of string buffer + * @param type Optional variable to store the file type. FileType_* constants + * + * @return 1 on success, 0 if there are no more files to read. + */ +native next_file(dirh, buffer[], length, &FileType:type = FileType_Unknown); + +/** + * Closes the directory. + * + * @param dirh Handle to a directory + */ +native close_dir(dirh); + +/** + * Loads a file using the LoadFileForMe engine function. + * + * The data is truncated if there is not enough space. No null-terminator + * is applied; the data is the raw contents of the file. + * + * @param file File to load (may be a file from the GCF) + * @param buffer Buffer to store file contents + * @param maxlength Maximum size of the file buffer + * @param length Variable to store the file length. This may return + * a number larger than the buffer size + * @return -1 if the file could not be loaded. Otherwise, + * the number of cells actually written to the buffer + * are returned. + */ +native LoadFileForMe(const file[], buffer[], maxlength, &length = 0); + +/** + * Returns a file timestamp as a unix timestamp. + * + * @param file File name + * @param tmode Time mode, see FileTime_* constants + * + * @return Returns a file timestamp as a unix timestamp + */ +native GetFileTime(const file[], FileTimeType:tmode); + +/** + * Changes a file or directories permissions. + * + * @param path Path to the file + * @param mode Permissions to set, see FPERM_* constants + * + * @return True on success, false otherwise + */ +native bool:SetFilePermissions(const path[], mode); + +/** + * Reads a single int8 (byte) from a file. The returned value is sign- + * extended to an int32. + * + * @param file Handle to the file + * @param data Variable to store the data read + * + * @return True on success, false on failure + */ +native bool:FileReadInt8(file, &any:data); + +/** + * Reads a single uint8 (unsigned byte) from a file. The returned value is + * zero-extended to an int32. + * + * @param file Handle to the file + * @param data Variable to store the data read + * + * @return True on success, false on failure + */ +native bool:FileReadUint8(file, &any:data); + +/** + * Reads a single int16 (short) from a file. The value is sign-extended to + * an int32. + * + * @param file Handle to the file + * @param data Variable to store the data read + * + * @return True on success, false on failure + */ +native bool:FileReadInt16(file, &any:data); + +/** + * Reads a single unt16 (unsigned short) from a file. The value is zero- + * extended to an int32. + * + * @param file Handle to the file + * @param data Variable to store the data read + * + * @return True on success, false on failure + */ +native bool:FileReadUint16(file, &any:data); + +/** + * Reads a single int32 (int/cell) from a file. + * + * @param file Handle to the file + * @param data Variable to store the data read + * + * @return True on success, false on failure + */ +native bool:FileReadInt32(file, &any:data); + +/** + * Writes a single int8 (byte) to a file. + * + * @param file Handle to the file + * @param data Data to write (truncated to an int8) + * + * @return True on success, false on failure + */ +native bool:FileWriteInt8(file, any:data); + +/** + * Writes a single int16 (short) to a file. + * + * @param file Handle to the file + * @param data Data to write (truncated to an int16) + * + * @return True on success, false on failure + */ +native bool:FileWriteInt16(file, any:data); + +/** + * Writes a single int32 (int/cell) to a file. + * + * @param file Handle to the file + * @param data Data to write + * + * @return True on success, false on failure + */ +native bool:FileWriteInt32(file, any:data); + diff --git a/amxmodx/scripting/include/float.inc b/amxmodx/scripting/include/float.inc new file mode 100644 index 0000000..a731ffb --- /dev/null +++ b/amxmodx/scripting/include/float.inc @@ -0,0 +1,422 @@ +/* Float arithmetic +* +* (c) Copyright 1999, Artran, Inc. +* Written by Greg Garner (gmg@artran.com) +* Modified in March 2001 to include user defined +* operators for the floating point functions. +* +* This file is provided as is (no warranties). +*/ + +#if defined _float_included + #endinput +#endif +#define _float_included + +#pragma rational Float + +/** + * Different methods of rounding + */ +enum floatround_method { + floatround_round = 0, + floatround_floor, + floatround_ceil, + floatround_tozero +}; + +/** + * Different units of measurement for angles + */ +enum anglemode { + radian = 0, + degrees, + grades +}; + +/** + * Converts an integer into a floating point value. + * + * @param value Value to be converted + * + * @return Converted value + */ +native Float:float(value); + +/** + * Converts a string into a floating point value. + * + * @param string Input string to be converted + * + * @return Converted value + */ +native Float:floatstr(const string[]); + +/** + * Returns the fractional part of a floating point value + * + * @param string Floating point value to get the fractional part from + * + * @return The fractional part + */ +native Float:floatfract(Float:value); + +/** + * Rounds a floating point value to an integer value + * + * @note For the list of available rounding methods look at + * floatround_method enumeration. + * + * @param value Floating point value to be rounded + * @param method Rounding method + * + * @return Converted value + */ +native floatround(Float:value, floatround_method:method=floatround_round); + +/** + * Compares two floating point values. + * + * @param fOne First value to be compared + * @param fTwo Second value to be compared + * + * @return If arguments are equal, returns 0. + * If the first one is greater, returns 1. + * If the second one is greater, returns -1. + */ +native floatcmp(Float:fOne, Float:fTwo); + +/** + * Returns the square root of a floating point value + * + * @note Same as floatpower(value, 0.5) + * + * @param value Floating point value to get square root from + * + * @return Square root of the input value + */ +native Float:floatsqroot(Float:value); + +/** + * Returns the value raised to the power of the exponent + * + * @param value Floating point value to be raised + * @param exponent The exponent + * + * @return Value raised to the power of the exponent + */ +native Float:floatpower(Float:value, Float:exponent); + +/** + * Returns the logarithm of value + * + * @param value Floating point value to calculate the logarithm for + * @param base The optional logarithmic base to use. + * Defaults to 10, or the natural logarithm + * + * @return Square root of the input value + */ +native Float:floatlog(Float:value, Float:base=10.0); + +/** + * Returns the sine of a given angle + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The angle to calculate the sine from + * @param mode What unit of measurement is the angle specified in + * Defaults to radians + * + * @return The sine of a given angle + */ +native Float:floatsin(Float:value, anglemode:mode=radian); + +/** + * Returns the cosine of a given angle + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The angle to calculate the cosine from + * @param mode What unit of measurement is the angle specified in + * Defaults to radians + * + * @return The cosine of a given angle + */ +native Float:floatcos(Float:value, anglemode:mode=radian); + +/** + * Returns the tangent of a given angle + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The angle to calculate the tangent from + * @param mode What unit of measurement is the angle specified in + * Defaults to radians + * + * @return The tangent of a given angle + */ +native Float:floattan(Float:value, anglemode:mode=radian); + +/** + * Returns the hyperbolic sine of a given angle + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The angle to calculate the hyperbolic sine from + * @param mode What unit of measurement is the angle specified in + * Defaults to radians + * + * @return The hyperbolic sine of a given angle + */ +native Float:floatsinh(Float:angle, anglemode:mode=radian); + +/** + * Returns the hyperbolic cosine of a given angle + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The angle to calculate the hyperbolic cosine from + * @param mode What unit of measurement is the angle specified in + * Defaults to radians + * + * @return The hyperbolic cosine of a given angle + */ +native Float:floatcosh(Float:angle, anglemode:mode=radian); + +/** + * Returns the hyperbolic tangent of a given angle + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The angle to calculate the hyperbolic tangent from + * @param mode What unit of measurement is the angle specified in + * Defaults to radians + * + * @return The hyperbolic tangent of a given angle + */ +native Float:floattanh(Float:angle, anglemode:mode=radian); + +/** + * Returns the absolute value of a floating point value + * + * @param value The floating point value to get the absolute value from + * + * @return The absolute value + */ +native Float:floatabs(Float:value); + +/* Return the angle of a sine, cosine or tangent. + * The output angle may be in radians, degrees, or grades. */ + +/** + * Returns the angle of the given tangent + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The tangent to calculate the angle from + * @param mode What unit of measurement should the output angle be in + * + * @return The angle of a tangent + */ +native Float:floatatan(Float:angle, {anglemode,_}:radix); + +/** + * Returns the angle of the given cosine + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The cosine to calculate the angle from + * @param mode What unit of measurement should the output angle be in + * + * @return The angle of a cosine + */ +native Float:floatacos(Float:angle, {anglemode,_}:radix); + +/** + * Returns the angle of the given sine + * + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param value The sine to calculate the angle from + * @param mode What unit of measurement should the output angle be in + * + * @return The angle of a sine + */ +native Float:floatasin(Float:angle, {anglemode,_}:radix); + +/** + * Computes the principal value of arctangent of y/x + * + * @note Someone should verify this native, not sure what it actually does. + * @note For available units of measurements(modes) look at the anglemode enum + * + * @param x Value representing the proportion of the x-coordinate. + * @param y Value representing the proportion of the x-coordinate. + * @param mode What unit of measurement should the output angle be in + * + * @return Arctangent of y/x + */ +native Float:floatatan2(Float:x, Float:y, {anglemode,_}:radix); + + + +/* Multiply two floats together */ +native Float:floatmul(Float:oper1, Float:oper2); + +/* Divide the dividend float by the divisor float */ +native Float:floatdiv(Float:dividend, Float:divisor); + +/* Add two floats together */ +native Float:floatadd(Float:dividend, Float:divisor); + +/* Subtract oper2 float from oper1 float */ +native Float:floatsub(Float:oper1, Float:oper2); + +/* user defined operators */ +native Float:operator*(Float:oper1, Float:oper2) = floatmul; +native Float:operator/(Float:oper1, Float:oper2) = floatdiv; +native Float:operator+(Float:oper1, Float:oper2) = floatadd; +native Float:operator-(Float:oper1, Float:oper2) = floatsub; + +stock Float:operator++(Float:oper) + return oper+1.0; + +stock Float:operator--(Float:oper) + return oper-1.0; + +stock Float:operator-(Float:oper) + return oper^Float:cellmin; /* IEEE values are sign/magnitude */ + +stock Float:operator*(Float:oper1, oper2) + return floatmul(oper1, float(oper2)); /* "*" is commutative */ + +stock Float:operator/(Float:oper1, oper2) + return floatdiv(oper1, float(oper2)); + +stock Float:operator/(oper1, Float:oper2) + return floatdiv(float(oper1), oper2); + +stock Float:operator+(Float:oper1, oper2) + return floatadd(oper1, float(oper2)); /* "+" is commutative */ + +stock Float:operator-(Float:oper1, oper2) + return floatsub(oper1, float(oper2)); + +stock Float:operator-(oper1, Float:oper2) + return floatsub(float(oper1), oper2); + +stock bool:operator==(Float:oper1, Float:oper2) + return floatcmp(oper1, oper2) == 0; + +stock bool:operator==(Float:oper1, oper2) + return floatcmp(oper1, float(oper2)) == 0; /* "==" is commutative */ + +stock bool:operator!=(Float:oper1, Float:oper2) + return floatcmp(oper1, oper2) != 0; + +stock bool:operator!=(Float:oper1, oper2) + return floatcmp(oper1, float(oper2)) != 0; /* "==" is commutative */ + +stock bool:operator>(Float:oper1, Float:oper2) + return floatcmp(oper1, oper2) > 0; + +stock bool:operator>(Float:oper1, oper2) + return floatcmp(oper1, float(oper2)) > 0; + +stock bool:operator>(oper1, Float:oper2) + return floatcmp(float(oper1), oper2) > 0; + +stock bool:operator>=(Float:oper1, Float:oper2) + return floatcmp(oper1, oper2) >= 0; + +stock bool:operator>=(Float:oper1, oper2) + return floatcmp(oper1, float(oper2)) >= 0; + +stock bool:operator>=(oper1, Float:oper2) + return floatcmp(float(oper1), oper2) >= 0; + +stock bool:operator<(Float:oper1, Float:oper2) + return floatcmp(oper1, oper2) < 0; + +stock bool:operator<(Float:oper1, oper2) + return floatcmp(oper1, float(oper2)) < 0; + +stock bool:operator<(oper1, Float:oper2) + return floatcmp(float(oper1), oper2) < 0; + +stock bool:operator<=(Float:oper1, Float:oper2) + return floatcmp(oper1, oper2) <= 0; + +stock bool:operator<=(Float:oper1, oper2) + return floatcmp(oper1, float(oper2)) <= 0; + +stock bool:operator<=(oper1, Float:oper2) + return floatcmp(float(oper1), oper2) <= 0; + +stock bool:operator!(Float:oper) + return (_:oper & ((-1)/2)) == 0; /* -1 = all bits to 1; /2 = remove most significant bit (sign) + works on both 32bit and 64bit systems; no constant required */ +/* forbidden operations */ +forward operator%(Float:oper1, Float:oper2); +forward operator%(Float:oper1, oper2); +forward operator%(oper1, Float:oper2); + + +/** + * Returns whichever value is the smaller one + * + * @param ValueA The first value + * @param ValueB The second value + * + * @return ValueA if it is smaller than ValueB, and vice versa + */ +stock Float:floatmin(Float:ValueA, Float:ValueB) +{ + if (ValueA<=ValueB) + { + return ValueA; + } + + return ValueB; +} + +/** + * Returns whichever value is the greater one + * + * @param ValueA The first value + * @param ValueB The second value + * + * @return ValueA if it is greater than ValueB, and vice versa + */ +stock Float:floatmax(Float:ValueA, Float:ValueB) +{ + if (ValueA>=ValueB) + { + return ValueA; + } + + return ValueB; +} + +/** + * Clamps a value between a minimum and a maximum floating point value + * + * @param Value The value to be clamped + * @param MinValue Minimum value + * @param MaxValue Maximum value + * + * @return The Value clamped between MinValue and MaxValue + */ +stock Float:floatclamp(Float:Value, Float:MinValue, Float:MaxValue) +{ + if (Value<=MinValue) + { + return MinValue; + } + if (Value>=MaxValue) + { + return MaxValue; + } + + return Value; +} \ No newline at end of file diff --git a/amxmodx/scripting/include/fun.inc b/amxmodx/scripting/include/fun.inc new file mode 100644 index 0000000..0dd35eb --- /dev/null +++ b/amxmodx/scripting/include/fun.inc @@ -0,0 +1,333 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Fun Functions +// + +#if defined _fun_included + #endinput +#endif +#define _fun_included + +#pragma reqlib fun +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib fun +#endif + + +/** + * Parts of body for hits, for use with set_user_hitzones(). + */ +const HITZONE_GENERIC = (1 << HIT_GENERIC); // 1 +const HITZONE_HEAD = (1 << HIT_HEAD); // 2 +const HITZONE_CHEST = (1 << HIT_CHEST); // 4 +const HITZONE_STOMACH = (1 << HIT_STOMACH); // 8 +const HITZONE_LEFTARM = (1 << HIT_LEFTARM); // 16 +const HITZONE_RIGHTARM = (1 << HIT_RIGHTARM); // 32 +const HITZONE_LEFTLEG = (1 << HIT_LEFTLEG); // 64 +const HITZONE_RIGHTLEG = (1 << HIT_RIGHTLEG); // 128 +const HITZONES_DEFAULT = HITZONE_GENERIC | HITZONE_HEAD | HITZONE_CHEST | HITZONE_STOMACH | + HITZONE_LEFTARM | HITZONE_RIGHTARM | HITZONE_LEFTLEG | HITZONE_RIGHTLEG; // 255 + +/** + * Tells whether receiver hears sender via voice communication. + * + * @param receiver Receiver + * @param sender Sender + * + * @return 1 if receiver hears the sender, 0 otherwise. + * @error If receiver or sender are not connected or not + * within the range of 1 to MaxClients + */ +native get_client_listen(receiver, sender); + +/** + * Sets who can listen who. + * + * @param receiver Receiver + * @param sender Sender + * @param listen 1 if receiver should be able to hear sender, 0 if not + * + * @return 0 if the setting can't be done for some reason + * @error If receiver or sender are not connected or not + * within the range of 1 to MaxClients. + */ +native set_client_listen(receiver, sender, listen); + +/** + * Sets player's godmode. + * + * @param index Client index + * @param godmode 1 to enable godmode, 0 to disable + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_godmode(index, godmode = 0); + +/** + * Tells whether a player has godmode on. + * + * @param index Client index + * + * @return 1 if player has godmode on, 0 if not + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native get_user_godmode(index); + +/** + * Sets player's armor amount. + * + * @param index Client index + * @param armor The armor amount to set + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_armor(index, armor); + +/** + * Sets player's health amount. + * + * @param index Client index + * @param health The health amount to set + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_health(index, health); + +/** + * Moves a player to the given origin. + * + * @param index Client index + * @param origin Origin to move a player to + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_origin(index, const origin[3]); + +/** + * Sets player's rendering mode. + * + * @note A really useful render modes reference: + * https://sites.google.com/site/svenmanor/rendermodes + * + * @param index Client index + * @param fx Rendering effects. One of kRenderFx* constants + * @param r The amount of red color (0 to 255) + * @param g The amount of green color (0 to 255) + * @param b The amount of blue color (0 to 255) + * @param render Render mode. One of kRender* constants + * @param amount Render amount (0 to 255) + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_rendering(index, fx = kRenderFxNone, r = 0, g = 0, b = 0, render = kRenderNormal, amount = 0); + +/** + * Gets player's rendering mode. + * + * @note A really useful render modes reference: + * https://sites.google.com/site/svenmanor/rendermodes + * + * @param index Client index + * @param fx Variable to store the rendering effect + * @param r Variable to store the amount of red color + * @param g Variable to store the amount of green color + * @param b Variable to store the amount of blue color + * @param render Variable to store the render mode + * @param amount Variable to store the render amount + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native get_user_rendering(index, &fx = kRenderFxNone, &r = 0, &g = 0, &b = 0, &render = kRenderNormal, &amount = 0); + +/** + * Gives an item to a player. + * + * @param index Client index + * @param item Classname of the item to give. Should start with either + * "weapon_", "ammo_", "item_" or "tf_weapon_" + * + * @return Item entity index. If an invalid item name is + * given or the item failed to create, it will return 0. + * If the item was removed, it will return -1 + * @error If player is not connected or not within the range + * of 1 to MaxClients or item creation fails. + */ +native give_item(index, const item[]); + +/** + * Sets (adds, removes) hit zones for a player. + * + * @note This actually sets rules of how any player can hit any other. + * Example: set_user_hitzones(id, target, 2) - makes @id able to + * hit @target only in the head. + * + * @param index Client index + * @param target The target player + * @param body A bitsum of the body parts that can/can't be shot. See HITZONE* constants. + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_hitzones(index = 0, target = 0, body = HITZONES_DEFAULT); + +/** + * Gets the set of hit zone "rules" between @index and @target players. + * + * @note For the body part bitsum, see HITZONE* constants. + * + * @param index Client index + * @param target The target player + * + * @return The bitsum of @target's body parts @index is able to hit + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native get_user_hitzones(index, target); + +/** + * Sets player's maximum movement speed. + * + * @param index Client index + * @param speed The maximum speed player will be able to run at + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_maxspeed(index, Float:speed = -1.0); + +/** + * Gets player's maximum movement speed. + * + * @param index Client index + * + * @return Player's maximum movement speed + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native Float:get_user_maxspeed(index); + +/** + * Sets player's gravity. + * + * @param index Client index + * @param gravity Gravity value to set, 1.0 being normal gravity (800) + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_gravity(index, Float:gravity = 1.0); + +/** + * Gets player's gravity. + * + * @param index Client index + * + * @return Player's gravity value, 1.0 being normal gravity (800) + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native Float:get_user_gravity(index); + +/** + * Spawns an entity. + * + * @param index Entity index + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native spawn(index); + +/** + * Enables or disables player's noclip. + * + * @param index Client index + * @param noclip 1 to enable noclip, 0 to disable + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_noclip(index, noclip = 0); + +/** + * Gets whether a player has noclip enabled or not. + * + * @param index Client index + * + * @return 1 if noclip is enabled, 0 if disabled + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native get_user_noclip(index); + +/** + * Tells whether a player has silent footsteps enabled. + * + * @param index Client index + * + * @return 1 if silent footsteps are enabled, 0 if not + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native get_user_footsteps(index); + +/** + * Enables or disables player's silent footsteps. + * + * @param index Client index + * @param set 1 if player should have silent footsteps, 0 otherwise + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_footsteps(id, set = 1); + +/** + * Strips all weapons from a player, including their knife. + * + * @param index Client index + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native strip_user_weapons(index); + +/** + * Sets player's frags amount. + * + * @param index Client index + * @param frags The amount of frags to set + * + * @noreturn + * @error If player is not connected or not within the range + * of 1 to MaxClients. + */ +native set_user_frags(index, frags); diff --git a/amxmodx/scripting/include/gameconfig.inc b/amxmodx/scripting/include/gameconfig.inc new file mode 100644 index 0000000..d3724e4 --- /dev/null +++ b/amxmodx/scripting/include/gameconfig.inc @@ -0,0 +1,93 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Game Config Functions +// + +#if defined _gameconfigs_included + #endinput +#endif +#define _gameconfigs_included + +enum GameConfig +{ + Invalid_GameConfig = 0 +}; + +/** + * Loads a game config file. + * + * @note The file path must be relative to the 'gamedata' folder under the data folder + * and the extension should be omitted. + * + * @param file File to load + * + * @return A handle to the game config file + */ +native GameConfig:LoadGameConfigFile(const file[]); + +/** + * Returns an offset value. + * + * @param handle Game config handle + * @param key Key to retrieve from the offset section + * + * @return An offset, or -1 on failure + * @error Invalid game config handle + */ +native GameConfGetOffset(GameConfig:handle, const key[]); + +/** + * Returns an offset value given a classname. + * + * @param handle Game config handle + * @param classname Class name to match from the offset section + * @param key Key to retrieve from the offset section + * + * @return An offset, or -1 on failure + * @error Invalid game config handle + */ +native GameConfGetClassOffset(GameConfig:handle, const classname[], const key[]); + +/** + * Gets the value of a key from the "Keys" section. + * + * @param handle Game config handle + * @param key Key to retrieve from the Keys section + * @param buffer Destination string buffer + * @param maxlen Maximum length of output string buffer + * + * @return True if key existed, false otherwise + * @error Invalid game config handle + */ +native bool:GameConfGetKeyValue(GameConfig:handle, const key[], buffer[], maxlen); + +/** + * Finds an address calculation in a GameConfig file. + * + * @param handle Game config handle + * @param name Name of the property to find + * + * @return An address calculated on success, otherwise 0 on failure. + * @error Invalid game config handle + */ +native GameConfGetAddress(GameConfig:handle, const name[]); + +/** + * Destroys a game config and frees its memory. + * + * @note The function automatically sets the variable passed to it to 0 to aid + * in preventing accidental usage after destroy. + * + * @param handle Game config handle + * + * @return 1 on success, 0 if an invalid handle was passed in + */ +native CloseGameConfigFile(&GameConfig:handle); \ No newline at end of file diff --git a/amxmodx/scripting/include/geoip.inc b/amxmodx/scripting/include/geoip.inc new file mode 100644 index 0000000..9bc211f --- /dev/null +++ b/amxmodx/scripting/include/geoip.inc @@ -0,0 +1,264 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// GeoIP Module Functions +// + +#if defined geoip_included + #endinput +#endif +#define _geoip_included + +#pragma reqlib geoip +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib geoip +#endif + +/** + * @global IP addresses passed to these natives can contain ports, the ports will be ignored. + */ + +/** + * Look up the two character country code for a given IP address. + * e.g: "US", "CA", etc. + * + * @param ip The IP address to lookup. + * @param result The result buffer. If the lookup does not succeed, the buffer is not modified. + * + * @return true on a successful lookup, false on a failed lookup. + */ +native bool:geoip_code2_ex(const ip[], result[3]); + +/** + * Look up the three character country code for a given IP address. + * e.g: "USA", "cAN", etc. + * + * @param ip The IP address to lookup. + * @param result The result buffer. If the lookup does not succeed, the buffer is not modified. + * + * @return true on a successful lookup, false on a failed lookup. + */ +native bool:geoip_code3_ex(const ip[], result[4]); + +/** + * Lookup the two character country code for a given IP address. Sets the buffer to "error" on + * an unsuccessful lookup. + * + * @deprecated This native will overflow the buffer by one cell on an unknown ip lookup! + * Use geoip_code2_ex instead. + * + * @param ip The IP address to lookup. + * @param result The result buffer. + * + * @return The result length. + */ +#pragma deprecated Use geoip_code2_ex() instead. +native geoip_code2(const ip[], ccode[3]); + +/** + * Lookup the three character country code for a given IP address. Sets the buffer to "error" on + * an unsuccessful lookup. + * + * @deprecated This native will overflow the buffer by one cell on an unknown ip lookup! + * Use geoip_code3_ex instead. + * + * @param ip The IP address to lookup. + * @param result The result buffer. + * + * @return The result length. + */ +#pragma deprecated Use geoip_code3_ex() instead. +native geoip_code3(const ip[], result[4]); + +/** + * Lookup the full country name for the given IP address. Sets the buffer to "error" on + * an unsuccessful lookup. + * + * @param ip The IP address to lookup. + * @param result The result of the geoip lookup. + * @param len The maximum length of the result buffer. + * + * @return The result length. + */ +#pragma deprecated Use geoip_country_ex() instead. +native geoip_country(const ip[], result[], len = 45); + +/** + * Lookup the full country name for the given IP address. + * + * @param ip The IP address to lookup. + * @param result The result of the geoip lookup. + * @param len The maximum length of the result buffer. + * @param id An optional player's index in order to return the result + * in the player's language, if supported. + * -1: the default language, which is english. + * 0: the server language. You can use LANG_SERVER define. + * >=1: the player's language. + * + * @return The result length on successful lookup, 0 otherwise. + */ +native geoip_country_ex(const ip[], result[], len, id = -1); + +/** + * Look up the full city name for the given IP address. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * @param result The result of the geoip look up. + * @param len The maximum length of the result buffer. + * @param id An optional player's index in order to return the result + * in the player's language, if supported. + * -1: the default language, which is english. + * 0: the server language. You can use LANG_SERVER define. + * >=1: the player's language. + * + * @return The result length on successful lookup, 0 otherwise. + */ +native geoip_city(const ip[], result[], len, id = -1); + +/** + * Look up the region/state code for the given IP address. + * e.g. "US-OH", "DE-HH", IT-82, "FR-U", etc. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * @param result The result of the geoip look up. + * @param len The maximum length of the result buffer. + * + * @return The result length on successful lookup, 0 otherwise. + */ +native geoip_region_code(const ip[], result[], len); + +/** + * Look up the full region/state name for the given IP address. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * @param result The result of the geoip look up. + * @param len The maximum length of the result buffer. + * @param id An optional player's index in order to return the result + * in the player's language, if supported. + * -1: the default language, which is english. + * 0: the server language. You can use LANG_SERVER define. + * >=1: the player's language. + * + * @return The result length on successful lookup, 0 otherwise. + */ +native geoip_region_name(const ip[], result[], len, id = -1); + +/** + * Look up the full time zone for the given IP address. + * e.g. America/Los_Angeles, Europe/Paris. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * @param result The result of the geoip look up. + * @param len The maximum length of the result buffer. + * + * @return The result length on successful lookup, 0 otherwise. + */ +native geoip_timezone(const ip[], result[], len); + +/** + * Look up the city's latitude for the given IP address. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * + * @return The result of the geoip look up, 0 if latitude is not found. + */ +native Float:geoip_latitude(const ip[]); + +/** + * Look up the city's longitude for the given IP address. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * + * @return The result of the geoip look up, 0 if longitude is not found. + */ +native Float:geoip_longitude(const ip[]); + +/** + * Calculate the distance between geographical coordinates, latitude and longitude. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param lat1 The first IP latitude. + * @param lon1 The first IP longitude. + * @param lat2 The second IP latitude. + * @param lon2 The second IP longitude. + * @param system The system of measurement, 0 = Metric(kilometers) or 1 = English(miles). + * + * @return The distance as result in specified system of measurement. + */ +#define SYSTEM_METRIC 0 // kilometers +#define SYSTEM_IMPERIAL 1 // statute miles + +native Float:geoip_distance(Float:lat1, Float:lon1, Float:lat2, Float:lon2, system = SYSTEM_METRIC); + +/** + * Look up the continent code for a given IP address. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * @note The code can be retrieved as integer (See CONTINENT_* constants.) or string (2 characters). + * @note Possible continent codes are AF, AN, AS, EU, NA, OC, SA for + * Africa(1), Antarctica(2), Asia(3), Europe(4), North America(5), Oceania(6), South America(7). + * + * @param ip The IP address to look up. + * @param result The result of the geoip look up. + * + * @return The continent id on successful lookup, 0 otherwise. + */ +enum Continent +{ + CONTINENT_UNKNOWN = 0, + CONTINENT_AFRICA, + CONTINENT_ANTARCTICA, + CONTINENT_ASIA, + CONTINENT_EUROPE, + CONTINENT_NORTH_AMERICA, + CONTINENT_OCEANIA, + CONTINENT_SOUTH_AMERICA, +}; +native Continent:geoip_continent_code(const ip[], result[3]); + +/** + * Look up the full continent name for the given IP address. + * + * @note This native requires GeoIP City database, which can be retrieved from: + * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) + * + * @param ip The IP address to look up. + * @param result The result of the geoip look up. + * @param len The maximum length of the result buffer. + * @param id An optional player's index in order to return the result + * in the player's language, if supported. + * -1: the default language, which is english. + * 0: the server language. You can use LANG_SERVER define. + * >=1: the player's language. + * + * @return The result length on successful lookup, 0 otherwise. + */ +native geoip_continent_name(const ip[], result[], len, id = -1); diff --git a/amxmodx/scripting/include/ham_const.inc b/amxmodx/scripting/include/ham_const.inc new file mode 100644 index 0000000..c21fbc7 --- /dev/null +++ b/amxmodx/scripting/include/ham_const.inc @@ -0,0 +1,4354 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Ham Sandwich Constants +// + +#if defined _ham_const_included + #endinput +#endif +#define _ham_const_included + +/** + * Ham return types. + * + * @note Return these from hooks to disable calling the target function. + * Numbers match up with fakemeta's FMRES_* for clarity. They are + * interchangable. 0 (or no return) is also interpretted as HAM_IGNORED. + */ +#define HAM_IGNORED 1 /**< Calls target function, returns normal value */ +#define HAM_HANDLED 2 /**< Tells the module you did something, still calls target function and returns normal value */ +#define HAM_OVERRIDE 3 /**< Still calls the target function, but returns whatever is set with SetHamReturn*() */ +#define HAM_SUPERCEDE 4 /**< Block the target call, and use your return value (if applicable) (Set with SetHamReturn*()) */ + +/** + * List of virtual functions made available through the hamsandwich module. + * + * @note Not all functions will do as you expect on all mods. If a function does + * not do what you would believe it should DO NOT file a bug report, you + * will be ignored. + * @note Passing invalid parameters has potential to crash the server, so be + * careful, and test carefully and adequately! + * @note All functions take (and pass) a "this" index as the first param. + * This is the entity from which the function is being executed on. + * @note All functions and forwards (eg: {Register,Execute}Ham[B]) require + * the mod to have the pev and base keys in addition to the function + * keys for the corresponding mod/operating system in gamedata + * @note Some functions that return booleans may need to be logically ANDed + * to get the desired results because the mod will return the full integer + * value. E.g.: (ExecuteHam(Ham_TS_IsObjective, this) & 0x0000FFFF) != 0 + */ + +enum Ham +{ + /** + * Description: This is typically called whenever an entity is created. + * It is the virtual equivilent of spawn from the engine. + * Some mods call this on player spawns too. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Spawn, this); + */ + Ham_Spawn = 0, + + /** + * Description: This is typically called on map change. + * This will typically precache all assets required by the entity. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Precache, this); + */ + Ham_Precache, + + /** + * Description: Typically this is similar to an engine keyvalue call. + * Use the kvd natives from fakemeta to handle the kvd_handle passed. + * NOTE: Do not pass handle 0 to this! Use create_kvd() from fakemeta instead! + * Forward params: function(this, kvd_handle); + * Return type: None. + * Execute params: ExecuteHam(Ham_Keyvalue, this, kvd_handle); + */ + Ham_Keyvalue, + + /** + * Description: Returns flags for how an entity can be used. + * Forward params: function(this) + * Return type: Integer (FCAP_* constants, see hlsdk_const.inc). + * Execute params: ExecuteHam(Ham_ObjectCaps, this); + */ + Ham_ObjectCaps, + + /** + * Description: Usually called to activate some objects. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Activate, this); + */ + Ham_Activate, + + /** + * Description: Usually called after the engine call with the same name. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SetObjectCollisionBox, this); + */ + Ham_SetObjectCollisionBox, + + /** + * Description: Returns an integer number that corresponds with what type of entity this is. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_Classify, this); + */ + Ham_Classify, + + /** + * Description: Typically called when an entity dies to notify any children entities about the death. + * Forward params: function(this, idchild) + * Return type: None. + * Execute params: ExecuteHam(Ham_DeathNotice, this, idchild) + */ + Ham_DeathNotice, + + /** + * Description: Usually called whenever an entity gets attacked by a hitscan (such as a gun) weapon. + * Use the get/set tr2 natives in fakemeta to handle the traceresult data. + * Do not use a handle of 0 as a traceresult in execution, use create_tr2() from Fakemeta + * to pass a custom handle instead. (Don't forget to free the handle when you're done.) + * Forward params: function(this, idattacker, Float:damage, Float:direction[3], traceresult, damagebits) + * Return type: None. + * Execute params: ExecuteHam(Ham_TraceAttack, this, idattacker, Float:damage, Float:direction[3], tracehandle, damagebits); + */ + Ham_TraceAttack, + + /** + * Description: Usually called whenever an entity takes any kind of damage. + * Inflictor is the entity that caused the damage (such as a gun). + * Attacker is the entity that tirggered the damage (such as the gun's owner). + * Forward params: function(this, idinflictor, idattacker, Float:damage, damagebits); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_TakeDamage, this, idinflictor, idattacker, Float:damage, damagebits); + */ + Ham_TakeDamage, + + /** + * Description: Usually called whenever an entity gets a form of a heal. + * Forward params: function(this, Float:health, damagebits); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_TakeHealth, this, Float:health, damagebits); + */ + Ham_TakeHealth, + + /** + * Description: Normally called whenever an entity dies. + * For Team Fortress Classic mod, see Ham_TFC_Killed. + * Forward params: function(this, idattacker, shouldgib) + * Return type: None. + * Execute params: ExecuteHam(Ham_Killed, this, idattacker, shouldgib); + */ + Ham_Killed, + + /** + * Description: Normally returns the blood color of the entity. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_BloodColor, this) + */ + Ham_BloodColor, + + /** + * Description: Traces where blood should appear. + * Forward params: function(this, Float:Damage, Float:Direction[3], trace_handle, damagebits); + * Return type: None. + * Execute params: ExecuteHam(Ham_TraceBleed, this, Float:damage, Float:direction[3], trace_handle, damagebits); + */ + Ham_TraceBleed, + + /** + * Description: Returns whether an entity is activated. + * This function is not supported by Day Of Defeat. + * This function has different version for the following mods: + * Team Fortress Classic, see Ham_TFC_IsTriggered instead. + * Sven-Coop 5.0+, see Ham_SC_IsTriggered instead. + * Forward params: function(this, idActivator); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_IsTriggered, this, idActivator); + */ + Ham_IsTriggered, + + /** + * Description: Returns the id of the entity if its class is derived off of CBaseMonster, -1 otherwise. + * Forward params: function(this) + * Return type: Entity. + * Execute params: ExecuteHam(Ham_MyMonsterPointer, this); + */ + Ham_MyMonsterPointer, + + /** + * Description: Returns the id of the entity if its class is derived off of CBaseSquadMonster, -1 otherwise. + * Forward params: function(this) + * Return type: Entity. + * Execute params: ExecuteHam(Ham_MySquadMonsterPointer, this); + */ + Ham_MySquadMonsterPointer, + + /** + * Description: Returns the toggle state of the entity. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_GetToggleState, this); + */ + Ham_GetToggleState, + + /** + * Description: Typically adds points to the entity. + * This function is not supported for the following mods: + * Team Fortress Classic. + * Sven-Coop 5.0-, see Ham_SC_AddPoints instead. + * Forward params: function(this, points, bool:cangonegative); + * Return type: None. + * Execute params: ExecuteHam(Ham_AddPoints, this, points, bool:cangonegative); + */ + Ham_AddPoints, + + /** + * Description: Typically adds points to everybody on the entity's team. + * This function is not supported for the following mods: + * Team Fortress Classic. + * Sven-Coop 5.0-, see Ham_SC_AddPointsToTeam instead. + * Forward params: function(this, points, bool:cangonegative); + * Return type: None. + * Execute params: ExecuteHam(Ham_AddPointsToTeam, this, points, bool:cangonegative); + */ + Ham_AddPointsToTeam, + + /** + * Description: Adds an item to the player's inventory. + * Forward params: function(this, idother); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_AddPlayerItem, this, idother); + */ + Ham_AddPlayerItem, + + /** + * Description: Removes an item to the player's inventory. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_RemovePlayerItem instead. + * Return type: Integer. + * Execute params: ExecuteHam(Ham_RemovePlayerItem, this, idother); + */ + Ham_RemovePlayerItem, + + /** + * Description: Gives ammo to the entity. + * This function is not supported for the following mods: + * Earth's Special Forces. + * Sven-Coop 4.8+, see Ham_SC_GiveAmmo instead. + * Team Fortress Classic, see Ham_TFC_GiveAmmo instead. + * Forward params: function(this, Amount, const Name[], Max) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_GiveAmmo, this, amount, "type", max); + */ + Ham_GiveAmmo, + + /** + * Description: Unsure, I believe this is the delay between activation for an entity. + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_GetDelay, this, Float:output) + */ + Ham_GetDelay, + + /** + * Description: Whether or not the entity is moving. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsMoving instead. + * Forward params: function(this); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_IsMoving, this); + */ + Ham_IsMoving, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_OverrideReset, this) + */ + Ham_OverrideReset, + + /** + * Description: Returns the damage decal of the entity for the damage type. + * Forward params: function(this, damagebits) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_DamageDecal, this); + */ + Ham_DamageDecal, + + /** + * Description: Sets the toggle state of the entity. + * Forward params: function(this, state) + * Return type: None. + * Execute params: ExecuteHam(Ham_SetToggleState, this, state); + */ + Ham_SetToggleState, + + /** + * Description: Not entirely sure what this does. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_StartSneaking, this); + */ + Ham_StartSneaking, + + /** + * Description: Not entirely sure what this does. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_StopSneaking, this); + */ + Ham_StopSneaking, + + /** + * Description: Not entirely sure. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_OnControls instead. + * Forward params: function(this, idOn) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_OnControls, this, idOn); + */ + Ham_OnControls, + + /** + * Description: Whether or not the entity is sneaking. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsSneaking instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_IsSneaking, this); + */ + Ham_IsSneaking, + + /** + * Description: Whether or not the entity is alive. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsAlive instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_IsAlive, this); + */ + Ham_IsAlive, + + /** + * Description: Whether or not the entity uses a BSP model. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsBSPModel instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_IsBSPModel, this); + */ + Ham_IsBSPModel, + + /** + * Description: Whether or not the entity can reflect gauss shots.. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_ReflectGauss instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ReflectGauss, this); + */ + Ham_ReflectGauss, + + /** + * Description: Whether or not the target is the same as the one passed. + * Note the strindex parameter is a string passed that has been allocated by the engine. + * Use fakemeta's EngFunc_SzFromIndex to convert to a normal string, or fakemeta's + * EngFunc_AllocString to create a new string. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_HasTarget instead. + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_HasTarget, this, strindex); + */ + Ham_HasTarget, + + /** + * Description: Whether or not the entity is in the world. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsInWorld instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_IsInWorld, this); + */ + Ham_IsInWorld, + + /** + * Description: Whether or not the entity is a player. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsPlayer instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_IsPlayer, this); + */ + Ham_IsPlayer, + + /** + * Description: Whether or not the entity is a net client. + * This function is not supported for the following mods: + * Sven-Coop 5.0+, see Ham_SC_IsNetClient instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_IsNetClient, this); + */ + Ham_IsNetClient, + + /** + * Description: Get the entity's team id. + * This function is not supported by Team Fortress Classic mod. + * Forward params: function(this); + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_TeamId, this, buffer[], size); + */ + Ham_TeamId, + + /** + * Description: Returns the next target of this. + * Forward params: function(this); + * Return type: Entity. + * Execute params: ExecuteHam(Ham_GetNextTarget, this); + */ + Ham_GetNextTarget, + + /** + * Description: Called whenever an entity thinks. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Think, this); + */ + Ham_Think, + + /** + * Description: Called whenever two entities touch. + * Forward params: function(this, idother); + * Return type: None. + * Execute params: ExecuteHam(Ham_Touch, this, idother); + */ + Ham_Touch, + + /** + * Description: Called whenver one entity uses another. + * Forward params: function(this, idcaller, idactivator, use_type, Float:value) + * Return type: None. + * Execute params: ExecuteHam(Ham_Use, this, idcaller, idactivator, use_type, Float:value); + */ + Ham_Use, + + /** + * Description: Normally called whenever one entity blocks another from moving. + * Forward params: function(this, idother); + * Return type: None. + * Execute params: ExecuteHam(Ham_Blocked, this, idother); + */ + Ham_Blocked, + + /** + * Description: Normally called when a map-based item respawns, such as a health kit or something. + * Forward params: function(this); + * Return type: Entity. + * Execute params: ExecuteHam(Ham_Respawn, this); + */ + Ham_Respawn, + + /** + * Description: Used in Half-Life to update a monster's owner. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_UpdateOwner, this); + */ + Ham_UpdateOwner, + + /** + * Description: Normally called whenever a barnacle grabs the entity. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_FBecomeProne instead. + * Forward params: function(this); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_FBecomeProne, this); + */ + Ham_FBecomeProne, + + /** + * Description: Returns the center of the entity. + * Forward params: function(this); + * Return type: Vector (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_Center, this, Float:output[3]); + */ + Ham_Center, + + /** + * Description: Returns the eye position of the entity. + * Forward params: function(this); + * Return type: Vector (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_EyePosition, this, Float:output[3]); + */ + Ham_EyePosition, + + /** + * Description: Returns the ear position of the entity. + * Forward params: function(this); + * Return type: Vector (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_EarPosition, this, Float:output[3]); + */ + Ham_EarPosition, + + /** + * Description: Position to shoot at. + * Forward params: function(this, Float:srcvector[3]); + * Return type: Vector (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_BodyTarget, Float:srcvector[3], Float:returnvector[3]) + */ + Ham_BodyTarget, + + /** + * Description: Returns the illumination of the entity. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_Illumination, this); + */ + Ham_Illumination, + + /** + * Description: Returns true if a line can be traced from the caller's eyes to the target. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_FVisible instead. + * Forward params: function(this, idOther); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FVisible, this, idOther); + */ + Ham_FVisible, + + /** + * Description: Returns true if a line can be traced from the caller's eyes to given vector. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_FVecVisible instead. + * Forward params: function(this, const Float:origin[3]); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FVecVisible, this, const Float:origin[3]); + */ + Ham_FVecVisible, + + + /** + * Players have all the attributes of normal entities, in addition to these. + */ + + /** + * Description: Typically called every frame when a player has jump held. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Player_Jump, this); + */ + Ham_Player_Jump, + + /** + * Description: Typically called every frame when a player has duck held. + * This function is not supported in Earth's Special Forces mod. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Player_Duck, this); + */ + Ham_Player_Duck, + + /** + * Description: Typically called every frame during PlayerPreThink engine call. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Player_PreThink, this); + */ + Ham_Player_PreThink, + + /** + * Description: Typically called every frame during PlayerPostThink engine call. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Player_PostThink, this); + */ + Ham_Player_PostThink, + + /** + * Description: Returns a vector that tells the gun position. + * This function is not supported by Team Fortress Classic. + * Forward params: function(this) + * Return type: Vector (byreffed in ExecuteHam);. + * Execute params: ExecuteHam(Ham_Player_GetGunPosition, this, Float:output[3]); + */ + Ham_Player_GetGunPosition, + + /** + * Description: Whether or not the player should fade on death. + * Forward param: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Player_ShouldFadeOnDeath, this); + */ + Ham_Player_ShouldFadeOnDeath, + + /** + * Description: Called whenever an impulse command is executed. + * Forward param: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Player_ImpulseComands, this); + */ + Ham_Player_ImpulseCommands, + + /** + * Description: Updates the client's data for hud changes (such as ammo). Usually called every frame. + * This function is not supported by Team Fortress Classic mod. + * Forward param: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Player_UpdateClientData, this); + */ + Ham_Player_UpdateClientData, + + + /** + * Items have all the attributes of normal entities in addition to these. + */ + + /** + * Description: Adds the item to the player. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Item_AddToPlayer instead. + * Forward params: function(this, idPlayer); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_AddToPlayer, this, idPlayer); + */ + Ham_Item_AddToPlayer, + + /** + * Description: Unsure. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Item_AddDuplicate instead. + * Forward params: function(this, idOriginal); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_AddDuplicate, this, idOriginal); + */ + Ham_Item_AddDuplicate, + + /** + * Description: Whether or not this entity can be deployed. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Item_CanDeploy instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_CanDeploy, this); + */ + Ham_Item_CanDeploy, + + /** + * Description: Deploys the entity (usually a weapon). + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Item_Deploy instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_Deploy, this); + */ + Ham_Item_Deploy, + + /** + * Description: Whether or not the entity can be holstered. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Item_CanHolster instead. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_CanHolster, this); + */ + Ham_Item_CanHolster, + + /** + * Description: Whether or not the entity (usually weapon) can be holstered. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_Holster, this); + */ + Ham_Item_Holster, + + /** + * Description: Updates the HUD info about this item. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_UpdateItemInfo, this); + */ + Ham_Item_UpdateItemInfo, + + /** + * Description: Called each frame for an item, normally only on active items. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Item_PreFrame, this); + */ + Ham_Item_PreFrame, + + /** + * Description: Called each frame for an item, normally only on active items. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Item_PostFrame, this); + */ + Ham_Item_PostFrame, + + /** + * Description: Called when an item gets dropped, normally on death only. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Item_Drop, this); + */ + Ham_Item_Drop, + + /** + * Description: Normally called when an item gets deleted. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Item_Kill, this); + */ + Ham_Item_Kill, + + /** + * Description: Called when an entity starts being attached to (normally invisible and "following") a player. + * Forward params: function(this, idPlayer) + * Return type: None. + * Execute params: ExecuteHam(Ham_Item_AttachToPlayer, this, idPlayer) + */ + Ham_Item_AttachToPlayer, + + /** + * Description: Returns the ammo index of the item. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_Item_PrimaryAmmoIndex, this); + */ + Ham_Item_PrimaryAmmoIndex, + + /** + * Description: Returns the secondary ammo index of the item. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_Item_SecondaryAmmoIndex, this); + */ + Ham_Item_SecondaryAmmoIndex, + + /** + * Description: Updates item data for the client. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Item_UpdateClientData instead. + * Forward params: function(this, idPlayer) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_Item_UpdateClientData, this, idPlayer); + */ + Ham_Item_UpdateClientData, + + /** + * Description: Returns the entity index if the item is a weapon, -1 otherwise. + * Forward params: function(this) + * Return type: Entity. + * Execute Params: ExecuteHam(Ham_Item_GetWeaponPtr, this) + */ + Ham_Item_GetWeaponPtr, + + /** + * Description: Returns the item slot for the item. + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_Item_ItemSlot, this) + */ + Ham_Item_ItemSlot, + + + /** + * Weapons have all the attributes to Ham_Item_*, in addition to these. + */ + + /** + * Description: Gets ammo from the target weapon. + * This function is not supported in Earth's Special Forces mod. + * Forward params: function(this, idTarget) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_Weapon_ExtractAmmo, this, idTarget) + */ + Ham_Weapon_ExtractAmmo, + + /** + * Description: Gets clip ammo from the target weapon. + * This function is not supported in Earth's Special Forces mod. + * Forward params: function(this, idTarget) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_Weapon_ExtractAmmo, this, idTarget) + */ + Ham_Weapon_ExtractClipAmmo, + + /** + * Description: Unsure. + * This function is not supported in Earth's Special Forces mod. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Weapon_AddWeapon instead. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Weapon_AddWeapon, this); + */ + Ham_Weapon_AddWeapon, + + /** + * Description: Plays the weapon's empty sound. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Weapon_PlayEmptySound instead. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Weapon_PlayEmptySound, this); + */ + Ham_Weapon_PlayEmptySound, + + /** + * Description: Sets the weapon so that it can play empty sound again. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Weapon_ResetEmptySound, this); + */ + Ham_Weapon_ResetEmptySound, + + /** + * Description: Sends an animation event for the weapon. + * This function has different versions for the following mods: + * Counter-Strike: see Ham_CS_Weapon_SendWeaponAnim. + * Team Fortress Classic: see Ham_TFC_Weapon_SendWeaponAnim. + * Day Of Defeat: see Ham_DOD_Weapon_SendWeaponAnim. + * Forward params: function(this, iAnim, skiplocal, body); + * Return type: None. + * Execute params: ExecuteHam(Ham_Weapon_SendWeaponAnim, this, iAnim, skiplocal, body); + */ + Ham_Weapon_SendWeaponAnim, + + /** + * Description: Whether or not the weapon is usable (has ammo, etc.) + * This function is not supported in Earth's Special Forces mod. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Weapon_IsUsable instead. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Weapon_IsUsable, this) + */ + Ham_Weapon_IsUsable, + + /** + * Description: Called when the main attack of a weapon is triggered. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Weapon_PrimaryAttack, this); + */ + Ham_Weapon_PrimaryAttack, + + /** + * Description: Called when the secondary attack of a weapon is triggered. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Weapon_SecondaryAttack, this); + */ + Ham_Weapon_SecondaryAttack, + + /** + * Description: Called when the weapon is reloaded. + * This function is not supported in Earth's Special Forces mod. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Weapon_Reload, this); + */ + Ham_Weapon_Reload, + + /** + * Description: Displays the idle animation for the weapon. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Weapon_WeaponIdle, this); + */ + Ham_Weapon_WeaponIdle, + + /** + * Description: There is no more ammo for this gun, so switch to the next best one. + * Forward params: function(this) + * Return type: None. + * ExecuteParams: ExecuteHam(Ham_Weapon_RetireWeapon, this) + */ + Ham_Weapon_RetireWeapon, + + /** + * Description: Whether or not the weapon should idle. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Weapon_ShouldWeaponIdle instead. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute Params: ExecuteHam(Ham_Weapon_ShouldWeaponIdle, this) + */ + Ham_Weapon_ShouldWeaponIdle, + + /** + * Description: Unsure. + * This function is not supported by Team Fortress Classic. + * This function has different version for the following mods: + * Sven-Coop 5.0+, see Ham_SC_Weapon_UseDecrement instead. + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Weapon_UseDecrement, this); + */ + Ham_Weapon_UseDecrement, + + + /** + * The following functions are specific to The Specialists. + */ + + /** + * Description: - + * Forward params: function(this, someboolvalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_TS_BreakableRespawn, this, someboolvalue); + */ + Ham_TS_BreakableRespawn, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean) + * Execute params: ExecuteHam(Ham_TS_CanUsedThroughWalls, this); + */ + Ham_TS_CanUsedThroughWalls, + + /** + * Description: Unsure - this was removed in TS 3.0 (and thus is deprecated). + * Forward params: function(this) + * Return type: Integer (I think...) + * Execute params: ExecuteHam(Ham_TS_RespawnWait, this); + */ + Ham_TS_RespawnWait, + + + /** + * The following functions are specific to Counter-Strike. + */ + + /** + * Description: This is called on a map reset for most map based entities. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_CS_Restart, this); + */ + Ham_CS_Restart, + + /** + * Description: Respawn function for players/bots only! Do not use this on non player/bot entities! + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_CS_RoundRespawn, this); + */ + Ham_CS_RoundRespawn, + + /** + * Description: Whether or not the player can drop the specified item. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_CS_Item_CanDrop, this); + */ + Ham_CS_Item_CanDrop, + + /** + * Description: Gets the maximum speed for whenever a player has the item deployed. + * Forward params: function(this); + * Return type: Float (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_CS_Item_GetMaxSpeed, this, Float:output); + */ + Ham_CS_Item_GetMaxSpeed, + + + /** + * The following functions are specific to Day Of Defeat. + */ + + /** + * Description: I assume this spawns players at the start of a new round. + * Forward params: function(this) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_RoundRespawn, this); + */ + Ham_DOD_RoundRespawn, + + /** + * Description: I assume this spawns entities (like func_breakables) at the start of a new round. + * Forward params: function(this) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_RoundRespawnEnt, this); + */ + Ham_DOD_RoundRespawnEnt, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: None, I think... + * Execute params: ExecuteHam(Ham_DOD_RoundStore, this); + */ + Ham_DOD_RoundStore, + + /** + * Description: Unsure. + * Forward params: function(this, someintegervalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_DOD_AreaSetIndex, this, someintegervalue) + */ + Ham_DOD_AreaSetIndex, + + /** + * Description: Unsure. + * Forward params: function(this, idPlayer) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_AreaSendStatus, this, idPlayer); + */ + Ham_DOD_AreaSendStatus, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_GetState, this); + */ + Ham_DOD_GetState, + + /** + * Description: Unsure. + * Forward params: function(this, idtarget) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_GetStateEnt, this, idtarget); + */ + Ham_DOD_GetStateEnt, + + /** + * Description: Whether or not a player can drop this item. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute Params: ExecuteHam(Ham_DOD_Item_CanDrop, this); + */ + Ham_DOD_Item_CanDrop, + + + /** + * The following functions are specific to The Team Fortress Classic. + */ + + /** + * Description: Unsure. + * Forward params: function(this, playerId) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_TFC_EngineerUse, this, playerId) + */ + Ham_TFC_EngineerUse, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_Finished, this); + */ + Ham_TFC_Finished, + + /** + * Description: Unsure. + * Forward params: function(this, grenId, Float:damage, Float:radius) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_EmpExplode, this, grenId, Float:damage, Float:radius) + */ + Ham_TFC_EmpExplode, + + /** + * Description: Unsure. + * 'damage' and 'radius' are byref'd in ExecuteHam. + * Forward params: function(this, Float:damage, Float:radius) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_CalcEmpDmgRad, this, Float:damage, Float:radius) + */ + Ham_TFC_CalcEmpDmgRad, + + /** + * Description: Unsure. + * Forward params: function(this, grenId) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_TakeEmpBlast, this, grenId); + */ + Ham_TFC_TakeEmpBlast, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_EmpRemove, this); + */ + Ham_TFC_EmpRemove, + + /** + * Description: Unsure. + * Forward params: function(this, grenId, Float:bounceMax) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_TakeConcussionBlast, this, grenId, Float:bounceMax); + */ + Ham_TFC_TakeConcussionBlast, + + /** + * Description: Unsure. + * Forward params: function(this, grenId) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_Concuss, this, grenId); + */ + Ham_TFC_Concuss, + + + /** + * The following functions are specific to Earth's Special Forces. + */ + + /** + * Description: Unsure. + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsEnvModel, this); + */ + Ham_ESF_IsEnvModel, + + /** + * Description: Unsure. + * This is available only in ESF Open Beta. + * Forward params: function(this, entityida, entityidb, Float:floata, Float:floatb, dmgbits) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ESF_TakeDamage2, this, entityida, entityidb, Float:floata, Float:floatb, dmgbits); + */ + Ham_ESF_TakeDamage2, + + + /** + * The following functions are specific to Natural Selection. + */ + + /** + * Description: Returns how many points each entity is worth. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_NS_GetPointValue, this); + */ + Ham_NS_GetPointValue, + + /** + * Description: Unsure. Probably awards this with the killing of idvictim. + * Forward params: function(this, idvictim) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_AwardKill, this, idvictim); + */ + Ham_NS_AwardKill, + + /** + * Description: Unsure, probably whenever an entity resets after a new round. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_ResetEntity, this); + */ + Ham_NS_ResetEntity, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_UpdateOnRemove, this) + */ + Ham_NS_UpdateOnRemove, + + + /** + * The following functions are specific to The Specialists. + */ + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_TS_GiveSlowMul, this) + */ + Ham_TS_GiveSlowMul, + + /** + * Description: Unsure. The second paramater is actually a char. + * Forward params: function(this, Float:someval, someotherval) + * Return type: None. + * Execute params: ExecuteHam(Ham_TS_GoSlow, this, Float:someval, someotherval) + */ + Ham_TS_GoSlow, + + /** + * Description: Probably returns true if the user is in slow mo. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_TS_InSlow, this) + */ + Ham_TS_InSlow, + + /** + * Description: Returns true if the entity is an objective. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_TS_IsObjective, this) + */ + Ham_TS_IsObjective, + + /** + * Description: Unsure. + * Forward params: function(this, bool:someval) + * Return type: None. + * Execute params: ExecuteHam(Ham_TS_EnableObjective, this, bool:someval) + */ + Ham_TS_EnableObjective, + + /** + * Description: Probably called when the engine call to OnEntFreePrivateData is called (the entity destructor.) + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_TS_OnEntFreePrivateData, this) + */ + Ham_TS_OnFreeEntPrivateData, + + /** + * Description: Probably called when the engine call to ShouldCollide is called. + * Forward params: function(this, otherEntity) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_TS_ShouldCollide, this, otherEntity) + */ + Ham_TS_ShouldCollide, + + + /** + * LATE ADDITIONS (2011) + */ + + /** + * Description: Turns a monster towards its ideal_yaw. + * Forward params: function(this, speed); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ChangeYaw, this, speed); + */ + Ham_ChangeYaw, + + /** + * Description: Returns if monster has human gibs. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_HasHumanGibs, this); + */ + Ham_HasHumanGibs, + + /** + * Description: Returns if monster has alien gibs. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_HasAlienGibs, this); + */ + Ham_HasAlienGibs, + + /** + * Description: Slowly fades a entity out, then removes it. + * Using this on player will crash your server. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_FadeMonster, this); + */ + Ham_FadeMonster, + + /** + * Description: Create some gore and get rid of a monster's model. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_GibMonster, this); + */ + Ham_GibMonster, + + /** + * Description: Called when monster dies and prepares its entity to become a corpse. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_BecomeDead, this); + */ + Ham_BecomeDead, + + /** + * Description: Checks relation ship between two monsters. + * Forward params: function(this, idother); + * Return type: Integer (R_* constants, see HLDSK). + * Execute params: ExecuteHam(Ham_IRelationship, this, idother); + */ + Ham_IRelationship, + + /** + * Description: Called when monster is about to emit pain sound. + * Not guaranteed to actually emit sound. (random, time, etc..) + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_PainSound, this); + */ + Ham_PainSound, + + /** + * Description: Prints debug information about monster to console. (state, activity, and other) + * This function is called by impulse 103. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_ReportAIState, this); + */ + Ham_ReportAIState, + + /** + * Description: Called when monster has died. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_MonsterInitDead, this); + */ + Ham_MonsterInitDead, + + /** + * Description: Function to find enemies or food by sight. + * distance is maximum distance (in units) monster can see. + * Forward params: function(this, distance); + * Return type: None. + * Execute params: ExecuteHam(Ham_Look, this, distance); + */ + Ham_Look, + + /** + * Description: This functions searches the link list whose head is the caller's m_pLink field. + * Forward params: function(this); + * Return type: Integer (entity). + * Execute params: ExecuteHam(Ham_BestVisibleEnemy, this); + */ + Ham_BestVisibleEnemy, + + /** + * Description: Returns true if the passed ent is in the caller's forward view cone. + * The dot product is performed in 2d, making the view cone infinitely tall. + * Forward params: function(this, idOther); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FInViewCone, this, idOther); + */ + Ham_FInViewCone, + + /** + * Description: Returns true if the passed ent is in the caller's forward view cone. + * The dot product is performed in 2d, making the view cone infinitely tall. + * Forward params: function(this, const Float:origin[3]); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FVecInViewCone, this, const Float:origin[3]); + */ + Ham_FVecInViewCone, + + /** + * Description: Determines the best type of death animation to play. + * Forward params: function(this); + * Return type: Integer (ACT_* constants, see HLDSK. It might different depending the mod). + * Execute params: ExecuteHam(Ham_GetDeathActivity, this); + */ + Ham_GetDeathActivity, + + + /** + * The following functions are not supported by Counter-Strike, The Specialists and Natural Selection mods + */ + + /** + * Description: Runs core AI functions. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_RunAI, this); + */ + Ham_RunAI, + + /** + * Description: Calls out to core AI functions and handles this monster's specific animation events. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_MonsterThink, this); + */ + Ham_MonsterThink, + + /** + * Description: After a monster is spawned, it needs to be dropped into the world, checked for mobility problems + * and put on the proper path, if any. This function does all of those things after the monster spawns. + * Any initialization that should take place for all monsters goes here. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_MonsterInit, this); + */ + Ham_MonsterInit, + + /** + * Description: Check validity of a straight move through space. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, const Float:start[3], const Float:end[3], target, Float:dist) + * Return type: Integer (See LOCALMOVE_* constants). + * Execute params: ExecuteHam(Ham_CheckLocalMove, this, const Float:start[3], const Float:end[3], target, Float:dist); + */ + Ham_CheckLocalMove, + + /** + * Description: Takes a single step towards the next ROUTE location. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:interval) + * Return type: None. + * Execute params: ExecuteHam(Ham_Move, this, Float:interval); + */ + Ham_Move, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, targetEnt, const Float:dir[3], Float:interval) + * Return type: None. + * Execute params: ExecuteHam(Ham_MoveExecute, this, targetEnt, const Float:dir[3], Float:interval); + */ + Ham_MoveExecute, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:waypointDist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ShouldAdvanceRoute, this, Float:waypointDist); + */ + Ham_ShouldAdvanceRoute, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this) + * Return type: Integer (ACT_* constants, see HLDSK. It might different depending the mod). + * Execute params: ExecuteHam(Ham_GetStoppedActivity, this); + */ + Ham_GetStoppedActivity, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_Stop, this); + */ + Ham_Stop, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CheckRangeAttack1, this, Float:dot, Float:dist); + */ + Ham_CheckRangeAttack1, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CheckRangeAttack2, this, Float:dot, Float:dist); + */ + Ham_CheckRangeAttack2, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CheckMeleeAttack1, this, Float:dot, Float:dist); + */ + Ham_CheckMeleeAttack1, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CheckMeleeAttack2, this, Float:dot, Float:dist); + */ + Ham_CheckMeleeAttack2, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: None. + * Execute params: ExecuteHam(Ham_ScheduleChange, this, Float:dot, Float:dist); + */ + Ham_ScheduleChange, + + /** + * Description: Determines whether or not the monster can play the scripted sequence or AI sequence that is + * trying to possess it. If DisregardState is set, the monster will be sucked into the script + * no matter what state it is in. ONLY Scripted AI ents should allow this. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * This function has different versions for the following mod: + * Sven Coop: see Ham_SC_CanPlaySequence + * Forward params: function(this, bool:disregardState, interruptLevel); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CanPlaySequence, this, bool:disregardState, interruptLevel); + */ + Ham_CanPlaySequence, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * This function has different versions for the following mod: + * Sven Coop: see Ham_SC_CanPlaySentence2 + * Forward params: function(this, bool:disregardState); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CanPlaySentence2, this, bool:disregardState); + */ + Ham_CanPlaySentence2, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, const sentence[], Float:duration, Float:volume, Float:attenuation); + * Return type: None. + * Execute params: ExecuteHam(Ham_PlaySentence, this, const sentence[], Float:duration, Float:volume, Float:attenuation); + */ + Ham_PlaySentence, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * This function has different version for Sven Coop, see Ham_SC_PlayScriptedSentence instead. + * Forward params: function(this, const sentence[], Float:duration, Float:volume, Float:attenuation, bool:concurrent, idListener); + * Return type: None. + * Execute params: ExecuteHam(Ham_PlayScriptedSentence, this, const sentence[], Float:duration, Float:volume, Float:attenuation, bool:concurrent, idListener); + */ + Ham_PlayScriptedSentence, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SentenceStop, this); + */ + Ham_SentenceStop, + + /** + * Description: Surveys the Conditions information available and finds the best new state for a monster. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Integer (MONSTERSTATE_* constants, see HLDSK). + * Execute params: ExecuteHam(Ham_GetIdealState, this); + */ + Ham_GetIdealState, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, newActivity); + * Return type: None. + * Execute params: ExecuteHam(Ham_SetActivity, this, newActivity); + */ + Ham_SetActivity, + + /** + * Description: Part of the condition collection process gets and stores data and conditions + * pertaining to a monster's enemy. Returns TRUE if Enemy LKP was updated. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, idEnemy); + * Return type: None. + * Execute params: ExecuteHam(Ham_CheckEnemy, this, idEnemy); + */ + Ham_CheckEnemy, + + /** + * Description: Tries to overcome local obstacles by triangulating a path around them. + * 'dist' is how far the obstruction that we are trying to triangulate around is from the monster. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, const Float:start[3], const Float:end[3], Float:dist, targetEnt, Float:apex[3]); + * Return type: None. + * Execute params: ExecuteHam(Ham_FTriangulate, this, const Float:start[3], const Float:end[3], Float:dist, targetEnt, Float:apex[3]); + */ + Ham_FTriangulate, + + /** + * Description: Allows each sequence to have a different turn rate associated with it. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SetYawSpeed, this); + */ + Ham_SetYawSpeed, + + /** + * Description: Tries to build a route as close to the target as possible, even if there isn't a path to the final point. + * If supplied, search will return a node at least as far away as MinDist from vecThreat, but no farther than minDist. + * If maxDist isn't supplied, it defaults to a reasonable value. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_BuildNearestRoute, this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist); + */ + Ham_BuildNearestRoute, + + /** + * Description: Tries to find a nearby node that will hide the caller from its enemy. + * If supplied, search will return a node at least as far away as MinDist from vecThreat, but no farther than minDist. + * If maxDist isn't supplied, it defaults to a reasonable value. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FindCover, this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist); + */ + Ham_FindCover, + + /** + * Description: Default cover radius. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Float. + * Execute params: ExecuteHam(Ham_CoverRadius, this); + */ + Ham_CoverRadius, + + /** + * Description: Prequalifies a monster to do more fine checking of potential attacks. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FCanCheckAttacks, this); + */ + Ham_FCanCheckAttacks, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_CheckAmmo, this); + */ + Ham_CheckAmmo, + + /** + * Description: Before a set of conditions is allowed to interrupt a monster's schedule, this function removes + * conditions that we have flagged to interrupt the current schedule, but may not want to interrupt + * the schedule every time. (Pain, for instance) + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_IgnoreConditions, this); + */ + Ham_IgnoreConditions, + + /** + * Description: Tells use whether or not the monster cares about the type of Hint Node given. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, hint); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FValidateHintType, this, hint); + */ + Ham_FValidateHintType, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_FValidateHintType, this); + */ + Ham_FCanActiveIdle, + + /** + * Description: Returns a bit mask indicating which types of sounds this monster regards. + * In the base class implementation, monsters care about all sounds, but no scents. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ISoundMask, this); + */ + Ham_ISoundMask, + + /** + * Description: - + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Float. + * Execute params: ExecuteHam(Ham_HearingSensitivity, this); + */ + Ham_HearingSensitivity, + + /** + * Description: Called by Barnacle victims when the barnacle pulls their head into its mouth. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this, idBarnacle); + * Return type: Float. + * Execute params: ExecuteHam(Ham_BarnacleVictimBitten, this, idBarnacle); + */ + Ham_BarnacleVictimBitten, + + /** + * Description: Called by barnacle victims when the host barnacle is killed. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: Float. + * Execute params: ExecuteHam(Ham_BarnacleVictimReleased, this); + */ + Ham_BarnacleVictimReleased, + + /** + * Description: Runs after conditions are collected and before scheduling code is run. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_PrescheduleThink, this); + */ + Ham_PrescheduleThink, + + /** + * Description: Plays death sounds. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_DeathSound, this); + */ + Ham_DeathSound, + + /** + * Description: Plays alert sounds. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_AlertSound, this); + */ + Ham_AlertSound, + + /** + * Description: Plays idle sounds. + * This function is not supported by Counter-Strike, The Specialists and Natural Selection mods. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_IdleSound, this); + */ + Ham_IdleSound, + + /** + * Description: This should stop a monster following a target. + * Forward params: function(this, bool:clearSchedule) + * Return type: None. + * Execute Params: ExecuteHam(Ham_StopFollowing, this, bool:clearSchedule); + */ + Ham_StopFollowing, + + + /** + * The following functions are specific to Counter-Strike. + */ + + /** + * Description: Sends an animation event for the weapon. skiplocal is 1 if client is predicting weapon animations. + * Forward params: function(this, anim, skiplocal); + * Return type: None. + * Execute params: ExecuteHam(Ham_CS_Weapon_SendWeaponAnim, this, anim, skiplocal); + */ + Ham_CS_Weapon_SendWeaponAnim, + + /** + * Description: Resets the player's max speed. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_CS_Player_ResetMaxSpeed, this); + */ + Ham_CS_Player_ResetMaxSpeed, + + /** + * Description: Whether or not the player is a bot. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CS_Player_IsBot, this); + */ + Ham_CS_Player_IsBot, + + /** + * Description: Returns a vector that tells the autoaim direction. + * Set crosshair position to point to enemey if sv_aim is 1. + * Forward params: function(this, Float:delta) + * Return type: Vector, byreffed in execute. + * Execute params: ExecuteHam(Ham_CS_Player_GetAutoaimVector, this, Float:delta, Float:output[3]); + */ + Ham_CS_Player_GetAutoaimVector, + + /** + * Description: Whether or not the player is being flashing. (flashbang grenade explosion) + * blindTime is the time you are considered as being blind. (holdTime * 0.33). + * Forward params: function(this, Float:blindTime, Float:duration, Float:holdTime, alpha); + * Return type: None. + * Execute params: ExecuteHam(Ham_CS_Player_Blind, this, Float:blindTime, Float:duration, Float:holdTime, alpha); + */ + Ham_CS_Player_Blind, + + /** + * Description: Whether or not the player is touching a weapon on the ground. + * Forward params: function(this, entityid); + * Return type: None. + * Execute params: ExecuteHam(Ham_CS_Player_OnTouchingWeapon, this, entityid); + */ + Ham_CS_Player_OnTouchingWeapon, + + + /** + * The following functions are specific to Day Of Defeat. + */ + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_SetScriptReset, this); + */ + Ham_DOD_SetScriptReset, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_Item_SpawnDeploy, this); + */ + Ham_DOD_Item_SpawnDeploy, + + /** + * Description: - + * Forward params: function(this, Float:someValue) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_Item_SetDmgTime, this, Float:someValue); + */ + Ham_DOD_Item_SetDmgTime, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_Item_DropGren, this); + */ + Ham_DOD_Item_DropGren, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute Params: ExecuteHam(Ham_DOD_Weapon_IsUseable, this); + */ + Ham_DOD_Weapon_IsUseable, + + /** + * Description: - + * Forward params: function(this, Float:accuracyFactor, idother, shared_rand) + * Return type: Vector, byreffed in execute. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_Aim, this, Float:accuracyFactor, idother, shared_rand, Float:output[3]); + */ + Ham_DOD_Weapon_Aim, + + /** + * Description: - + * Forward params: function(this, Float:accuracyFactor, idother) + * Return type: Float. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_flAim, this, Float:accuracyFactor, idother); + */ + Ham_DOD_Weapon_flAim, + + /** + * Description: - + * Forward params: function(this, Float:amount, targetEnt) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_RemoveStamina, this, Float:amount, targetEnt); + */ + Ham_DOD_Weapon_RemoveStamina, + + /** + * Description: - + * Forward params: function(this, fov) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_ChangeFOV, this, fov); + */ + Ham_DOD_Weapon_ChangeFOV, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_ZoomOut, this); + */ + Ham_DOD_Weapon_ZoomOut, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_ZoomIn, this); + */ + Ham_DOD_Weapon_ZoomIn, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_GetFOV, this); + */ + Ham_DOD_Weapon_GetFOV, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute Params: ExecuteHam(Ham_DOD_Weapon_IsWaterSniping, this); + */ + Ham_DOD_Weapon_PlayerIsWaterSniping, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_UpdateZoomSpeed, this); + */ + Ham_DOD_Weapon_UpdateZoomSpeed, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute Params: ExecuteHam(Ham_DOD_Weapon_Special, this); + */ + Ham_DOD_Weapon_Special, + + + /** + * The following functions are specific to Team Fortress Classic. + */ + + /** + * Description: Get the item name. + * Forward params: function(this, const buffer[]); + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_TFC_DB_GetItemName, this, buffer[], size); + */ + Ham_TFC_DB_GetItemName, + + /** + * Description: This entity is exploding, or otherwise needs to inflict damage upon entities within a certain range. + * Forward params: function(this, inflictorId, attackerId, Float:damage, classIgnore, bitsDamageType) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_RadiusDamage, this, inflictorId, attackerId, Float:damage, classIgnore, bitsDamageType); + */ + Ham_TFC_RadiusDamage, + + /** + * Description: This entity is exploding, or otherwise needs to inflict damage upon entities within a certain range. + * Forward params: function(this, const Float:source[3], inflictorId, attackerId, Float:damage, classIgnore, bitsDamageType) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_RadiusDamage2, this, const Float:source[3], inflictorId, attackerId, Float:damage, classIgnore, bitsDamageType); + */ + Ham_TFC_RadiusDamage2, + + + /** + * The following functions are specific to Earth's Special Forces. + */ + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsFighter, this); + */ + Ham_ESF_IsFighter, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsBuddy, this); + */ + Ham_ESF_IsBuddy, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, const char sample[], somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_EmitSound, this, const sample[], somevalue); + */ + Ham_ESF_EmitSound, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_EmitNullSound, this, somevalue); + */ + Ham_ESF_EmitNullSound, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, someentid, somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_IncreaseStrength, this, someentid, somevalue); + */ + Ham_ESF_IncreaseStrength, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_IncreasePL, this, somevalue); + */ + Ham_ESF_IncreasePL, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetPowerLevel, this, somevalue); + */ + Ham_ESF_SetPowerLevel, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetMaxPowerLevel, this, somevalue); + */ + Ham_ESF_SetMaxPowerLevel, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, anim) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StopAniTrigger, this, anim); + */ + Ham_ESF_StopAniTrigger, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StopFly, this); + */ + Ham_ESF_StopFly, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_HideWeapon, this); + */ + Ham_ESF_HideWeapon, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_HideWeapon, this, somevalue); + */ + Ham_ESF_ClientRemoveWeapon, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, const model[]) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SendClientsCustomModel, this, const model[]); + */ + Ham_ESF_SendClientsCustomModel, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanTurbo, this); + */ + Ham_ESF_CanTurbo, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanPrimaryFire, this); + */ + Ham_ESF_CanPrimaryFire, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanSecondaryFire, this); + */ + Ham_ESF_CanSecondaryFire, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanStopFly, this); + */ + Ham_ESF_CanStopFly, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanBlock, this); + */ + Ham_ESF_CanBlock, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanRaiseKi, this); + */ + Ham_ESF_CanRaiseKi, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanRaiseStamina, this); + */ + Ham_ESF_CanRaiseStamina, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanTeleport, this); + */ + Ham_ESF_CanTeleport, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanStartFly, this); + */ + Ham_ESF_CanStartFly, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanStartPowerup, this); + */ + Ham_ESF_CanStartPowerup, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanJump, this); + */ + Ham_ESF_CanJump, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_CanWallJump, this); + */ + Ham_ESF_CanWallJump, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsSuperJump, this); + */ + Ham_ESF_IsSuperJump, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsMoveBack, this); + */ + Ham_ESF_IsMoveBack, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ESF_CheckWallJump, this); + */ + Ham_ESF_CheckWallJump, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, const Float:somevalue[3]) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_EnableWallJump, this, const Float:somevalue[3]); + */ + Ham_ESF_EnableWallJump, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_DisableWallJump, this); + */ + Ham_ESF_DisableWallJump, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_ResetWallJumpVars, this); + */ + Ham_ESF_ResetWallJumpVars, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, const value[], const Float:somevalue[3], const someothervalue[]) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_GetWallJumpAnim, const value[], const Float:somevalue[3], const someothervalue[]); + */ + Ham_ESF_GetWallJumpAnim, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, const somevalue[], const someothervalue[]) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_GetWallJumpAnim2, this, const somevalue[], const someothervalue[]); + */ + Ham_ESF_GetWallJumpAnim2, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetFlyMoveType, this); + */ + Ham_ESF_SetWallJumpAnimation, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetFlyMoveType, this); + */ + Ham_ESF_SetFlyMoveType, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsFlyMoveType, this); + */ + Ham_ESF_IsFlyMoveType, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_IsWalkMoveType, this); + */ + Ham_ESF_IsWalkMoveType, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetWalkMoveType, this); + */ + Ham_ESF_SetWalkMoveType, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_DrawChargeBar, this, somevalue); + */ + Ham_ESF_DrawChargeBar, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StartBlock, this); + */ + Ham_ESF_StartBlock, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StopBlock, this); + */ + Ham_ESF_StopBlock, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StartFly, this); + */ + Ham_ESF_StartFly, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, Float:value) + * Return type: Float. + * Execute params: ExecuteHam(Ham_ESF_GetMaxSpeed, this, Float:value); + */ + Ham_ESF_GetMaxSpeed, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, anim) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetAnimation, this, anim); + */ + Ham_ESF_SetAnimation, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_PlayAnimation, this); + */ + Ham_ESF_PlayAnimation, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ESF_GetMoveForward, this); + */ + Ham_ESF_GetMoveForward, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ESF_GetMoveRight, this); + */ + Ham_ESF_GetMoveRight, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ESF_GetMoveUp, this); + */ + Ham_ESF_GetMoveUp, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_AddBlindFX, this); + */ + Ham_ESF_AddBlindFX, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_RemoveBlindFX, this); + */ + Ham_ESF_RemoveBlindFX, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_DisablePSBar, this); + */ + Ham_ESF_DisablePSBar, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_AddBeamBoxCrosshair, this, somevalue); + */ + Ham_ESF_AddBeamBoxCrosshair, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_RemoveBeamBoxCrosshair, this); + */ + Ham_ESF_RemoveBeamBoxCrosshair, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_DrawPSWinBonus, this); + */ + Ham_ESF_DrawPSWinBonus, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, Float:value, Float:othervalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_DrawPSBar, this, Float:value, Float:othervalue); + */ + Ham_ESF_DrawPSBar, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_LockCrosshair, this); + */ + Ham_ESF_LockCrosshair, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_UnLockCrosshair, this); + */ + Ham_ESF_UnLockCrosshair, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_RotateCrosshair, this); + */ + Ham_ESF_RotateCrosshair, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_UnRotateCrosshair, this); + */ + Ham_ESF_UnRotateCrosshair, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_WaterMove, this); + */ + Ham_ESF_WaterMove, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_CheckTimeBasedDamage, this); + */ + Ham_ESF_CheckTimeBasedDamage, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_DoesSecondaryAttack, this); + */ + Ham_ESF_DoesSecondaryAttack, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_ESF_DoesPrimaryAttack, this); + */ + Ham_ESF_DoesPrimaryAttack, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_RemoveSpecialModes, this); + */ + Ham_ESF_RemoveSpecialModes, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StopTurbo, this); + */ + Ham_ESF_StopTurbo, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_TakeBean, this); + */ + Ham_ESF_TakeBean, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_GetPowerLevel, this); + */ + Ham_ESF_GetPowerLevel, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_RemoveAllOtherWeapons, this); + */ + Ham_ESF_RemoveAllOtherWeapons, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_StopSwoop, this); + */ + Ham_ESF_StopSwoop, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetDeathAnimation, this); + */ + Ham_ESF_SetDeathAnimation, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_SetModel, this); + */ + Ham_ESF_SetModel, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_AddAttacks, this); + */ + Ham_ESF_AddAttacks, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this, const value[], const othervalue[], somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_EmitClassSound, this, const value[], const othervalue[], somevalue); + */ + Ham_ESF_EmitClassSound, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_CheckLightning, this); + */ + Ham_ESF_CheckLightning, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_FreezeControls, this); + */ + Ham_ESF_FreezeControls, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_UnFreezeControls, this); + */ + Ham_ESF_UnFreezeControls, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_UpdateKi, this); + */ + Ham_ESF_UpdateKi, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_ESF_UpdateHealth, this); + */ + Ham_ESF_UpdateHealth, + + /** + * Description: - + * This is available only in ESF Open Beta. + * Forward params: function(this) + * Return type: Vector. + * Execute params: ExecuteHam(Ham_ESF_GetTeleportDir, this, output[3]); + */ + Ham_ESF_GetTeleportDir, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_ESF_Weapon_HolsterMeleed, this); + */ + Ham_ESF_Weapon_HolsterWhenMeleed, + + + /** + * The following functions are specific to Natural Selection. + */ + + /** + * Description: - + * Forward params: function(this, controller, Float:value) + * Return type: Float. + * Execute params: ExecuteHam(Ham_SetBoneController, this, controller, Float:value) + */ + Ham_NS_SetBoneController, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_SaveDataForReset, this) + */ + Ham_NS_SaveDataForReset, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_NS_GetHull, this) + */ + Ham_NS_GetHull, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_NS_GetMaxWalkSpeed, this) + */ + Ham_NS_GetMaxWalkSpeed, + + /** + * Description: - + * Forward params: function(this, const teamID[]) + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_NS_SetTeamID, this, const teamID[]) + */ + Ham_NS_SetTeamID, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_NS_GetPlayerClass, this) + */ + Ham_NS_GetEffectivePlayerClass, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_NS_GetAuthenticationMask, this) + */ + Ham_NS_GetAuthenticationMask, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_EffectivePlayerClassChanged, this) + */ + Ham_NS_EffectivePlayerClassChanged, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_NeedsTeamUpdate, this) + */ + Ham_NS_NeedsTeamUpdate, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_SendTeamUpdate, this) + */ + Ham_NS_SendTeamUpdate, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_SendWeaponUpdate, this) + */ + Ham_NS_SendWeaponUpdate, + + /** + * Description: - + * Forward params: function(this, idOther) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_InitPlayerFromSpawn, this, idOther) + */ + Ham_NS_InitPlayerFromSpawn, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_PackDeadPlayerItems, this) + */ + Ham_NS_PackDeadPlayerItems, + + /** + * Description: Gets sequence name based on index. + * animationName are passed by reference in ExecuteHam. outputLength is the max output length. + * Forward params: function(this, activity, const animationName[], bool:somevalue) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_GetAnimationForActivity, this, activity, output[], bool:somevalue, outputLength) + */ + Ham_NS_GetAnimationForActivity, + + /** + * Description: - + * Forward params: function(this, const Float:position[3], const Float:viewAngles[3]) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_StartObserver, this, const Float:position[3], const Float:viewAngles[3]) + */ + Ham_NS_StartObserver, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_StopObserver, this) + */ + Ham_NS_StopObserver, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_NS_GetAdrenalineFactor, this) + */ + Ham_NS_GetAdrenalineFactor, + + /** + * Description: - + * Forward params: function(this, const name[], bool:showpickup)) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_GiveNamedItem, this, const name[], bool:showpickup) + */ + Ham_NS_GiveNamedItem, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_Suicide, this) + */ + Ham_NS_Suicide, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_NS_GetCanUseWeapon, this) + */ + Ham_NS_GetCanUseWeapon, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_NS_Weapon_GetWeapPrimeTime, this) + */ + Ham_NS_Weapon_GetWeaponPrimeTime, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_NS_Weapon_PrimeWeapon, this) + */ + Ham_NS_Weapon_PrimeWeapon, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_NS_Weapon_GetIsWeaponPrimed, this) + */ + Ham_NS_Weapon_GetIsWeaponPrimed, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_NS_Weapon_GetIsWeapPriming, this) + */ + Ham_NS_Weapon_GetIsWeaponPriming, + + /** + * Description: - + * Forward params: function(this, const viewModel[], const weaponModel[], anim, const animExt[], skiplocal, body) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_NS_Weapon_DefaultDeploy, this, const viewModel[], const weaponModel[], anim, const animExt[], skiplocal, body) + */ + Ham_NS_Weapon_DefaultDeploy, + + /** + * Description: - + * Forward params: function(this, clipsize, anim, Float:delay, body) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_NS_Weapon_DefaultReload, this, clipsize, anim, Float:delay, body) + */ + Ham_NS_Weapon_DefaultReload, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_NS_Weapon_GetDeployTime, this) + */ + Ham_NS_Weapon_GetDeployTime, + + + /** + * The following functions are specific to Sven Co-op. + */ + + /** + * Description: Returns the type of group (i.e, "houndeye", or "human military" + * so that monsters with different classnames still realize that they are teammates. + * (overridden for monsters that form groups) + * Classes list: + * CLASS_NONE 0 + * CLASS_MACHINE 1 + * CLASS_PLAYER 2 + * CLASS_HUMAN_PASSIVE 3 + * CLASS_HUMAN_MILITARY 4 + * CLASS_ALIEN_MILITARY 5 + * CLASS_ALIEN_PASSIVE 6 + * CLASS_ALIEN_MONSTER 7 + * CLASS_ALIEN_PREY 8 + * CLASS_ALIEN_PREDATOR 9 + * CLASS_INSECT 10 + * CLASS_PLAYER_ALLY 11 + * CLASS_PLAYER_BIOWEAPON 12 + * CLASS_ALIEN_BIOWEAPON 13 + * CLASS_XRACE_PITDRONE 14 + * CLASS_XRACE_SHOCK 15 + * CLASS_BARNACLE 99 + * Forward params: function(this, class) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_GetClassification, this, class) + */ + Ham_SC_GetClassification, + + /** + * Description: Whether entity is a monter. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsMonster, this) + */ + Ham_SC_IsMonster, + + /** + * Description: (!) This function is no more available in the mod. + * Whether entity uses PhysX feature. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsPhysX, this) + */ + Ham_SC_IsPhysX, + + /** + * Description: Whether this is a point entity. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsPointEntity, this) + */ + Ham_SC_IsPointEntity, + + /** + * Description: Whether entity is a machine. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsMachine, this) + */ + Ham_SC_IsMachine, + + /** + * Description: Removes the entity and all its content in critical situation. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CriticalRemove, this) + */ + Ham_SC_CriticalRemove, + + /** + * Description: Updates global tables that need to know about entities being removed. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(UpdateOnRemove, this) + */ + Ham_SC_UpdateOnRemove, + + /** + * Description: Returns true if a line can be traced from the caller's eyes to the target vector. + * Forward params: function(this, entity, bool:ignoreGlass) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FVisible, this, entity, bool:ignoreGlass) + */ + Ham_SC_FVisible, + + /** + * Description: Returns true if a line can be traced from the given point to the target point. + * Forward params: function(this, const Float:target[3], const Float:start[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FVisibleFromPos, this, const Float:target[3], const Float:start[3]) + */ + Ham_SC_FVisibleFromPos, + + /** + * Description: Returns true if passed in entity is facing current entity. + * Some examples of dotProduct value : + * VIEW_FIELD_FULL -1.0 + * VIEW_FIELD_WIDE -0.7 + * VIEW_FIELD_NARROW 0.7 + * VIEW_FIELD_ULTRA_NARROW 0.9 + * Forward params: function(this, entTest, Float:dotProduct) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsFacing, this, entTest, Float:dotProduct) + */ + Ham_SC_IsFacing, + + /** + * Description: Gets points without killing an entity. + * Forward params: function(this, Float:damage) + * Return type: Float. + * Execute params: ExecuteHam(Ham_SC_GetPointsForDamage, this, Float:damage) + */ + Ham_SC_GetPointsForDamage, + + /** + * Description: Gets points for making some damage. + * Forward params: function(this, attacker, inflictor, Float:damage) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_GetDamagePoints, this, attacker, inflictor, Float:damage) + */ + Ham_SC_GetDamagePoints, + + /** + * Description: Constructor. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_OnCreate, this) + */ + Ham_SC_OnCreate, + + /** + * Description: Desctructor. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_OnDestroy, this) + */ + Ham_SC_OnDestroy, + + /** + * Description: (!) This function is no more available in the mod. + * Returns false if the entity is somehow invalid. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsValidEntity, this) + */ + Ham_SC_IsValidEntity, + + /** + * Description: Checks if this monster should fade out. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_ShouldFadeOnDeath, this) + */ + Ham_SC_ShouldFadeOnDeath, + + /** + * Description: Sets up a friendly monster. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_SetupFriendly, this) + */ + Ham_SC_SetupFriendly, + + /** + * Description: (!) This function is no more available in the mod. + * Tries to revive a monster. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_ReviveThink, this) + */ + Ham_SC_ReviveThink, + + /** + * Description: Revives a monster. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Revive, this) + */ + Ham_SC_Revive, + + /** + * Description: Final bit of initization before a monster is turned over to the AI. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_StartMonster, this) + */ + Ham_SC_StartMonster, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CheckRangeAttack1_Move, this, Float:dot, Float:dist) + */ + Ham_SC_CheckRangeAttack1_Move, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CheckRangeAttack2_Move, this, Float:dot, Float:dist) + */ + Ham_SC_CheckRangeAttack2_Move, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CheckMeleeAttack1_Move, this, Float:dot, Float:dist) + */ + Ham_SC_CheckMeleeAttack1_Move, + + /** + * Description: Surveys conditions and set appropriate conditions bits for attack types. + * Forward params: function(this, Float:dot, Float:dist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CheckMeleeAttack2_Move, this, Float:dot, Float:dist) + */ + Ham_SC_CheckMeleeAttack2_Move, + + /** + * Description: Checks tank usage. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CheckTankUsage, this) + */ + Ham_SC_CheckTankUsage, + + /** + * Description: Sets a monster's gait activity. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_SetGaitActivity, this) + */ + Ham_SC_SetGaitActivity, + + /** + * Description: Tries to overcome local obstacles by triangulating a path around them. + * Forward params: function(this, const Float:start[3], const Float:end[3], Float:dist, targetEnt, Float:apex[3], Float:apex2[3], bool:coverPath) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FTriangulate, this, const Float:start[3], const Float:end[3], Float:dist, targetEnt, Float:apex[3], Float:apex2[3], bool:coverPath ) + */ + Ham_SC_FTriangulate, + + /** + * Description: Tries to overcome local obstacles by triangulating a path around them. + * Forward params: function(this, const Float:start[3], const Float:end[3], Float:dist, targetEnt, Float:apex[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FTriangulateExtension, this, const Float:start[3], const Float:end[3], Float:dist, targetEnt, Float:apex[3]) + */ + Ham_SC_FTriangulateExtension, + + /** + * Description: Tries to find a nearby node that will hide the caller from its enemy. + * If supplied, search will return a node at least as far away as minDist, but no farther than maxDist. + * If maxDist isn't supplied, it defaults to a reasonable value. + * Forward params: function(this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FindCoverGrenade, this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist) + */ + Ham_SC_FindCoverGrenade, + + /** + * Description: Tries to find a nearby node that will hide the caller from its enemy. + * If supplied, search will return a node at least as far away as minDist, but no farther than maxDist. + * If maxDist isn't supplied, it defaults to a reasonable value. + * Forward params: function(this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FindCoverDistance, this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist) + */ + Ham_SC_FindCoverDistance, + + /** + * Description: Tries to find a nearby node that will hide the caller from its enemy. + * If supplied, search will return a node at least as far away as minDist, but no farther than maxDist. + * If maxDist isn't supplied, it defaults to a reasonable value. + * Forward params: function(this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FindAttackPoint, this, const Float:threat[3], const Float:viewOffset[3], Float:minDist, Float:maxDist) + */ + Ham_SC_FindAttackPoint, + + /** + * Description: Determines whether or not the chosen cover location is a good one to move to. + * Currently based on proximity to others in the squad. + * Forward params: function(this, const Float:coverLocation[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FValidateCover, this, const Float:coverLocation[3]) + */ + Ham_SC_FValidateCover, + + /** + * Description: Checks for possibility of friendly fire. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_NoFriendlyFire, this) + */ + Ham_SC_NoFriendlyFire1, + + /** + * Description: Checks for possibility of friendly fire. + * Forward params: function(this, const Float:pos[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_NoFriendlyFire2, this, const Float:pos[3]) + */ + Ham_SC_NoFriendlyFire2, + + /** + * Description: Checks for possibility of friendly fire. + * Forward params: function(this, const Float:pos[3], targetEnt) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_NoFriendlyFire3, this, const Float:pos[3], targetEnt) + */ + Ham_SC_NoFriendlyFire3, + + /** + * Description: Checks for possibility of friendly fire from the calling monster's origin to toPos. + * Forward params: function(this, const Float:toPos[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_NoFriendlyFireToPos, this, const Float:toPos[3]) + */ + Ham_SC_NoFriendlyFireToPos, + + /** + * Description: Same as FVisible but from gun position. + * Forward params: function(this, entity, Float:pos[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FVisibleGunPos, this, entity, Float:pos[3]) + */ + Ham_SC_FVisibleGunPos, + + /** + * Description: Checks for monsters in this generic cone. + * Forward params: function(this, entity, const Float:pos[3]) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FInBulletCone, this, entity, const Float:pos[3]) + */ + Ham_SC_FInBulletCone, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_CallGibMonster, this) + */ + Ham_SC_CallGibMonster, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_CheckTimeBasedDamage, this) + */ + Ham_SC_CheckTimeBasedDamage, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsMoving, this) + */ + Ham_SC_IsMoving, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsPlayerFollowing, this) + */ + Ham_SC_IsPlayerFollowing, + + /** + * Description: - + * Forward params: function(this, idleader, bool:noSound) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_StartPlayerFollowing, this, idleader, bool:noSound) + */ + Ham_SC_StartPlayerFollowing, + + /** + * Description: - + * Forward params: function(this, bool:clearSchedule, bool:noSound) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_StopPlayerFollowing, this, bool:clearSchedule, bool:noSound) + */ + Ham_SC_StopPlayerFollowing, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_UseSound, this) + */ + Ham_SC_UseSound, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_UnUseSound, this) + */ + Ham_SC_UnUseSound, + + /** + * Description: - + * Forward params: function(this, idOther) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_RideMonster, this, idOther) + */ + Ham_SC_RideMonster, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_CheckAndApplyGenericAttacks, this) + */ + Ham_SC_CheckAndApplyGenericAttacks, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_CheckScared, this) + */ + Ham_SC_CheckScared, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_CheckCreatureDanger, this) + */ + Ham_SC_CheckCreatureDanger, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_CheckFallDamage, this) + */ + Ham_SC_CheckFallDamage, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_CheckRevival, this) + */ + Ham_SC_CheckRevival, + + /** + * Description: (!) This function is no more available in the mod. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_MedicCallSound, this) + */ + Ham_SC_MedicCallSound, + + + /** + * Description: (!) This function is no more available in the mod. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_MenuInputPerformed, this) + */ + Ham_SC_Player_MenuInputPerformed, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_IsMenuInputDone, this) + */ + Ham_SC_Player_IsMenuInputDone, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_SpecialSpawn, this) + */ + Ham_SC_Player_SpecialSpawn, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Player_IsValidInfoEntity, this) + */ + Ham_SC_Player_IsValidInfoEntity, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_LevelEnd, this) + */ + Ham_SC_Player_LevelEnd, + + /** + * Description: - + * Forward params: function(this, voteType) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_VoteStarted, this, voteType) + */ + Ham_SC_Player_VoteStarted, + + /** + * Description: - + * Forward params: function(this, voteType) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Player_CanStartNextVote, this, voteType) + */ + Ham_SC_Player_CanStartNextVote, + + /** + * Description: - + * Forward params: function(this, voteInput) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_Vote, this, voteInput) + */ + Ham_SC_Player_Vote, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Player_HasVoted, this) + */ + Ham_SC_Player_HasVoted, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_ResetVote, this) + */ + Ham_SC_Player_ResetVote, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_Player_LastVoteInput, this) + */ + Ham_SC_Player_LastVoteInput, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_InitVote, this) + */ + Ham_SC_Player_InitVote, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_SC_Player_StartNextVote, this) + */ + Ham_SC_Player_TimeToStartNextVote, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_ResetView, this) + */ + Ham_SC_Player_ResetView, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_SC_Player_GetLogFrequency, this) + */ + Ham_SC_Player_GetLogFrequency, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Player_LogPlayerStats, this) + */ + Ham_SC_Player_LogPlayerStats, + + /** + * Description: (!) This function is no more available in the mod. + * Forward params: function(this, idPlayer, Float:time) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_DisableCollision, this, idPlayer, Float:time) + */ + Ham_SC_Player_DisableCollisionWithPlayer, + + /** + * Description: (!) This function is no more available in the mod. + * Forward params: function(this, idPlayer, bool:testIntersection) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_EnableCollision, this, idPlayer, bool:testIntersection) + */ + Ham_SC_Player_EnableCollisionWithPlayer, + + /** + * Description: (!) This function is no more available in the mod. + * Forward params: function(this, idPlayer) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Player_CanTouchPlayer, this, idPlayer) + */ + Ham_SC_Player_CanTouchPlayer, + + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Item_Materialize, this) + */ + Ham_SC_Item_Materialize, + + + /** + * Description: - + * Forward params: function(this, const Float:moving[3], const Float:standing[3], const Float:crouched[3]) + * Return type: Vector, byreffed in execute. + * Execute params: ExecuteHam(Ham_SC_Weapon_BulletAccuracy, this, const Float:moving[3], const Float:standing[3], const Float:crouched[3], Float:output[3]) + */ + Ham_SC_Weapon_BulletAccuracy, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_TertiaryAttack, this) + */ + Ham_SC_Weapon_TertiaryAttack, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_BurstSupplement, this) + */ + Ham_SC_Weapon_BurstSupplement, + + /** + * Description: - + * Forward params: function(this, const alternative[] = "") + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_SC_Weapon_GetP_Model, this, const alternative[] = "", buffer[], size) + */ + Ham_SC_Weapon_GetP_Model, + + /** + * Description: - + * Forward params: function(this, const alternative[] = "") + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_SC_Weapon_GetW_Model, this, const alternative[] = "", buffer[], size) + */ + Ham_SC_Weapon_GetW_Model, + + /** + * Description: - + * Forward params: function(this, const alternative[] = "") + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_SC_Weapon_GetV_Model, this, const alternative[] = "", buffer[], size) + */ + Ham_SC_Weapon_GetV_Model, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_PrecacheCustomMdl, this) + */ + Ham_SC_Weapon_PrecacheCustomModels, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_IsMultiplayer, this) + */ + Ham_SC_Weapon_IsMultiplayer, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_FRunfuncs, this) + */ + Ham_SC_Weapon_FRunfuncs, + + /** + * Description: - + * Forward params: function(this, fov) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_SetFOV, this, fov) + */ + Ham_SC_Weapon_SetFOV, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_FCanRun, this) + */ + Ham_SC_Weapon_FCanRun, + + /** + * Description: - + * Forward params: function(this, Float:frametime) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_CustomDecrement, this, Float:frametime) + */ + Ham_SC_Weapon_CustomDecrement, + + /** + * Description: - + * Forward params: function(this, const model[]) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_SetV_Model, this, const model[]) + */ + Ham_SC_Weapon_SetV_Model, + + /** + * Description: - + * Forward params: function(this, const model[]) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_SetP_Model, this, const model[]) + */ + Ham_SC_Weapon_SetP_Model, + + /** + * Description: - + * Forward params: function(this, skin) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_ChangeWeaponSkin, this, skin) + */ + Ham_SC_Weapon_ChangeWeaponSkin, + + + /** + * LATE ADDITIONS (2013) + */ + + /** + * Description: Normally called whenever an entity dies. + * Forward params: function(this, idinflictor, idattacker, shouldgib) + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_Killed, this, idinflictor, idattacker, shouldgib); + */ + Ham_TFC_Killed, + + /** + * Description: Returns whether an entity is activated. + * Forward params: function(this, idActivator); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_IsTriggered, this, idActivator); + */ + Ham_TFC_IsTriggered, + + /** + * Description: Sends an animation event for the weapon. skiplocal is 1 if client is predicting weapon animations. + * Forward params: function(this, anim, skiplocal); + * Return type: None. + * Execute params: ExecuteHam(Ham_TFC_Weapon_SendWeaponAnim, this, anim, skiplocal); + */ + Ham_TFC_Weapon_SendWeaponAnim, + + /** + * Description: Gets next attack delay. + * Forward params: function(this, Float:delay) + * Return type: Float (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_TFC_Weapon_GetNextAttackDelay, this, Float:delay, Float:output); + */ + Ham_TFC_Weapon_GetNextAttackDelay, + + + /** + * Description: Usually called whenever an entity gets a form of a heal. + * Forward params: function(this, Float:health, damagebits, health_cap); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_TakeHealth, this, Float:health, damagebits, health_cap); + */ + Ham_SC_TakeHealth, + + /** + * Description: Usually called whenever an entity gets a form of armor. + * Forward params: function(this, Float:armor, damagebits, armor_cap); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_TakeArmor, this, Float:armor, damagebits, armor_cap); + */ + Ham_SC_TakeArmor, + + /** + * Description: Gives ammo to the entity. + * Forward params: function(this, amount, const name[], max, const bool:fromPlayer) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_GiveAmmo, this, amount, "type", max, fromPlayer); + */ + Ham_SC_GiveAmmo, + + /** + * Description: Determines if we should ignore damage. + * Forward params: function(this, idattacker); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_CheckAttacker, this, idattacker); + */ + Ham_SC_CheckAttacker, + + /** + * Description: Determines if a player is connected. + * Forward params: function(this); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_Player_IsConnected, this); + */ + Ham_SC_Player_IsConnected, + + + /** + * Description: Sends an animation event for the weapon. skiplocal is 1 if client is predicting weapon animations. + * Forward params: function(this, anim, skiplocal); + * Return type: None. + * Execute params: ExecuteHam(Ham_DOD_Weapon_SendWeaponAnim, this, anim, skiplocal); + */ + Ham_DOD_Weapon_SendWeaponAnim, + + + /** + * Description: - + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CS_Item_IsWeapon, this); + */ + Ham_CS_Item_IsWeapon, + + + /** + * Description: Returns the id of the entity if its class is derived off of CBaseSquadTalkMonster, -1 otherwise. + * Forward params: function(this) + * Return type: Entity. + * Execute params: ExecuteHam(Ham_OPF_MySquadTalkMonsterPointer, this); + */ + Ham_OPF_MySquadTalkMonsterPointer, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float (byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_OPF_WeaponTimeBase, this); + */ + Ham_OPF_WeaponTimeBase, + + + /** + * Description: Called when the alternate attack of a weapon is triggered. + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_TS_Weapon_AlternateAttack, this); + */ + Ham_TS_Weapon_AlternateAttack, + + + /** + * Description: Gets item infos. + * Forward params: function(this, iteminfo_handle); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_Item_GetItemInfo, this, iteminfo_handle); + * Use CreateHamItemInfo() to pass a new ItemInfo handle. + */ + Ham_Item_GetItemInfo, + + + /** + * LATE ADDITIONS (2017) + */ + + /** + * Description: Performs checks that must occur before Spawn itself is called. Always call baseclass version first. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_PreSpawn, this); + */ + Ham_SC_PreSpawn, + + /** + * Description: Performs checks that must occur after Spawn itself is called. Always call baseclass version first. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_PostSpawn, this); + */ + Ham_SC_PostSpawn, + + /** + * Description: - + * Forward params: function(this, key); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_PostSpawn, this, const key[]); + */ + Ham_SC_OnKeyValueUpdate, + + /** + * Description: - + * Forward params: function(this, classification); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_SetClassification, this, classification); + */ + Ham_SC_SetClassification, + + /** + * Description: Returns whether an entity is activated. + * This function is not supported by Day Of Defeat. + * This function has different version for Team Fortress Classic, see Ham_TFC_IsTriggered instead. + * Forward params: function(this, idActivator); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_IsTriggered, this, idActivator); + */ + Ham_SC_IsTriggered, + + /** + * Description: Returns the id of the entity if its class is derived off of ICustomEntity, -1 otherwise. + * Forward params: function(this) + * Return type: Entity. + * Execute params: ExecuteHam(Ham_SC_MyCustomPointer, this); + */ + Ham_SC_MyCustomPointer, + + /** + * Description: Returns the id of the entity if its class is derived off of CBasePlayerItem, -1 otherwise. + * Forward params: function(this) + * Return type: Entity. + * Execute params: ExecuteHam(Ham_SC_MyItemPointer, this); + */ + Ham_SC_MyItemPointer, + + /** + * Description: Typically adds points to the entity. + * Forward params: function(this, points, bool:cangonegative); + * Return type: None. + * Execute params: ExecuteHam(Ham_AddPoints, this, points, bool:cangonegative); + */ + Ham_SC_AddPoints, + + /** + * Description: Typically adds points to everybody on the entity's team. + * Forward params: function(this, points, bool:cangonegative); + * Return type: None. + * Execute params: ExecuteHam(Ham_AddPointsToTeam, this, points, bool:cangonegative); + */ + Ham_SC_AddPointsToTeam, + + /** + * Description: Removes an item to the player's inventory. + * Forward params: function(this, idother); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_RemovePlayerItem, this, idother); + */ + Ham_SC_RemovePlayerItem, + + /** + * Description: Not entirely sure. + * Forward params: function(this, idOn) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_OnControls, this, idOn); + */ + Ham_SC_OnControls, + + /** + * Description: Whether or not the entity is sneaking. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsSneaking, this); + */ + Ham_SC_IsSneaking, + + /** + * Description: Whether or not the entity is alive. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsAlive, this); + */ + Ham_SC_IsAlive, + + /** + * Description: Whether or not the entity uses a BSP model. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsBSPModel, this); + */ + Ham_SC_IsBSPModel, + + /** + * Description: Whether or not the entity can reflect gauss shots. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_ReflectGauss, this); + */ + Ham_SC_ReflectGauss, + + /** + * Description: Whether or not the target is the same as the one passed. + * Note the strindex parameter is a string passed that has been allocated by the engine. + * Use fakemeta's EngFunc_SzFromIndex to convert to a normal string, or fakemeta's + * EngFunc_AllocString to create a new string. + * Forward params: function(this, strindex). + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_HasTarget, this, strindex); + */ + Ham_SC_HasTarget, + + /** + * Description: Whether or not the entity is in the world. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsInWorld, this); + */ + Ham_SC_IsInWorld, + + /** + * Description: Whether or not the entity is a player. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Sc_IsPlayer, this); + */ + Ham_Sc_IsPlayer, + + /** + * Description: Whether or not the entity is a net client. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsNetClient, this); + */ + Ham_SC_IsNetClient, + + /** + * Description: Whether or not the entity is a brush entity breakable. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsBreakable, this); + */ + Ham_SC_IsBreakable, + + /** + * Description: - + * Forward params: function(this, idActivator, useType, value); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_SUB_UseTargets, this, idActivator, useType, value); + */ + Ham_SC_SUB_UseTargets, + + /** + * Description: - + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsLockedByMaster, this); + */ + Ham_SC_IsLockedByMaster, + + /** + * Description: Normally called whenever a barnacle grabs the entity. + * Forward params: function(this, idOther); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FBecomeProne, this, idOther); + */ + Ham_SC_FBecomeProne, + + /** + * Description: Returns true if a line can be traced from the caller's eyes to given vector. + * Forward params: function(this, const Float:origin[3]); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_FVecVisible, this, const Float:origin[3]); + */ + Ham_SC_FVecVisible, + + /** + * Description: Sets the player ally state + * Forward params: function(this, bool:state); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_SetPlayerAlly, this, bool:state); + */ + Ham_SC_SetPlayerAlly, + + /** + * Description: Callback after trigger_setorigin has moved the entity. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_OnSetOriginByMap, this); + */ + Ham_SC_OnSetOriginByMap, + + /** + * Description: Return true if you want to be revivable. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_IsRevivable, this); + */ + Ham_SC_IsRevivable, + + /** + * Description: - + * timeUntilRevive is the time until the actual revive event occurs. + * Forward params: function(this, Float:timeUntilRevive); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_BeginRevive, Float:timeUntilRevive); + */ + Ham_SC_BeginRevive, + + /** + * Description: - + * timeUntilRevive is the time before the monster is supposed to be revived + * Forward params: function(this, Float:timeUntilRevive); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_EndRevive, Float:timeUntilRevive); + */ + Ham_SC_EndRevive, + + /** + * Description: Determines whether or not the monster can play the scripted sequence or AI sequence that is + * trying to possess it. If DisregardState is set, the monster will be sucked into the script + * no matter what state it is in. ONLY Scripted AI ents should allow this. + * Forward params: function(this, bool:disregardState, interruptLevel); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CanPlaySequence, this, bool:disregardState, interruptLevel); + */ + Ham_SC_CanPlaySequence, + + /** + * Description: - + * Forward params: function(this, bool:disregardState); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_CanPlaySentence2, this, bool:disregardState); + */ + Ham_SC_CanPlaySentence2, + + /** + * Description: - + * Forward params: function(this, const sentence[], Float:duration, Float:volume, Float:attenuation, bool:concurrent, idListener); + * Return type: None. + * Execute params: ExecuteHam(Ham_PlayScriptedSentence, this, const sentence[], Float:duration, Float:volume, Float:attenuation, bool:concurrent, idListener); + */ + Ham_SC_PlayScriptedSentence, + + + /** + * Items have all the attributes of normal entities in addition to these. + */ + + /** + * Description: Adds the item to the player. + * Forward params: function(this, idPlayer); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_Item_AddToPlayer, this, idPlayer); + */ + Ham_SC_Item_AddToPlayer, + + /** + * Description: Returns true if you want your duplicate removed from world. + * Forward params: function(this, idOriginal); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_AddDuplicate, this, idOriginal); + */ + Ham_SC_Item_AddDuplicate, + + /** + * Description: - + * Forward params: function(this, idOther); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_AddAmmoFromItem, this, idOther); + */ + Ham_SC_Item_AddAmmoFromItem, + + /** + * Description: - + * Forward params: function(this) + * Return type: String (string length returned and string byref'd in ExecuteHam). + * Execute params: ExecuteHam(Ham_SC_Item_GetPickupSound, this) + */ + Ham_SC_Item_GetPickupSound, + + /** + * Description: - + * Collect Types: + * COLLECT_TOUCH 0 + * COLLECT_USE_DIRECT 1 + * COLLECT_USE_INDIRECT 2 + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_CanCollect, this, idOther, collectType); + */ + Ham_SC_Item_CanCollect, + + /** + * Description: - + * Forward params: function(this, idOther, collectType); + * Collect Types: + * COLLECT_TOUCH 0 + * COLLECT_USE_DIRECT 1 + * COLLECT_USE_INDIRECT 2 + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Item_Collect, this, idOther, collectType); + */ + Ham_SC_Item_Collect, + + /** + * Description: Gets item infos. + * Forward params: function(this, iteminfo_handle); + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_Item_GetItemInfo, this, iteminfo_handle); + * Use CreateHamItemInfo() to pass a new ItemInfo handle. + */ + Ham_SC_Item_GetItemInfo, + + /** + * Description: Whether or not this entity can be deployed. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_CanDeploy, this); + */ + Ham_SC_Item_CanDeploy, + + /** + * Description: Deploys the entity (usually a weapon). + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_Deploy, this); + */ + Ham_SC_Item_Deploy, + + /** + * Description: Whether or not the entity can be holstered. + * Forward params: function(this); + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_CanHolster, this); + */ + Ham_SC_Item_CanHolster, + + /** + * Description: Called each frame by the player PreThink if inactive. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Item_InactiveItemPreFrame, this); + */ + Ham_SC_Item_InactiveItemPreFrame, + + /** + * Description: Called each frame by the player PostThink if inactive. + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Item_InactiveItemPostFrame, this); + */ + Ham_SC_Item_InactiveItemPostFrame, + + /** + * Description: - + * Forward params: function(this); + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Item_DetachFromPlayer, this); + */ + Ham_SC_Item_DetachFromPlayer, + + /** + * Description: Updates item data for the client. + * Forward params: function(this, idPlayer) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_Item_UpdateClientData, this, idPlayer); + */ + Ham_SC_Item_UpdateClientData, + + /** + * Description: - + * Forward params: function(this) + * Return type: Float. + * Execute params: ExecuteHam(Ham_SC_Item_GetRespawnTime, this); + */ + Ham_SC_Item_GetRespawnTime, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Item_CanHaveDuplicates, this); + */ + Ham_SC_Item_CanHaveDuplicates, + + + /** + * Weapons have all the attributes to Ham_Item_*, in addition to these. + */ + + /** + * Description: - + * Forward params: function(this, idOriginal) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_ExtractAmmoFromItem, idOriginal); + */ + Ham_SC_Weapon_ExtractAmmoFromItem, + + /** + * Description: Unsure. + * This function is not supported in Earth's Special Forces mod. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_AddWeapon, this); + */ + Ham_SC_Weapon_AddWeapon, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_Weapon_GetAmmo1Drop); + */ + Ham_SC_Weapon_GetAmmo1Drop, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer. + * Execute params: ExecuteHam(Ham_SC_Weapon_GetAmmo2Drop, idOriginal); + */ + Ham_SC_Weapon_GetAmmo2Drop, + + /** + * Description: Plays the weapon's empty sound. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_PlayEmptySound, this); + */ + Ham_SC_Weapon_PlayEmptySound, + + /** + * Description: Whether or not the weapon is usable (has ammo, etc.) + * This function is not supported in Earth's Special Forces mod. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_IsUsable, this) + */ + Ham_SC_Weapon_IsUsable, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Weapon_FinishReload, idOriginal); + */ + Ham_SC_Weapon_FinishReload, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_ShouldReload, idOriginal); + */ + Ham_SC_Weapon_ShouldReload, + + /** + * Description: Whether or not the weapon should idle. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute Params: ExecuteHam(Ham_SC_Weapon_ShouldWeaponIdle, this) + */ + Ham_SC_Weapon_ShouldWeaponIdle, + + /** + * Description: Unsure. + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Weapon_UseDecrement, this); + */ + Ham_SC_Weapon_UseDecrement, + + + /** + * Players have all the attributes of normal entities, in addition to these. + */ + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_EnteredObserver, this); + */ + Ham_SC_Player_EnteredObserver, + + /** + * Description: - + * Forward params: function(this) + * Return type: None. + * Execute params: ExecuteHam(Ham_SC_Player_LeftObserver, this); + */ + Ham_SC_Player_LeftObserver, + + /** + * Description: - + * Forward params: function(this) + * Return type: Integer (boolean). + * Execute params: ExecuteHam(Ham_SC_Player_IsObserver, this); + */ + Ham_SC_Player_IsObserver, + + + /** + * DONT USE ME LOL + */ + HAM_LAST_ENTRY_DONT_USE_ME_LOL +}; + +/** + * Ham error types. + */ +enum HamError +{ + HAM_OK = 0, + + HAM_INVALID_FUNC, // The function is not valid + HAM_FUNC_NOT_CONFIGURED, // This function is not configured in gamedata + HAM_FUNC_NOT_AVAILABLE, // This function is not more available in the mod + + HAM_ERR_END +}; + +/** + * Constants for usage with [Get|Set]HamItemInfo + */ +enum HamItemInfo +{ + Ham_ItemInfo_iSlot, + Ham_ItemInfo_iPosition, + Ham_ItemInfo_pszAmmo1, + Ham_ItemInfo_iMaxAmmo1, + Ham_ItemInfo_pszAmmo2, + Ham_ItemInfo_iMaxAmmo2, + Ham_ItemInfo_pszName, + Ham_ItemInfo_iMaxClip, + Ham_ItemInfo_iId, + Ham_ItemInfo_iFlags, + Ham_ItemInfo_iWeight +}; + diff --git a/amxmodx/scripting/include/hamsandwich.inc b/amxmodx/scripting/include/hamsandwich.inc new file mode 100644 index 0000000..8eb65c2 --- /dev/null +++ b/amxmodx/scripting/include/hamsandwich.inc @@ -0,0 +1,439 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Ham Sandwich Functions +// + +/** + * Ham Sandwich is a module that is used to hook and call virtual functions of + * entities. + * Virtual functions are mod-specific functions. This means that in order + * for this to work on a mod, it needs to be configured with the gamedata + * file. + * Be very careful with parameter passing to these functions. + */ + +#if defined _hamsandwich_included + #endinput +#endif +#define _hamsandwich_included + +#include + +#pragma reqlib hamsandwich +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib hamsandwich +#endif + +/** + * Hooks the virtual table for the specified entity class. + * An example would be: RegisterHam(Ham_TakeDamage, "player", "player_hurt"); + * Look at the Ham enum for parameter lists. + * + * @param function The function to hook. + * @param EntityClass The entity classname to hook. + * @param callback The forward to call. + * @param post Whether or not to forward this in post. + * @param specialbot Whether or not to enable support for bot without "player" classname. + * @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off. + */ +native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0, bool:specialbot = false); + +/** + * Hooks the virtual table for the player class. + * An example would be: RegisterHam(Ham_TakeDamage, "player_hurt"); + * Look at the Ham enum for parameter lists. + * + * @param function The function to hook. + * @param callback The forward to call. + * @param post Whether or not to forward this in post. + * @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off. + */ +stock HamHook:RegisterHamPlayer(Ham:function, const Callback[], Post=0) +{ + return RegisterHam(function, "player", Callback, Post, true); +} + +/** + * Hooks the virtual table for the specified entity's class. + * An example would be: RegisterHam(Ham_TakeDamage, id, "player_hurt"); + * Look at the Ham enum for parameter lists. + * Note: This will cause hooks for the entire internal class that the entity is + * not exclusively for the provided entity. + * + * @param function The function to hook. + * @param EntityId The entity classname to hook. + * @param callback The forward to call. + * @param post Whether or not to forward this in post. + * @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off. + */ +native HamHook:RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0); + + +/** + * Stops a ham forward from triggering. + * Use the return value from RegisterHam as the parameter here! + * + * @param fwd The forward to stop. + */ +native DisableHamForward(HamHook:fwd); + +/** + * Starts a ham forward back up. + * Use the return value from RegisterHam as the parameter here! + * + * @param fwd The forward to re-enable. + */ +native EnableHamForward(HamHook:fwd); + +/** + * Executes the virtual function on the entity. + * Look at the Ham enum for parameter lists. + * + * @param function The function to call. + * @param id The id of the entity to execute it on. + */ +native ExecuteHam(Ham:function, this, any:...); + +/** + * Executes the virtual function on the entity, this will trigger all hooks on that function. + * Be very careful about recursion! + * Look at the Ham enum for parameter lists. + * + * @param function The function to call. + * @param id The id of the entity to execute it on. + */ +native ExecuteHamB(Ham:function, this, any:...); + +/** + * Gets the return status of the current hook. + * This is useful to determine what return natives to use. + * + * @return The current status of the hook (such as HAM_SUPERCEDE). + */ +native GetHamReturnStatus(); + +/** + * Gets the return value of a hook for hooks that return integers or booleans. + * + * @param output The variable to store the value in. + */ +native GetHamReturnInteger(&output); + +/** + * Gets the return value of a hook for hooks that return float. + * + * @param output The variable to store the value in. + */ +native GetHamReturnFloat(&Float:output); + +/** + * Gets the return value of a hook for hooks that return Vectors. + * + * @param output The variable to store the value in. + */ +native GetHamReturnVector(Float:output[3]); + +/** + * Gets the return value of a hook for hooks that return entities. + * + * @param output The variable to store the value in. Will be -1 on null. + */ +native GetHamReturnEntity(&output); + +/** + * Gets the return value of a hook for hooks that return strings. + * + * @param output The buffer to store the string in. + * @param size The string size of the buffer. + */ +native GetHamReturnString(output[], size); + +/** + * Gets the original return value of a hook for hooks that return integers or booleans. + * + * @param output The variable to store the value in. + */ +native GetOrigHamReturnInteger(&output); + +/** + * Gets the original return value of a hook for hooks that return floats. + * + * @param output The variable to store the value in. + */ +native GetOrigHamReturnFloat(&Float:output); + +/** + * Gets the original return value of a hook for hooks that return Vectors. + * + * @param output The variable to store the value in. + */ +native GetOrigHamReturnVector(Float:output[3]); + +/** + * Gets the original return value of a hook for hooks that return entities. + * + * @param output The variable to store the value in. -1 on null. + */ +native GetOrigHamReturnEntity(&output); + +/** + * Gets the original return value of a hook for hooks that return strings. + * + * @param output The buffer to store the string in. + * @param size The size of the buffer. + */ +native GetOrigHamReturnString(output[], size); + + +/** + * Sets the return value of a hook that returns an integer or boolean. + * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE. + * + * @param value The value to set the return to. + */ +native SetHamReturnInteger(value); + +/** + * Sets the return value of a hook that returns a float. + * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE. + * + * @param value The value to set the return to. + */ +native SetHamReturnFloat(Float:value); + +/** + * Sets the return value of a hook that returns a Vector. + * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE. + * + * @param value The value to set the return to. + */ +native SetHamReturnVector(const Float:value[3]); + +/** + * Sets the return value of a hook that returns an entity. Set to -1 for null. + * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE. + * + * @param value The value to set the return to. + */ +native SetHamReturnEntity(value); + +/** + * Sets the return value of a hook that returns a string. + * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE. + * + * @param value The value to set the return to. + */ +native SetHamReturnString(const value[]); + + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are integers. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param value The value to change it to. + */ +native SetHamParamInteger(which, value); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are floats. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param value The value to change it to. + */ +native SetHamParamFloat(which, Float:value); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are Vectors. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param value The value to change it to. + */ +native SetHamParamVector(which, const Float:value[3]); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are entities. + * + * @note Due to a historical bug, the changes made by this native are not reflected in the corresponding post forward + * for backward compatibility reasons. Use SetHamParamEntity2 if this is required. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param value The value to change it to. + */ +native SetHamParamEntity(which, value); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are entities. + * + * @note Same as SetHamParamEntity except the changes made by this native are reflected in the corresponding post forward. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param value The value to change it to. + */ +native SetHamParamEntity2(which, value); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are strings. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param ouput The value to change it to. + */ +native SetHamParamString(which, const output[]); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are trace result handles. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param tr_handle The value to change it to. + */ +native SetHamParamTraceResult(which, tr_handle); + +/** + * Sets a parameter on the fly of the current hook. This has no effect in post hooks. + * Use this on parameters that are trace result handles. + * + * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". + * @param iteminfo_handle The value to change it to. + */ +native SetHamParamItemInfo(which, iteminfo_handle); + + +/** + * Gets a parameter on the fly of the current hook. + * Use this on parameters that are iteminfo result handles. + * + * @param iteminfo_handle Item info handle. + * @param type Item info type. See HamItemInfo constants. + */ +native GetHamItemInfo(iteminfo_handle, HamItemInfo:type, any:...); + +/** + * Sets a parameter on the fly of the current hook. + * Use this on parameters that are iteminfo result handles. + * + * @param iteminfo_handle Item info handle. + * @param type Item info type. See HamItemInfo_ constants. + */ +native SetHamItemInfo(iteminfo_handle, HamItemInfo:type, any:...); + +/** + * Creates an ItemInfo handle. This value should never be altered. + * The handle can be used in Get/SetHamItemInfo. + * + * NOTE: You must call FreeHamItemInfo() on every handle made with CreateHamItemInfo(). + * + * @return A new ItemInfo handle. + */ +native CreateHamItemInfo(); + +/** + * Frees an ItemIndo handle created with CreateHamItemInfo(). Do not call + * this more than once per handle, or on handles not created through + * CreateHamItemInfo(). + * + * @param itemInfo_handle ItemInfo handle created via CreateHamItemInfo(). + * @noreturn + */ +native FreeHamItemInfo(itemInfo_handle); + + +/** + * Returns whether or not the function for the specified Ham is valid. + * Things that would make it invalid would be bounds (an older module version + * may not have all of the functions), and the function not being found in + * the mod's hamdata.ini file. + * + * @param function The function to look up. + * @return true if the function is valid, false otherwise. + */ +native bool:IsHamValid(Ham:function); + +/** + * This is used to compliment fakemeta's {get,set}_pdata_{int,float,string}. + * This requires the mod to have the pev and base fields set in hamdata.ini. + * Note this dereferences memory! Improper use of this will crash the server. + * This will return an index of the corresponding cbase field in private data. + * Returns -1 on a null entry. + * + * @param id The entity to examine the private data. + * @param offset The windows offset of the data. + * @param linuxdiff The linux difference of the data. + * @param macdiff The mac os x difference of the data. + * @return The index of the corresponding pdata field. -1 for none set. + */ +native get_pdata_cbase(id, offset, linuxdiff=5, macdiff=5); + +/** + * This is used to compliment fakemeta's {get,set}_pdata_{int,float,string}. + * This requires the mod to have the pev and base fields set in hamdata.ini. + * This will set the corresponding cbase field in private data with the index. + * Pass -1 to null the entry. + * + * @param id The entity to examine the private data. + * @param offset The windows offset of the data. + * @param value The index to store, -1 for invalid + * @param linuxdiff The linux difference of the data. + * @param macdiff The mac os x difference of the data. + */ +native set_pdata_cbase(id, offset, value, linuxdiff=5, macdiff=5); + +/** + * This is similar to the get_pdata_cbase, however it does not dereference memory. + * This is many times slower than get_pdata_cbase, and this should only be used + * for testing and finding of offsets, not actual release quality plugins. + * This will return an index of the corresponding cbase field in private data. + * Returns -1 on a null entry. -2 on an invalid entry. + * + * @param id Entry to examine the private data. + * @param offset The windows offset of the data. + * @param linuxdiff The linux difference of the data. + * @param macdiff The mac os x difference of the data. + * @return The index of the corresponding pdata field, -1 for null, -2 for invalid. + */ +native get_pdata_cbase_safe(id, offset, linuxdiff=5, macdiff=5); + + + + +// This is the callback from the module, this handles any fatal errors. +// This will in turn call the "HamFilter(Ham:id, HamError:err, const reason[])" public, if it exists. +// Return PLUGIN_HANDLED from within the HamFilter to stop the plugin from failing. +// Any other return value will fail the plugin. +// You do not need to have a HamFilter, if there is none, all fatal errors will fail the plugin. +// Do not modify this! +public __fatal_ham_error(Ham:id, HamError:err, const reason[]) +{ + + new func=get_func_id("HamFilter", -1); + new bool:fail=true; + + if (func != -1 && callfunc_begin_i(func, -1)==1) + { + callfunc_push_int(_:id); + callfunc_push_int(_:err); + callfunc_push_str(reason, false); + if (callfunc_end()==PLUGIN_HANDLED) + { + fail=false; + } + } + if (fail) + { + set_fail_state(reason); + } + +} diff --git a/amxmodx/scripting/include/hlsdk_const.inc b/amxmodx/scripting/include/hlsdk_const.inc new file mode 100644 index 0000000..f9b8cfa --- /dev/null +++ b/amxmodx/scripting/include/hlsdk_const.inc @@ -0,0 +1,808 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Half-Life SDK Constants +// + +#if defined _hlsdk_const_included + #endinput +#endif +#define _hlsdk_const_included + +/** + * pev(entity, pev_button) or pev(entity, pev_oldbuttons) values + */ +#define IN_ATTACK (1<<0) +#define IN_JUMP (1<<1) +#define IN_DUCK (1<<2) +#define IN_FORWARD (1<<3) +#define IN_BACK (1<<4) +#define IN_USE (1<<5) +#define IN_CANCEL (1<<6) +#define IN_LEFT (1<<7) +#define IN_RIGHT (1<<8) +#define IN_MOVELEFT (1<<9) +#define IN_MOVERIGHT (1<<10) +#define IN_ATTACK2 (1<<11) +#define IN_RUN (1<<12) +#define IN_RELOAD (1<<13) +#define IN_ALT1 (1<<14) +#define IN_SCORE (1<<15) // Used by client.dll for when scoreboard is held down + +/** + * pev(entity, pev_flags) values + */ +#define FL_FLY (1<<0) // Changes the SV_Movestep() behavior to not need to be on ground +#define FL_SWIM (1<<1) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water) +#define FL_CONVEYOR (1<<2) +#define FL_CLIENT (1<<3) +#define FL_INWATER (1<<4) +#define FL_MONSTER (1<<5) +#define FL_GODMODE (1<<6) +#define FL_NOTARGET (1<<7) +#define FL_SKIPLOCALHOST (1<<8) // Don't send entity to local host, it's predicting this entity itself +#define FL_ONGROUND (1<<9) // At rest / on the ground +#define FL_PARTIALGROUND (1<<10) // Not all corners are valid +#define FL_WATERJUMP (1<<11) // Player jumping out of water +#define FL_FROZEN (1<<12) // Player is frozen for 3rd person camera +#define FL_FAKECLIENT (1<<13) // JAC: fake client, simulated server side; don't send network messages to them +#define FL_DUCKING (1<<14) // Player flag -- Player is fully crouched +#define FL_FLOAT (1<<15) // Apply floating force to this entity when in water +#define FL_GRAPHED (1<<16) // Worldgraph has this ent listed as something that blocks a connection +#define FL_IMMUNE_WATER (1<<17) +#define FL_IMMUNE_SLIME (1<<18) +#define FL_IMMUNE_LAVA (1<<19) +#define FL_PROXY (1<<20) // This is a spectator proxy +#define FL_ALWAYSTHINK (1<<21) // Brush model flag -- call think every frame regardless of nextthink - ltime (for constantly changing velocity/path) +#define FL_BASEVELOCITY (1<<22) // Base velocity has been applied this frame (used to convert base velocity into momentum) +#define FL_MONSTERCLIP (1<<23) // Only collide in with monsters who have FL_MONSTERCLIP set +#define FL_ONTRAIN (1<<24) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction. +#define FL_WORLDBRUSH (1<<25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something) +#define FL_SPECTATOR (1<<26) // This client is a spectator, don't run touch functions, etc. +#define FL_CUSTOMENTITY (1<<29) // This is a custom entity +#define FL_KILLME (1<<30) // This entity is marked for death -- This allows the engine to kill ents at the appropriate time +#define FL_DORMANT (1<<31) // Entity is dormant, no updates to client + +/** + * engfunc(EngFunc_WalkMove, entity, Float:yaw, Float:dist, iMode) iMode values + */ +#define WALKMOVE_NORMAL 0 // Normal walkmove +#define WALKMOVE_WORLDONLY 1 // Doesn't hit ANY entities, no matter what the solid type +#define WALKMOVE_CHECKONLY 2 // Move, but don't touch triggers + +/** + * engfunc(EngFunc_MoveToOrigin, entity, Float:goal[3], Float:distance, moveType) moveType values + */ +#define MOVE_NORMAL 0 // normal move in the direction monster is facing +#define MOVE_STRAFE 1 // moves in direction specified, no matter which way monster is facing + +/** + * pev(entity, pev_movetype) values + */ +#define MOVETYPE_NONE 0 // Never moves +#define MOVETYPE_WALK 3 // Player only - moving on the ground +#define MOVETYPE_STEP 4 // Gravity, special edge handling -- monsters use this +#define MOVETYPE_FLY 5 // No gravity, but still collides with stuff +#define MOVETYPE_TOSS 6 // Gravity/Collisions +#define MOVETYPE_PUSH 7 // No clip to world, push and crush +#define MOVETYPE_NOCLIP 8 // No gravity, no collisions, still do velocity/avelocity +#define MOVETYPE_FLYMISSILE 9 // Extra size to monsters +#define MOVETYPE_BOUNCE 10 // Just like Toss, but reflect velocity when contacting surfaces +#define MOVETYPE_BOUNCEMISSILE 11 // Bounce w/o gravity +#define MOVETYPE_FOLLOW 12 // Track movement of aiment +#define MOVETYPE_PUSHSTEP 13 // BSP model that needs physics/world collisions (uses nearest hull for world collision) + +/** + * pev(entity, pev_solid) values + * + * @note Some movetypes will cause collisions independent of SOLID_NOT and + * SOLID_TRIGGER when the entity moves. SOLID only effects OTHER entities + * colliding with this one when they move - UGH! + */ +#define SOLID_NOT 0 // No interaction with other objects +#define SOLID_TRIGGER 1 // Touch on edge, but not blocking +#define SOLID_BBOX 2 // Touch on edge, block +#define SOLID_SLIDEBOX 3 // Touch on edge, but not an onground +#define SOLID_BSP 4 // BSP clip, touch on edge, block + +/** + * pev(entity, pev_deadflag) values + */ +#define DEAD_NO 0 // Alive +#define DEAD_DYING 1 // Playing death animation or still falling off of a ledge waiting to hit ground +#define DEAD_DEAD 2 // Dead, lying still +#define DEAD_RESPAWNABLE 3 +#define DEAD_DISCARDBODY 4 + +/** + * new Float:takedamage, pev(entity, pev_takedamage, takedamage) values + */ +#define DAMAGE_NO 0.0 +#define DAMAGE_YES 1.0 +#define DAMAGE_AIM 2.0 + +/** + * pev(entity, pev_effects) values + */ +#define EF_BRIGHTFIELD 1 // Swirling cloud of particles +#define EF_MUZZLEFLASH 2 // Single frame ELIGHT on entity attachment 0 +#define EF_BRIGHTLIGHT 4 // DLIGHT centered at entity origin +#define EF_DIMLIGHT 8 // Player flashlight +#define EF_INVLIGHT 16 // Get lighting from ceiling +#define EF_NOINTERP 32 // Don't interpolate the next frame +#define EF_LIGHT 64 // Rocket flare glow sprite +#define EF_NODRAW 128 // Don't draw entity + +/** + * Spectating camera mode constants + * + * @note These constants are linked to different camera modes available when you + * are spectating (either dead or when in spectator team). Usually this is + * stored in the pev_iuser1 field in Counter-Strike and Half-Life games. + */ +#define OBS_NONE 0 +#define OBS_CHASE_LOCKED 1 // Locked Chase Cam +#define OBS_CHASE_FREE 2 // Free Chase Cam +#define OBS_ROAMING 3 // Free Look +#define OBS_IN_EYE 4 // First Person +#define OBS_MAP_FREE 5 // Free Overview +#define OBS_MAP_CHASE 6 // Chase Overview + +/** + * engfunc(EngFunc_PointContents, Float:origin) return values + */ +#define CONTENTS_EMPTY -1 +#define CONTENTS_SOLID -2 +#define CONTENTS_WATER -3 +#define CONTENTS_SLIME -4 +#define CONTENTS_LAVA -5 +#define CONTENTS_SKY -6 +#define CONTENTS_ORIGIN -7 // Removed at csg time +#define CONTENTS_CLIP -8 // Changed to contents_solid +#define CONTENTS_CURRENT_0 -9 +#define CONTENTS_CURRENT_90 -10 +#define CONTENTS_CURRENT_180 -11 +#define CONTENTS_CURRENT_270 -12 +#define CONTENTS_CURRENT_UP -13 +#define CONTENTS_CURRENT_DOWN -14 +#define CONTENTS_TRANSLUCENT -15 +#define CONTENTS_LADDER -16 +#define CONTENT_FLYFIELD -17 +#define CONTENT_GRAVITY_FLYFIELD -18 +#define CONTENT_FOG -19 + +/** + * Instant damage values for use with the 3rd parameter of the "Damage" client + * message. + */ +#define DMG_GENERIC 0 // Generic damage was done +#define DMG_CRUSH (1<<0) // Crushed by falling or moving object +#define DMG_BULLET (1<<1) // Shot +#define DMG_SLASH (1<<2) // Cut, clawed, stabbed +#define DMG_BURN (1<<3) // Heat burned +#define DMG_FREEZE (1<<4) // Frozen +#define DMG_FALL (1<<5) // Fell too far +#define DMG_BLAST (1<<6) // Explosive blast damage +#define DMG_CLUB (1<<7) // Crowbar, punch, headbutt +#define DMG_SHOCK (1<<8) // Electric shock +#define DMG_SONIC (1<<9) // Sound pulse shockwave +#define DMG_ENERGYBEAM (1<<10) // Laser or other high energy beam +#define DMG_NEVERGIB (1<<12) // With this bit OR'd in, no damage type will be able to gib victims upon death +#define DMG_ALWAYSGIB (1<<13) // With this bit OR'd in, any damage type can be made to gib victims upon death. +#define DMG_DROWN (1<<14) // Drowning +#define DMG_PARALYZE (1<<15) // Slows affected creature down +#define DMG_NERVEGAS (1<<16) // Nerve toxins, very bad +#define DMG_POISON (1<<17) // Blood poisioning +#define DMG_RADIATION (1<<18) // Radiation exposure +#define DMG_DROWNRECOVER (1<<19) // Drowning recovery +#define DMG_ACID (1<<20) // Toxic chemicals or acid burns +#define DMG_SLOWBURN (1<<21) // In an oven +#define DMG_SLOWFREEZE (1<<22) // In a subzero freezer +#define DMG_MORTAR (1<<23) // Hit by air raid (done to distinguish grenade from mortar) +#define DMG_GRENADE (1<<24) // Counter-Strike only - Hit by HE grenade +#define DMG_TIMEBASED (~(0x3fff)) // Mask for time-based damage + +/** +* Gib values used on client kill based on instant damage values +*/ +#define GIB_NORMAL 0 // Gib if entity was overkilled +#define GIB_NEVER 1 // Never gib, no matter how much death damage is done ( freezing, etc ) +#define GIB_ALWAYS 2 // Always gib ( Houndeye Shock, Barnacle Bite ) +#define GIB_TRY_HEALTH -9000 // Gib players if their health is under this value. (GIB_NEVER overrides this value) + +/** + * Valid constants for fNoMonsters parameter of EngFunc_TraceLine, + * EngFunc_TraceMonsterHull, EngFunc_TraceHull and EngFunc_TraceSphere. + */ +#define DONT_IGNORE_MONSTERS 0 +#define IGNORE_MONSTERS 1 +#define IGNORE_MISSILE 2 +#define IGNORE_GLASS 0x100 + +/** + * The hullnumber paramater of EngFunc_TraceHull, EngFunc_TraceModel and + * DLLFunc_GetHullBounds + */ +#define HULL_POINT 0 +#define HULL_HUMAN 1 +#define HULL_LARGE 2 +#define HULL_HEAD 3 + +/** + * global_get(glb_trace_flags) + */ +#define FTRACE_SIMPLEBOX (1<<0) // Traceline with a simple box + +/** + * Used with get/set_es(es_handle, ES_eFlags, ...) (entity_state data structure) + */ +#define EFLAG_SLERP 1 // Do studio interpolation of this entity + +/** + * @section pev(entity, pev_spawnflags) values + */ + +/** + * func_train + */ +#define SF_TRAIN_WAIT_RETRIGGER 1 +#define SF_TRAIN_START_ON 4 // Train is initially moving +#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains + +/** + * func_wall_toggle + */ +#define SF_WALL_START_OFF 0x0001 +#define SF_WALL_NOTSOLID 0x0008 + +/** + * func_converyor + */ +#define SF_CONVEYOR_VISUAL 0x0001 +#define SF_CONVEYOR_NOTSOLID 0x0002 + +/** + * func_button + */ +#define SF_BUTTON_DONTMOVE 1 +#define SF_BUTTON_TOGGLE 32 // Button stays pushed until reactivated +#define SF_BUTTON_SPARK_IF_OFF 64 // Button sparks in OFF state +#define SF_BUTTON_TOUCH_ONLY 256 // Button only fires as a result of USE key. + +/** + * func_rot_button + */ +#define SF_ROTBUTTON_NOTSOLID 1 +#define SF_ROTBUTTON_BACKWARDS 2 + +/** + * env_global + */ +#define SF_GLOBAL_SET 1 // Set global state to initial state on spawn + +/** + * multisource + */ +#define SF_MULTI_INIT 1 + +/** + * momentary_rot_button + */ +#define SF_MOMENTARY_DOOR 0x0001 + +/** + * button_target + */ +#define SF_BTARGET_USE 0x0001 +#define SF_BTARGET_ON 0x0002 + +/** + * func_door, func_water, func_door_rotating, momementary_door + */ +#define SF_DOOR_ROTATE_Y 0 +#define SF_DOOR_START_OPEN 1 +#define SF_DOOR_ROTATE_BACKWARDS 2 +#define SF_DOOR_PASSABLE 8 +#define SF_DOOR_ONEWAY 16 +#define SF_DOOR_NO_AUTO_RETURN 32 +#define SF_DOOR_ROTATE_Z 64 +#define SF_DOOR_ROTATE_X 128 +#define SF_DOOR_USE_ONLY 256 // Door must be opened by player's use button +#define SF_DOOR_NOMONSTERS 512 // Monster can't open +#define SF_DOOR_TOUCH_ONLY_CLIENTS 1024 // Only clients can touch +#define SF_DOOR_SILENT 0x80000000 // This bit marks that func_door are actually func_water + +/** + * gibshooter + */ +#define SF_GIBSHOOTER_REPEATABLE 1 // Allows a gibshooter to be refired + +/** + * env_funnel + */ +#define SF_FUNNEL_REVERSE 1 // Funnel effect repels particles instead of attracting them + +/** + * env_bubbles + */ +#define SF_BUBBLES_STARTOFF 0x0001 + +/** + * env_blood + */ +#define SF_BLOOD_RANDOM 0x0001 +#define SF_BLOOD_STREAM 0x0002 +#define SF_BLOOD_PLAYER 0x0004 +#define SF_BLOOD_DECAL 0x0008 + +/** + * env_shake + */ +#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius +#define SF_SHAKE_DISRUPT 0x0002 // Disrupt controls +#define SF_SHAKE_INAIR 0x0004 // Shake players in air + +/** + * env_fade + */ +#define SF_FADE_IN 0x0001 // Fade in, not out +#define SF_FADE_MODULATE 0x0002 // Modulate, don't blend +#define SF_FADE_ONLYONE 0x0004 + +/** + * env_beam, env_lightning + */ +#define SF_BEAM_STARTON 0x0001 +#define SF_BEAM_TOGGLE 0x0002 +#define SF_BEAM_RANDOM 0x0004 +#define SF_BEAM_RING 0x0008 +#define SF_BEAM_SPARKSTART 0x0010 +#define SF_BEAM_SPARKEND 0x0020 +#define SF_BEAM_DECALS 0x0040 +#define SF_BEAM_SHADEIN 0x0080 +#define SF_BEAM_SHADEOUT 0x0100 +#define SF_BEAM_TEMPORARY 0x8000 + +/** + * env_sprite + */ +#define SF_SPRITE_STARTON 0x0001 +#define SF_SPRITE_ONCE 0x0002 +#define SF_SPRITE_TEMPORARY 0x8000 + +/** + * env_message + */ +#define SF_MESSAGE_ONCE 0x0001 // Fade in, not out +#define SF_MESSAGE_ALL 0x0002 // Send to all clients + +/** + * env_explosion + */ +#define SF_ENVEXPLOSION_NODAMAGE (1<<0) // When set, ENV_EXPLOSION will not actually inflict damage +#define SF_ENVEXPLOSION_REPEATABLE (1<<1) // Can this entity be refired? +#define SF_ENVEXPLOSION_NOFIREBALL (1<<2) // Don't draw the fireball +#define SF_ENVEXPLOSION_NOSMOKE (1<<3) // Don't draw the smoke +#define SF_ENVEXPLOSION_NODECAL (1<<4) // Don't make a scorch mark +#define SF_ENVEXPLOSION_NOSPARKS (1<<5) // Don't make a scorch mark + +/** + * func_tank + */ +#define SF_TANK_ACTIVE 0x0001 +#define SF_TANK_PLAYER 0x0002 +#define SF_TANK_HUMANS 0x0004 +#define SF_TANK_ALIENS 0x0008 +#define SF_TANK_LINEOFSIGHT 0x0010 +#define SF_TANK_CANCONTROL 0x0020 +#define SF_TANK_SOUNDON 0x8000 + +/** + * grenade + */ +#define SF_DETONATE 0x0001 + +/** + * item_suit + */ +#define SF_SUIT_SHORTLOGON 0x0001 + +/** + * game_score + */ +#define SF_SCORE_NEGATIVE 0x0001 +#define SF_SCORE_TEAM 0x0002 + +/** + * game_text + */ +#define SF_ENVTEXT_ALLPLAYERS 0x0001 + +/** + * game_team_master + */ +#define SF_TEAMMASTER_FIREONCE 0x0001 +#define SF_TEAMMASTER_ANYTEAM 0x0002 + +/** + * game_team_set + */ +#define SF_TEAMSET_FIREONCE 0x0001 +#define SF_TEAMSET_CLEARTEAM 0x0002 + +/** + * game_player_hurt + */ +#define SF_PKILL_FIREONCE 0x0001 + +/** + * game_counter + */ +#define SF_GAMECOUNT_FIREONCE 0x0001 +#define SF_GAMECOUNT_RESET 0x0002 + +/** + * game_player_equip + */ +#define SF_PLAYEREQUIP_USEONLY 0x0001 + +/** + * game_player_team + */ +#define SF_PTEAM_FIREONCE 0x0001 +#define SF_PTEAM_KILL 0x0002 +#define SF_PTEAM_GIB 0x0004 + +/** + * func_trackchange + */ +#define SF_PLAT_TOGGLE 0x0001 +#define SF_TRACK_ACTIVATETRAIN 0x00000001 +#define SF_TRACK_RELINK 0x00000002 +#define SF_TRACK_ROTMOVE 0x00000004 +#define SF_TRACK_STARTBOTTOM 0x00000008 +#define SF_TRACK_DONT_MOVE 0x00000010 + +/** + * func_tracktrain + */ +#define SF_TRACKTRAIN_NOPITCH 0x0001 +#define SF_TRACKTRAIN_NOCONTROL 0x0002 +#define SF_TRACKTRAIN_FORWARDONLY 0x0004 +#define SF_TRACKTRAIN_PASSABLE 0x0008 +#define SF_PATH_DISABLED 0x00000001 +#define SF_PATH_FIREONCE 0x00000002 +#define SF_PATH_ALTREVERSE 0x00000004 +#define SF_PATH_DISABLE_TRAIN 0x00000008 +#define SF_PATH_ALTERNATE 0x00008000 +#define SF_CORNER_WAITFORTRIG 0x001 +#define SF_CORNER_TELEPORT 0x002 +#define SF_CORNER_FIREONCE 0x004 + +/** +* func_plat +*/ +#define SF_PLAT_TOGGLE 0x0001 + +/** +* path_track +*/ +#define SF_PATH_DISABLED 0x00000001 +#define SF_PATH_FIREONCE 0x00000002 +#define SF_PATH_ALTREVERSE 0x00000004 +#define SF_PATH_DISABLE_TRAIN 0x00000008 +#define SF_PATH_ALTERNATE 0x00008000 + +/** +* path_corner +*/ +#define SF_CORNER_WAITFORTRIG 0x001 +#define SF_CORNER_TELEPORT 0x002 +#define SF_CORNER_FIREONCE 0x004 + +/** + * trigger_push + */ +#define SF_TRIGGER_PUSH_START_OFF 2 // Spawnflag that makes trigger_push spawn turned OFF + +/** + * trigger_hurt + */ +#define SF_TRIGGER_HURT_TARGETONCE 1 // Only fire hurt target once +#define SF_TRIGGER_HURT_START_OFF 2 // Spawnflag that makes trigger_push spawn turned OFF +#define SF_TRIGGER_HURT_NO_CLIENTS 8 // Spawnflag that makes trigger_push spawn turned OFF +#define SF_TRIGGER_HURT_CLIENTONLYFIRE 16 // Trigger hurt will only fire its target if it is hurting a client +#define SF_TRIGGER_HURT_CLIENTONLYTOUCH 32 // Only clients may touch this trigger + +/** + * trigger_auto + */ +#define SF_AUTO_FIREONCE 0x0001 +#define SF_AUTO_NORESET 0x0002 + +/** + * trigger_relay + */ +#define SF_RELAY_FIREONCE 0x0001 + +/** + * multi_manager + */ +#define SF_MULTIMAN_CLONE 0x80000000 +#define SF_MULTIMAN_THREAD 0x00000001 + +/** + * env_render + * @note These are flags to indicate masking off various render parameters that + * are usually copied to the targets + */ +#define SF_RENDER_MASKFX (1<<0) +#define SF_RENDER_MASKAMT (1<<1) +#define SF_RENDER_MASKMODE (1<<2) +#define SF_RENDER_MASKCOLOR (1<<3) + +/** + * trigger_changelevel + */ +#define SF_CHANGELEVEL_USEONLY 0x0002 + +/** + * trigger_endsection + */ +#define SF_ENDSECTION_USEONLY 0x0001 + +/** + * trigger_camera + */ +#define SF_CAMERA_PLAYER_POSITION 1 +#define SF_CAMERA_PLAYER_TARGET 2 +#define SF_CAMERA_PLAYER_TAKECONTROL 4 + +/** + * func_rotating + */ +#define SF_BRUSH_ROTATE_Y_AXIS 0 +#define SF_BRUSH_ROTATE_INSTANT 1 +#define SF_BRUSH_ROTATE_BACKWARDS 2 +#define SF_BRUSH_ROTATE_Z_AXIS 4 +#define SF_BRUSH_ROTATE_X_AXIS 8 +#define SF_PENDULUM_AUTO_RETURN 16 +#define SF_PENDULUM_PASSABLE 32 +#define SF_BRUSH_ROTATE_SMALLRADIUS 128 +#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 +#define SF_BRUSH_ROTATE_LARGERADIUS 512 + +/** + * triggers + */ +#define SF_TRIGGER_ALLOWMONSTERS 1 // Monsters allowed to fire this trigger +#define SF_TRIGGER_NOCLIENTS 2 // Players not allowed to fire this trigger +#define SF_TRIGGER_PUSHABLES 4 // Only pushables can fire this trigger + +#define SF_TRIG_PUSH_ONCE 1 + +/** +* trigger_multiple +*/ +#define SF_TRIGGER_MULTIPLE_NOTOUCH 0x0001 + +/** +* trigger_counter +*/ +#define SF_TRIGGER_COUNTER_NOMESSAGE 0x0001 + +/** + * func_breakable + */ +#define SF_BREAK_TRIGGER_ONLY 1 // May only be broken by trigger +#define SF_BREAK_TOUCH 2 // Can be 'crashed through' by running player (plate glass) +#define SF_BREAK_PRESSURE 4 // Can be broken by a player standing on it +#define SF_BREAK_CROWBAR 256 // Instant break if hit with crowbar + +/** + * func_pushable (also func_breakable, so don't collide with those flags) + */ +#define SF_PUSH_BREAKABLE 128 + +/** + * light_spawn + */ +#define SF_LIGHT_START_OFF 1 +#define SPAWNFLAG_NOMESSAGE 1 +#define SPAWNFLAG_NOTOUCH 1 +#define SPAWNFLAG_DROIDONLY 4 +#define SPAWNFLAG_USEONLY 1 // Can't be touched, must be used (buttons) + +/** + * Monster Spawnflags + */ +#define SF_MONSTER_WAIT_TILL_SEEN 1 // Spawnflag that makes monsters wait until player can see them before attacking +#define SF_MONSTER_GAG 2 // No idle noises from this monster +#define SF_MONSTER_HITMONSTERCLIP 4 +#define SF_MONSTER_PRISONER 16 // Monster won't attack anyone, no one will attacke him +#define SF_MONSTER_WAIT_FOR_SCRIPT 128 // Spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked +#define SF_MONSTER_PREDISASTER 256 // This is a predisaster scientist or barney; influences how they speak +#define SF_MONSTER_FADECORPSE 512 // Fade out corpse after death +#define SF_MONSTER_FALL_TO_GROUND 0x80000000 +#define SF_MONSTER_TURRET_AUTOACTIVATE 32 +#define SF_MONSTER_TURRET_STARTINACTIVE 64 +#define SF_MONSTER_WAIT_UNTIL_PROVOKED 64 // Don't attack the player unless provoked + +/** + * info_decal + */ +#define SF_DECAL_NOTINDEATHMATCH 2048 + +/** + * worldspawn + */ +#define SF_WORLD_DARK 0x0001 // Fade from black at startup +#define SF_WORLD_TITLE 0x0002 // Display game title at startup +#define SF_WORLD_FORCETEAM 0x0004 // Force teams + +/** + * Set this bit on guns and stuff that should never respawn + */ +#define SF_NORESPAWN (1<<30) + +/** + * @endsection + */ + +/** + * Train status values + */ +#define TRAIN_ACTIVE 0x80 +#define TRAIN_NEW 0xc0 + +#define TRAIN_OFF 0x00 +#define TRAIN_NEUTRAL 0x01 +#define TRAIN_SLOW 0x02 +#define TRAIN_MEDIUM 0x03 +#define TRAIN_FAST 0x04 +#define TRAIN_BACK 0x05 + +/** + * Valve Mod Weapon Constants + */ +#define HLI_HEALTHKIT 1 +#define HLI_ANTIDOTE 2 +#define HLI_SECURITY 3 +#define HLI_BATTERY 4 + +#define HLW_NONE 0 +#define HLW_CROWBAR 1 +#define HLW_GLOCK 2 +#define HLW_PYTHON 3 +#define HLW_MP5 4 +#define HLW_CHAINGUN 5 +#define HLW_CROSSBOW 6 +#define HLW_SHOTGUN 7 +#define HLW_RPG 8 +#define HLW_GAUSS 9 +#define HLW_EGON 10 +#define HLW_HORNETGUN 11 +#define HLW_HANDGRENADE 12 +#define HLW_TRIPMINE 13 +#define HLW_SATCHEL 14 +#define HLW_SNARK 15 +#define HLW_SUIT 31 +#define HLW_ALLWEAPONS (~(1< 0) { + if(get_user_flags(id) & ADMIN_IMMUNITY) + access = "Head Admin"; + if(get_user_flags(id) & ADMIN_LEVEL_E) + access = "Honorary"; + if(get_user_flags(id) & ADMIN_LEVEL_H) + access = "VIP LVL 3"; + if(get_user_flags(id) & ADMIN_LEVEL_G) + access = "VIP LVL 2"; + if(get_user_flags(id) & ADMIN_LEVEL_F) + access = "VIP LVL 1"; + if(get_user_flags(id) & ADMIN_USER) + access = "User"; + } + else + access = "Server"; + return access; +} + +stock StringTimer(const Float:flRealTime, szOutPut[], const iSizeOutPut) { + static Float:flTime, iMinutes, iSeconds, iMiliSeconds, Float:iMili; + new string[12] + flTime = flRealTime; + if(flTime < 0.0) + flTime = 0.0; + iMinutes = floatround(flTime / 60, floatround_floor); + iSeconds = floatround(flTime - (iMinutes * 60), floatround_floor); + iMili = floatfract(flRealTime); + formatex(string, 11, "%.02f", iMili >= 0 ? iMili + 0.005 : iMili - 0.005); + iMiliSeconds = floatround(str_to_float(string) * 100, floatround_floor); + formatex(szOutPut, iSizeOutPut, "%02d:%02d.%02d", iMinutes, iSeconds, iMiliSeconds); +} + +stock Weapon_Converter(speed) { + new weapon_name[15]; + if(speed == 250) weapon_name = "USP [250]"; + if(speed == 245) weapon_name = "P90 [245]"; + if(speed == 240) weapon_name = "FAMAS [240]"; + if(speed == 235) weapon_name = "SG550 [235]"; + if(speed == 230) weapon_name = "M4A1 [230]"; + if(speed == 221) weapon_name = "AK47 [221]"; + if(speed == 220) weapon_name = "M249 [220]"; + if(speed == 210) weapon_name = "AWP [210]"; + return weapon_name; +} + +stock Weapon_ID_Converter(speed) { + new weapon_name[15]; + if(speed == 250) weapon_name = "weapon_usp"; + if(speed == 245) weapon_name = "weapon_p90"; + if(speed == 240) weapon_name = "weapon_famas"; + if(speed == 235) weapon_name = "weapon_sg550"; + if(speed == 230) weapon_name = "weapon_m4a1"; + if(speed == 221) weapon_name = "weapon_ak47"; + if(speed == 220) weapon_name = "weapon_m249"; + if(speed == 210) weapon_name = "weapon_awp"; + return weapon_name; +} + +stock ham_give_weapon(id, weapon[]) { + if(!equal(weapon,"weapon_",7)) + return 0; + new wEnt = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,weapon)); + if(!pev_valid(wEnt)) + return 0; + set_pev(wEnt,pev_spawnflags,SF_NORESPAWN); + dllfunc(DLLFunc_Spawn,wEnt); + if(!ExecuteHamB(Ham_AddPlayerItem,id,wEnt)) { + if(pev_valid(wEnt)) set_pev(wEnt,pev_flags,pev(wEnt,pev_flags) | FL_KILLME); + return 0; + } + ExecuteHamB(Ham_Item_AttachToPlayer,wEnt,id); + return 1; +} + +stock kz_vector_add(const Float:in1[], const Float:in2[], Float:out[]) { + out[0] = in1[0] + in2[0]; + out[1] = in1[1] + in2[1]; + out[2] = in1[2] + in2[2]; +} + +stock kz_vecotr_mul_scalar(const Float:vec[], Float:scalar, Float:out[]) { + out[0] = vec[0] * scalar; + out[1] = vec[1] * scalar; + out[2] = vec[2] * scalar; +} diff --git a/amxmodx/scripting/include/kz_sql.inc b/amxmodx/scripting/include/kz_sql.inc new file mode 100644 index 0000000..233d951 --- /dev/null +++ b/amxmodx/scripting/include/kz_sql.inc @@ -0,0 +1,435 @@ +#define ACCESS_H ADMIN_LEVEL_E +#define ACCESS_3 ADMIN_LEVEL_H +#define ACCESS_2 ADMIN_LEVEL_G +#define ACCESS_1 ADMIN_LEVEL_F +#define ACCESS_0 ADMIN_USER + +new Handle:g_SqlTuple; +new Handle:SqlConnection; +new g_Error[512]; + +// MapID in kz_maps SQL Table +new kz_mapID; +new kz_maptype[25]; +new delete_entity; + +new gMapName[64]; +new weapon_name[33]; +new Float:timer_time[33]; +new Float:Update_timer[33]; +// my time in top15 +new Float:kz_my_protime[33]; +new Float:kz_my_nubtime[33]; +// Speclist +new SpecList[33] = { true, ... }; +new SpecAdmImm[33]; +// SQL Config +new InvisUser[33]; +new InvisWater[33]; +new full_Invisible[33]; +new noTeleport[32]; +new ShowTime[33]; +new SaveCfgDate[33][40]; +enum { + TOP_NULL, + PRO_TOP, + NUB_TOP, + STATS_TOP, + WeaponTop, + PROGEN, + LAST_PRO10, + PRO_RECORDS, + PLAYERS_RANKING, + GENERAL_RANKING, + MAPS_STATISTIC, + PL_STATS, + WR_PLAY, + HELP +}; + +new const g_weaponsnames[][] = { + "", + "p228", "shield", "scout", "250", "240", "250", + "mac10", "240", "250", "250", "250", + "250", "210", "240", "240", "250", "250", + "210", "250", "220", "230", "230", "tmp", "210", + "250", "250", "235", "221", "250", "245", + "250", "250", "fn57", "mp5", "vest", "vesthelm", + "250", "hegren", "sgren", "defuser", "nvgs", "primammo", + "secammo", "km45", "9x19mm", "nighthawk", "228compact", + "12gauge", "autoshotgun", "mp", "c90", "cv47", "defender", + "clarion", "krieg552", "bullpup", "magnum", "d3au1", + "krieg550" +}; + +new const other_weapons_name[8][] = { + "weapon_p90", "weapon_famas", "weapon_sg552", "weapon_awp", + "weapon_m4a1", "weapon_m249", "weapon_ak47", "weapon_awp" +}; + +public plugin_sql() { + new ErrorCode; + SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,g_Error,511); + + if(!SqlConnection) { + server_print("[KZ] Could not connect to SQL database.!"); + return pause("a"); + } + + QueryInstallTable(); + + return PLUGIN_CONTINUE; +} + +public QueryHandle(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime) { + if(iFailState != TQUERY_SUCCESS) { + log_amx("[KZ] TOP15 SQL: SQL Error #%d - %s", iErrnum, szError); + client_print_color(0, print_chat, "$s ^x01 Error mySQL connect", prefix); + } + else if(iFailState == TQUERY_QUERY_FAILED) + set_fail_state("Query failed. QueryHandle %s", szError); + + SQL_FreeHandle(hQuery); + return PLUGIN_CONTINUE; +} + +public QueryInstallTable() { + new CreateInto[1001]; + + formatex(CreateInto, 1000, "CREATE TABLE IF NOT EXISTS `kz_pro15` (`map_id` INT(10) NOT NULL,`mapname` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`authid` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`name` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`time` DECIMAL(65,2) NOT NULL,`date` DATETIME NOT NULL)"); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", CreateInto); + + formatex(CreateInto, 1000, "CREATE TABLE IF NOT EXISTS `kz_nub15` (`map_id` INT(10) NOT NULL,`mapname` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`authid` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`name` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`time` DECIMAL(65,2) NOT NULL,`date` DATETIME NOT NULL,`checkpoints` DOUBLE(22,0) NOT NULL,`gocheck` DOUBLE(22,0) NOT NULL)"); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", CreateInto); + + formatex(CreateInto, 1000, "CREATE TABLE IF NOT EXISTS `kz_maps` (`id` INT(11) NOT NULL AUTO_INCREMENT,`mapname` VARCHAR(64) NOT NULL COLLATE 'utf8_general_ci',`type` VARCHAR(64) NULL COLLATE 'utf8_general_ci',`challenge` INT(3) NOT NULL DEFAULT '0',`entity` INT(2) NOT NULL DEFAULT '1',`start` VARCHAR(50) NULL COLLATE 'utf8_general_ci',`finish` VARCHAR(50) NULL COLLATE 'utf8_general_ci',PRIMARY KEY (`id`))"); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", CreateInto); +} + +public SQL_MapID() { + new s_Error[128], startposition[64], finishposition[64], p_start[3][64], p_finish[3][64] + new Handle:h_Query = SQL_PrepareQuery(SqlConnection, "SELECT * FROM `kz_maps` WHERE mapname='%s'", gMapName) + + if(!SQL_Execute(h_Query)) + SQL_QueryError(h_Query, s_Error, charsmax(s_Error)); + else { + new mapid = SQL_FieldNameToNum(h_Query, "id"); + new type = SQL_FieldNameToNum(h_Query, "type"); + new delentity = SQL_FieldNameToNum(h_Query, "entity"); + new start = SQL_FieldNameToNum(h_Query, "start"); + new finish = SQL_FieldNameToNum(h_Query, "finish"); + + while(SQL_MoreResults(h_Query)) { + kz_mapID = SQL_ReadResult(h_Query, mapid); + SQL_ReadResult(h_Query, type, kz_maptype, charsmax(kz_maptype)); + delete_entity = SQL_ReadResult(h_Query, delentity); + SQL_ReadResult(h_Query, start, startposition, charsmax(startposition)); + SQL_ReadResult(h_Query, finish, finishposition, charsmax(finishposition)); + SQL_NextRow(h_Query); + } + } + + if(!equali(startposition, "")) { + strtok(startposition, p_start[0], charsmax(p_start[]), startposition, charsmax(startposition), ' ', true); + strtok(startposition, p_start[1], charsmax(p_start[]), startposition, charsmax(startposition), ' ', true); + strtok(startposition, p_start[2], charsmax(p_start[]), startposition, charsmax(startposition), ' ', true); + DefaultStartPos[0] = str_to_float(p_start[0]); + DefaultStartPos[1] = str_to_float(p_start[1]); + DefaultStartPos[2] = str_to_float(p_start[2]); + Default_SF[0] = true; + } + else + Default_SF[0] = false; + + if(!equali(finishposition, "")) { + strtok(finishposition, p_finish[0], charsmax(p_finish[]), finishposition, charsmax(finishposition), ' ', true); + strtok(finishposition, p_finish[1], charsmax(p_finish[]), finishposition, charsmax(finishposition), ' ', true); + strtok(finishposition, p_finish[2], charsmax(p_finish[]), finishposition, charsmax(finishposition), ' ', true); + DefaultFinishPos[0] = str_to_float(p_finish[0]); + DefaultFinishPos[1] = str_to_float(p_finish[1]); + DefaultFinishPos[2] = str_to_float(p_finish[2]); + Default_SF[1] = true; + } + else + Default_SF[1] = false; + + if(equali(kz_maptype, "slide")) mapIsSlide = true; + if(equali(kz_maptype, "gravity")) mapIsGravity = true; + if(equali(kz_maptype, "")) kz_maptype = "n/a"; + + if(delete_entity) + for(new i = 0; i < sizeof(g_remove_ent); i++) + sx_remove_entity(g_remove_ent[i], "classname", 0, ""); + + if(!kz_mapID) { + new Handle:h_Query2 = SQL_PrepareQuery(SqlConnection, "INSERT INTO `kz_maps` (`mapname`) VALUES ('%s');", gMapName); + if(SQL_Execute(h_Query2)) + kz_mapID = SQL_GetInsertId(h_Query2); + SQL_FreeHandle(h_Query2); + } + + SQL_FreeHandle(h_Query); + + server_print("[KZ_SQL] ID Map = %d", kz_mapID); + server_print("[KZ_SQL] Type map = %s", kz_maptype); + + return PLUGIN_HANDLED; +} + +public SQL_StartFinish(bool:L, Float:position[3]) { + if(L) + Default_SF[0] = true; + else + Default_SF[1] = true; + + new createinto[1001]; + formatex(createinto, sizeof createinto - 1, "UPDATE `kz_maps` SET `%s` = '%f %f %f' WHERE (`id` = %d)", (L ? "start":"finish"), position[0], position[1], position[2], kz_mapID); + SQL_ThreadQuery(g_SqlTuple, "SQL_WorkHandle", createinto); +} + +public SQL_StatsAdd(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime) { + new id = cData[0]; + new style = cData[1]; + new Float:time = Update_timer[id]; + new check = cData[3]; + new gocheck = cData[4]; + if(iFailState != TQUERY_SUCCESS) { + log_amx("[KZ] TOP15 SQL: SQL Error #%d - %s", iErrnum, szError); + client_print_color(0, print_chat, "%s^x01 %F", prefix, LANG_PLAYER, "KZ_TOP15_SQL_ERROR"); + } + new checkpoints[32], gochecks[32]; + new createinto[1001]; + new name[32], recdata[64]; + get_user_name(id, name, 31); + get_time("%Y%m%d%H%M%S", recdata, sizeof recdata - 1); + new wpn = get_user_weapon(id); + replace_all(name, 31, "'", ""); + + new bool:user_weapon = false; + new weapon = get_user_weapon(id); + get_weaponname(weapon, weapon_name, charsmax(weapon_name)); + + for(new i = 0; i < 8; i++) + if(equali(other_weapons_name[i], weapon_name)) + user_weapon = true; + + if(SQL_NumResults(hQuery) == 0) { + formatex(checkpoints, 31, ", %d", check); + formatex(gochecks, 31, ", %d", gocheck); + + if(user_weapon && get_pcvar_num(sv_airaccelerate) == 10) { + formatex(createinto, sizeof createinto - 1, "INSERT INTO `%s` VALUES (%d, '%s', '%s', '%s', '%s', '%f', '%s'%s%s)", style == PRO_TOP ? "kz_weapon_pro" : "kz_weapon_nub", kz_mapID, gMapName, g_weaponsnames[wpn], kz_authid[id], name, time, recdata, style == PRO_TOP ? "" : checkpoints, style == PRO_TOP ? "" : gochecks); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", createinto); + GetNewRank(id, style, true); + } + else { + formatex(createinto, sizeof createinto - 1, "INSERT INTO `%s` VALUES (%d, '%s', '%s', '%s', '%f', '%s'%s%s)", style == PRO_TOP ? "kz_pro15" : "kz_nub15", kz_mapID, gMapName, kz_authid[id], name, time, recdata, style == PRO_TOP ? "" : checkpoints, style == PRO_TOP ? "" : gochecks); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", createinto); + GetNewRank(id, style, false); + } + } + else { + new Float:oldtime, Float:thetime; + SQL_ReadResult(hQuery, 0, oldtime); + + if(time < oldtime) { + formatex(checkpoints, 31, ", checkpoints=%d", check); + formatex(gochecks, 31, ", gocheck=%d", gocheck); + thetime = oldtime - time; + + show_finish_message(id, thetime, false, true); + + if(user_weapon && get_pcvar_num(sv_airaccelerate) == 10) { + formatex(createinto, sizeof createinto - 1, "UPDATE `%s` SET time='%f', date='%s' %s%s WHERE map_id=%d AND weapon='%s' AND authid='%s'", style == PRO_TOP ? "kz_weapon_pro" : "kz_weapon_nub", time, recdata, style == PRO_TOP ? "" : checkpoints, style == PRO_TOP ? "" : gochecks, kz_mapID, g_weaponsnames[wpn], kz_authid[id]); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", createinto); + GetNewRank(id, style, true); + } + else { + formatex(createinto, sizeof createinto - 1, "UPDATE `%s` SET time='%f', date='%s' %s%s WHERE map_id=%d AND authid='%s'", style == PRO_TOP ? "kz_pro15" : "kz_nub15", time, recdata, style == PRO_TOP ? "" : checkpoints, style == PRO_TOP ? "" : gochecks, kz_mapID, kz_authid[id]); + SQL_ThreadQuery(g_SqlTuple, "QueryHandle", createinto); + GetNewRank(id, style, false); + } + } + else { + thetime = time - oldtime; + show_finish_message(id, thetime, false, false); + } + } + + return PLUGIN_HANDLED; +} + +stock GetNewRank(id, type, bool:user_weapon) { + new createinto[1000]; + + new cData[2]; + cData[0] = id; + cData[1] = type; + new wpn = get_user_weapon(id); + + if(user_weapon && get_pcvar_num(sv_airaccelerate) == 10) + formatex(createinto, charsmax(createinto), "SELECT authid FROM `%s` WHERE map_id=%d AND weapon='%s' ORDER BY time", type == PRO_TOP ? "kz_weapon_pro" : "kz_weapon_nub", kz_mapID, g_weaponsnames[wpn]); + else + formatex(createinto, charsmax(createinto), "SELECT authid FROM `%s` WHERE map_id=%d ORDER BY time", type == PRO_TOP ? "kz_pro15" : "kz_nub15", kz_mapID); + + SQL_ThreadQuery(g_SqlTuple, "GetNewRank_QueryHandler", createinto, cData, 2); +} + +public GetNewRank_QueryHandler(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime) { + new id = cData[0]; + if(iFailState != TQUERY_SUCCESS) + return log_amx("TOP15 SQL: SQL Error #%d - %s", iErrnum, szError) + + new authid[32], namez[32], i = 0; + get_user_name(id, namez, 31); + + new bool:user_weapon = false; + new weapon = get_user_weapon(id); + get_weaponname(weapon, weapon_name, charsmax(weapon_name)); + + for(new i = 0; i < 8; i++) + if(equali(other_weapons_name[i], weapon_name)) + user_weapon = true; + + while(SQL_MoreResults(hQuery)) { + i++; + SQL_ReadResult(hQuery, 0, authid, 31); + if(equal(authid, kz_authid[id])) { + if(user_weapon) + client_print_color(0, print_chat, "^x04%s^x03 %s^x04 is now ^x03%d^x04 in^x03 %s^x04",prefix, namez, i, cData[1] == PRO_TOP ? "Professional Weapon Top" : "General Weapon Top"); + else + client_print_color(0, print_chat, "^x04%s^x03 %s^x04 is now ^x03%d^x04 in^x03 %s^x04",prefix, namez, i, cData[1] == PRO_TOP ? "Professional Top" : "General Top"); + break; + } + SQL_NextRow(hQuery); + } + + SQL_FreeHandle(hQuery); + return PLUGIN_CONTINUE; +} + +public mytime(id, type) { + new createinto[256], cData[2]; + cData[0] = id; + cData[1] = type; + formatex(createinto, sizeof createinto - 1, "SELECT * FROM %s WHERE map_id=%d AND authid='%s'", type == PRO_TOP ? "kz_pro15" : "kz_nub15", kz_mapID, kz_authid[id]); + SQL_ThreadQuery(g_SqlTuple, "SQL_MyTimeHandle", createinto, cData, 2); +} + +public SQL_MyTimeHandle(failstate, Handle:hQuery, error[], errcode, cData[], iSize, Float:fQueueTime) { + new id = cData[0]; + new type = cData[1]; + if(failstate == TQUERY_CONNECT_FAILED) + set_fail_state("Could not connect to database."); + else if(failstate == TQUERY_QUERY_FAILED) + set_fail_state("Query failed. SQL_MyTimeHandle %s", error); + else if(errcode) + log_amx("Error on query: %s", error); + else { + if(SQL_NumResults(hQuery)) { + if(type == PRO_TOP) + SQL_ReadResult(hQuery, 4, kz_my_protime[id]); + else + SQL_ReadResult(hQuery, 4, kz_my_nubtime[id]); + } + else { + if(type == PRO_TOP) + kz_my_protime[id] = 0.0; + else + kz_my_nubtime[id] = 0.0; + } + } + SQL_FreeHandle(hQuery); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SQL CFG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +public SQL_Config(id) { + new createinto[128], cData[1]; + cData[0] = id; + formatex(createinto, sizeof createinto - 1, "SELECT * FROM kzp_players WHERE auth='%s'", kz_authid[id]); + g_SqlTuple = SQL_MakeStdTuple(); + SQL_ThreadQuery(g_SqlTuple, "SQL_ConfigHandle", createinto, cData, 1); +} + +public SQL_ConfigHandle(failstate, Handle:hQuery, error[], errcode, cData[], iSize, Float:fQueueTime) { + new id = cData[0]; + if(failstate == TQUERY_CONNECT_FAILED) + set_fail_state("Could not connect to database."); + else if(failstate == TQUERY_QUERY_FAILED ) + set_fail_state("Query failed. SQL_Config %s", error); + else if(errcode) + log_amx("Error on query: %s", error); + else { + if(SQL_NumResults(hQuery)) { + ShowTime[id] = SQL_ReadResult(hQuery, 8); + InvisUser[id] = SQL_ReadResult(hQuery, 9); + InvisWater[id] = SQL_ReadResult(hQuery, 10); + full_Invisible[id] = SQL_ReadResult(hQuery, 11); + noTeleport[id] = SQL_ReadResult(hQuery, 12); + SpecList[id] = SQL_ReadResult(hQuery, 13); + SpecAdmImm[id] = SQL_ReadResult(hQuery, 14); + SQL_ReadResult(hQuery, 4, SaveCfgDate[id], charsmax(SaveCfgDate)); + } + else { + InvisUser[id] = 0; + InvisWater[id] = 0; + full_Invisible[id] = 0; + noTeleport[id] = 0; + SpecList[id] = 1; + SpecAdmImm[id] = 0; + ShowTime[id] = 2; + } + + //server_print("user: %d, i_user: %d, i_water: %d, fullinvis: %d, notp: %d, spec: %d, specadm: %d, stime: %d, lastsave: %s", id, InvisUser[id], InvisWater[id], full_Invisible[id], noTeleport[id], SpecList[id], SpecAdmImm[id], ShowTime[id], SaveCfgDate[id]); + } + SQL_FreeHandle(hQuery); +} + + +public SQL_ConfigSave(id) { + new createinto[128], cData[1]; + cData[0] = id; + formatex(createinto, sizeof createinto - 1, "SELECT * FROM kzp_players WHERE auth='%s'", kz_authid[id]); + SQL_ThreadQuery(g_SqlTuple, "SQL_ConfigSaveHandle", createinto, cData, 1); +} + +public SQL_ConfigSaveHandle(failstate, Handle:hQuery, error[], errcode, cData[], iSize, Float:fQueueTime) { + new id = cData[0]; + new nowdate[40]; + get_time("%Y-%m-%d %H:%M:%S", nowdate, sizeof nowdate - 1); + SaveCfgDate[id] = nowdate; + + if(failstate == TQUERY_CONNECT_FAILED) + set_fail_state("Could not connect to database."); + else if(failstate == TQUERY_QUERY_FAILED) + set_fail_state("Query failed. SQL_ConfigSaveHandle %s", error); + else if(errcode) + log_amx("Error on query: %s", error); + else { + if(SQL_NumResults(hQuery)) { + new createinto[1001]; + formatex(createinto, sizeof createinto - 1, "UPDATE `kzp_players` SET `showTime` = %d,`invisUser` = %d,`invisWater` = %d,`invisFull` = %d,`noTeleport` = %d,`specList` = %d,`specAdmin` = %d, `date` = '%s' WHERE (`auth` = '%s')", ShowTime[id], InvisUser[id], InvisWater[id], full_Invisible[id], noTeleport[id], SpecList[id], SpecAdmImm[id], SaveCfgDate[id], kz_authid[id]); + SQL_ThreadQuery(g_SqlTuple, "SQL_WorkHandle", createinto); + client_print_color(id, print_chat, "^x01%s^x03 The config was saved successfully.", prefix); + } + /*else { + new createinto[1001]; + formatex(createinto, sizeof createinto - 1, "INSERT INTO `kzp_players` VALUES (null, '%s', %d, %d, %d, %d, %d, %d, %d, '%s')", kz_authid[id], ShowTime[id], InvisUser[id], InvisWater[id], full_Invisible[id], noTeleport[id], SpecList[id], SpecAdmImm[id], SaveCfgDate[id]); + SQL_ThreadQuery(g_SqlTuple, "SQL_WorkHandle", createinto); + client_print_color(id, print_chat, "^x01%s^x03 The config was saved successfully.", prefix); + }*/ + } + SQL_FreeHandle(hQuery); +} + +public SQL_WorkHandle(failstate, Handle:hQuery, error[], errcode, cData[], iSize, Float:fQueueTime) { + if(failstate == TQUERY_CONNECT_FAILED) + set_fail_state("Could not connect to database."); + else if(failstate == TQUERY_QUERY_FAILED) + set_fail_state("Query failed. SQL_WorkHandle %s", error); + else if(errcode) + log_amx("Error on query: %s", error); + SQL_FreeHandle(hQuery); +} diff --git a/amxmodx/scripting/include/lang.inc b/amxmodx/scripting/include/lang.inc new file mode 100644 index 0000000..a88c66c --- /dev/null +++ b/amxmodx/scripting/include/lang.inc @@ -0,0 +1,119 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Language Functions +// + +#if defined _lang_included + #endinput +#endif +#define _lang_included + +/** + * Returns the number of languages loaded. + * + * @return Number of languages loaded. + */ +native get_langsnum(); + +/** + * Returns the two-letter name of a language returned by get_langsnum() + * + * @param id Language index, starting at 0 + * @param name Buffer to store the name in + * + * @noreturn + */ +native get_lang(id, name[3]); + +/** + * Registers a dictionary file, making sure the words are in the dictionary. + * + * @note The file should be in "addons/amxmodx/data/lang", but only the name + * needs to be given. For example, register_dictionary("file.txt") will + * be "addons/amxmodx/data/lang/file.txt". + * + * @param filename Dictionary file name + * + * @return On success, the function will return 1, otherwise it will + * return 0 if the file couldn't be found or opened, and -1 if + * the dictionary was already registered by a plugin + */ +native register_dictionary(const filename[]); + +/** + * Checks if the language is loaded. + * + * @return 1 if it is, 0 otherwise + */ +native lang_exists(const name[]); + +enum TransKey +{ + TransKey_Bad = -1, +}; + +/** + * Creates a new or finds an existing translation key. + * + * @param key Key to create or find + * + * @return Key index + */ +native TransKey:CreateLangKey(const key[]); + +/** + * Finds a translation key index without adding on failure. + * + * @param key Key to search for + * + * @return Key index, or -1 if not found + */ +native TransKey:GetLangTransKey(const key[]); + +/** + * Adds a new translation. + * + * @param lang Two-letter language name + * @param key Language key + * @param phrase Translated text + * + * @noreturn + */ +native AddTranslation(const lang[3], TransKey:key, const phrase[]); + +/** + * Looks up the translation of the key for the given type. + * + * @note This does NOT format the output text! For example, if the key + * contains %s, the outputted text will also contain %s. + * @note LANG_PLAYER is invalid in this, use a player index or LANG_SERVER. + * + * @param Output Buffer to store the output in + * @param OutputSize Maximum buffer size + * @param Key Language key + * @param id Client index or LANG_SERVER + * + * @return 1 on success, 0 otherwise + */ +native LookupLangKey(Output[], OutputSize, const Key[], const &id); + +/** + * Sets the global language target. + * + * @note This is useful for creating functions + * that will be compatible with the %l format specifier. Note that invalid + * indexes can be specified but the error will occur during translation, + * not during this function call. + * + * @param client Client index or LANG_SERVER + * @noreturn + */ +native SetGlobalTransTarget(client); diff --git a/amxmodx/scripting/include/message_const.inc b/amxmodx/scripting/include/message_const.inc new file mode 100644 index 0000000..f9b07d6 --- /dev/null +++ b/amxmodx/scripting/include/message_const.inc @@ -0,0 +1,1130 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Message Constants +// + +#if defined _message_const_included + #endinput +#endif +#define _message_const_included + +/** + * Destination types for message_begin() + */ +#define MSG_BROADCAST 0 // Unreliable to all +#define MSG_ONE 1 // Reliable to one (msg_entity) +#define MSG_ALL 2 // Reliable to all +#define MSG_INIT 3 // Write to the init string +#define MSG_PVS 4 // Ents in PVS of org +#define MSG_PAS 5 // Ents in PAS of org +#define MSG_PVS_R 6 // Reliable to PVS +#define MSG_PAS_R 7 // Reliable to PAS +#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped) +#define MSG_SPEC 9 // Sends to all spectator proxies + +/** + * Hardcoded message types for message_begin() + * + * @note Look at the actual HLSDK for details + */ +#define SVC_BAD 0 +#define SVC_NOP 1 +#define SVC_DISCONNECT 2 +#define SVC_EVENT 3 +#define SVC_VERSION 4 +#define SVC_SETVIEW 5 +#define SVC_SOUND 6 +#define SVC_TIME 7 +#define SVC_PRINT 8 +#define SVC_STUFFTEXT 9 +#define SVC_SETANGLE 10 +#define SVC_SERVERINFO 11 +#define SVC_LIGHTSTYLE 12 +#define SVC_UPDATEUSERINFO 13 +#define SVC_DELTADESCRIPTION 14 +#define SVC_CLIENTDATA 15 +#define SVC_STOPSOUND 16 +#define SVC_PINGS 17 +#define SVC_PARTICLE 18 +#define SVC_DAMAGE 19 +#define SVC_SPAWNSTATIC 20 +#define SVC_EVENT_RELIABLE 21 +#define SVC_SPAWNBASELINE 22 +#define SVC_TEMPENTITY 23 +#define SVC_SETPAUSE 24 +#define SVC_SIGNONNUM 25 +#define SVC_CENTERPRINT 26 +#define SVC_KILLEDMONSTER 27 +#define SVC_FOUNDSECRET 28 +#define SVC_SPAWNSTATICSOUND 29 +#define SVC_INTERMISSION 30 +#define SVC_FINALE 31 +#define SVC_CDTRACK 32 +#define SVC_RESTORE 33 +#define SVC_CUTSCENE 34 +#define SVC_WEAPONANIM 35 +#define SVC_DECALNAME 36 +#define SVC_ROOMTYPE 37 +#define SVC_ADDANGLE 38 +#define SVC_NEWUSERMSG 39 +#define SVC_PACKETENTITIES 40 +#define SVC_DELTAPACKETENTITIES 41 +#define SVC_CHOKE 42 +#define SVC_RESOURCELIST 43 +#define SVC_NEWMOVEVARS 44 +#define SVC_RESOURCEREQUEST 45 +#define SVC_CUSTOMIZATION 46 +#define SVC_CROSSHAIRANGLE 47 +#define SVC_SOUNDFADE 48 +#define SVC_FILETXFERFAILED 49 +#define SVC_HLTV 50 +#define SVC_DIRECTOR 51 +#define SVC_VOICEINIT 52 +#define SVC_VOICEDATA 53 +#define SVC_SENDEXTRAINFO 54 +#define SVC_TIMESCALE 55 +#define SVC_RESOURCELOCATION 56 +#define SVC_SENDCVARVALUE 57 +#define SVC_SENDCVARVALUE2 58 + +/** + * Flags for set_msg_block() + */ +#define BLOCK_NOT 0 +#define BLOCK_ONCE 1 +#define BLOCK_SET 2 + +/** + * Message argument types used with get_msg_argtype() and set_msg_arg_* + */ +enum +{ + ARG_BYTE = 1, /* int */ + ARG_CHAR, /* int */ + ARG_SHORT, /* int */ + ARG_LONG, /* int */ + ARG_ANGLE, /* float */ + ARG_COORD, /* float */ + ARG_STRING, /* string */ + ARG_ENTITY, /* int */ +}; + +/** + * @section TempEntity messages for message_begin() + */ + +/** + * Beam effect between two points + * + * @note + * write_byte(TE_BEAMPOINTS) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ +#define TE_BEAMPOINTS 0 + +/** + * Beam effect between a point and an entity + * + * @note + * write_byte(TE_BEAMENTPOINT) + * write_short(start entity) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ + #define TE_BEAMENTPOINT 1 + +/** + * Particle effect plus ricochet sound + * + * @note + * write_byte(TE_GUNSHOT) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + */ +#define TE_GUNSHOT 2 + +/** + * Additive sprite, 2 dynamic lights, flickering particles, explosion sound, + * move vertically 8 pps + * + * @note + * write_byte(TE_EXPLOSION) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(sprite index) + * write_byte(scale in 0.1's) + * write_byte(framerate) + * write_byte(flags) + */ +#define TE_EXPLOSION 3 + +/** + * Flags for the TE_EXPLOSION effect, controlling its performance and aesthetic + * features + */ +#define TE_EXPLFLAG_NONE 0 // All flags clear makes default Half-Life explosion +#define TE_EXPLFLAG_NOADDITIVE 1 // Sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite) +#define TE_EXPLFLAG_NODLIGHTS 2 // Do not render dynamic lights +#define TE_EXPLFLAG_NOSOUND 4 // Do not play client explosion sound +#define TE_EXPLFLAG_NOPARTICLES 8 // Do not draw particles + +/** + * Quake1 "tarbaby" explosion with sound + * + * @note + * write_byte(TE_TAREXPLOSION) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + */ +#define TE_TAREXPLOSION 4 + +/** + * Alphablend sprite, move vertically 30pps + * + * @note + * write_byte(TE_SMOKE) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(sprite index) + * write_byte(scale in 0.1's) + * write_byte(framerate) + */ +#define TE_SMOKE 5 + +/** + * Tracer effect from point to point + * + * @note + * write_byte(TE_TRACER) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + */ +#define TE_TRACER 6 + +/** + * TE_BEAMPOINTS with simplified parameters + * + * @note + * write_byte(TE_LIGHTNING) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + * write_byte(life in 0.1's) + * write_byte(width in 0.1's) + * write_byte(amplitude in 0.01's) + * write_short(sprite model index) + */ +#define TE_LIGHTNING 7 + +/** + * TE_BEAMENTS + * + * @note + * write_byte(TE_BEAMENTS) + * write_short(start entity) + * write_short(end entity) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ +#define TE_BEAMENTS 8 + +/** + * 8 random tracers with gravity, ricochet sprite + * + * @note + * write_byte(TE_SPARKS) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + */ +#define TE_SPARKS 9 + +/** + * Quake1 lava splash + * + * @note + * write_byte(TE_LAVASPLASH) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + */ +#define TE_LAVASPLASH 10 + +/** + * Quake1 teleport splash + * + * @note + * write_byte(TE_TELEPORT) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + */ +#define TE_TELEPORT 11 + +/** + * Quake1 colormaped (base palette) particle explosion with sound + * + * @note + * write_byte(TE_EXPLOSION2) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(starting color) + * write_byte(num colors) + */ +#define TE_EXPLOSION2 12 + +/** + * Decal from the .BSP file + * + * @note + * write_byte(TE_BSPDECAL) + * write_coord(position.x) decal position (center of texture in world) + * write_coord(position.y) + * write_coord(position.z) + * write_short(texture index of precached decal texture name) + * write_short(entity index) + * [optional - write_short(index of model of above entity) only included if previous short is non-zero (not the world)] + */ +#define TE_BSPDECAL 13 + +/** + * Tracers moving toward a point + * + * @note + * write_byte(TE_IMPLOSION) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(radius) + * write_byte(count) + * write_byte(life in 0.1's) + */ +#define TE_IMPLOSION 14 + +/** + * Line of moving glow sprites with gravity, fadeout, and collisions + * + * @note + * write_byte(TE_SPRITETRAIL) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + * write_short(sprite index) + * write_byte(count) + * write_byte(life in 0.1's) + * write_byte(scale in 0.1's) + * write_byte(velocity along vector in 10's) + * write_byte(randomness of velocity in 10's) + */ +#define TE_SPRITETRAIL 15 + +/** + * Additive sprite, plays 1 cycle + * + * @note + * write_byte(TE_SPRITE) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(sprite index) + * write_byte(scale in 0.1's) + * write_byte(brightness) + */ +#define TE_SPRITE 17 + +/** + * A beam with a sprite at the end + * + * @note + * write_byte(TE_BEAMSPRITE) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + * write_short(beam sprite index) + * write_short(end sprite index) + */ +#define TE_BEAMSPRITE 18 + +/** + * Screen aligned beam ring, expands to max radius over lifetime + * + * @note + * write_byte(TE_BEAMTORUS) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(axis.x) + * write_coord(axis.y) + * write_coord(axis.z) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ +#define TE_BEAMTORUS 19 + +/** + * Disk that expands to max radius over lifetime + * + * @note + * write_byte(TE_BEAMDISK) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(axis.x) + * write_coord(axis.y) + * write_coord(axis.z) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ +#define TE_BEAMDISK 20 + +/** + * Cylinder that expands to max radius over lifetime + * + * @note + * write_byte(TE_BEAMCYLINDER) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(axis.x) + * write_coord(axis.y) + * write_coord(axis.z) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ +#define TE_BEAMCYLINDER 21 + +/** + * Create a line of decaying beam segments until entity stops moving + * + * @note + * write_byte(TE_BEAMFOLLOW) + * write_short(entity:attachment to follow) + * write_short(sprite index) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + */ +#define TE_BEAMFOLLOW 22 + +/** + * TE_GLOWSPRITE + * + * @note + * write_byte(TE_GLOWSPRITE) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(model index) + * write_byte(scale / 10) + * write_byte(size) + * write_byte(brightness) + */ +#define TE_GLOWSPRITE 23 + +/** + * Connect a beam ring to two entities + * + * @note + * write_byte(TE_BEAMRING) + * write_short(start entity) + * write_short(end entity) + * write_short(sprite index) + * write_byte(starting frame) + * write_byte(frame rate in 0.1's) + * write_byte(life in 0.1's) + * write_byte(line width in 0.1's) + * write_byte(noise amplitude in 0.01's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(brightness) + * write_byte(scroll speed in 0.1's) + */ +#define TE_BEAMRING 24 + +/** + * Oriented shower of tracers + * + * @note + * write_byte(TE_STREAK_SPLASH) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(vector.x) + * write_coord(vector.y) + * write_coord(vector.z) + * write_byte(color) + * write_short(count) + * write_short(base speed) + * write_short(random velocity) + */ +#define TE_STREAK_SPLASH 25 + +/** + * Dynamic light, effect world, minor entity effect + * + * @note + * write_byte(TE_DLIGHT) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(radius in 10's) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(life in 10's) + * write_byte(decay rate in 10's) + */ +#define TE_DLIGHT 27 + +/** + * Point entity light, no world effect + * + * @note + * write_byte(TE_ELIGHT) + * write_short(entity:attachment to follow) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(radius) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + * write_byte(life in 0.1's) + * write_coord(decay rate) + */ +#define TE_ELIGHT 28 + +/** + * TE_TEXTMESSAGE + * + * @note + * write_byte(TE_TEXTMESSAGE) + * write_byte(channel) + * write_short(x) -1 = center) + * write_short(y) -1 = center) + * write_byte(effect) 0 = fade in/fade out, 1 is flickery credits, 2 is write out (training room) + * write_byte(red) - text color + * write_byte(green) + * write_byte(blue) + * write_byte(alpha) + * write_byte(red) - effect color + * write_byte(green) + * write_byte(blue) + * write_byte(alpha) + * write_short(fadein time) + * write_short(fadeout time) + * write_short(hold time) + * [optional] write_short(fxtime) time the highlight lags behing the leading text in effect 2 + * write_string(text message) 512 chars max string size + */ +#define TE_TEXTMESSAGE 29 + +/** + * TE_LINE + * + * @note + * write_byte(TE_LINE) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + * write_short(life in 0.1 s) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + */ +#define TE_LINE 30 + +/** + * TE_BOX + * + * @note + * write_byte(TE_BOX) + * write_coord(boxmins.x) + * write_coord(boxmins.y) + * write_coord(boxmins.z) + * write_coord(boxmaxs.x) + * write_coord(boxmaxs.y) + * write_coord(boxmaxs.z) + * write_short(life in 0.1 s) + * write_byte(red) + * write_byte(green) + * write_byte(blue) + */ +#define TE_BOX 31 + +/** + * Kill all beams attached to entity + * + * @note + * write_byte(TE_KILLBEAM) + * write_short(entity) + */ +#define TE_KILLBEAM 99 + +/** + * TE_LARGEFUNNEL + * + * @note + * write_byte(TE_LARGEFUNNEL) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(sprite index) + * write_short(flags) + */ +#define TE_LARGEFUNNEL 100 + +/** + * Particle spray + * + * @note + * write_byte(TE_BLOODSTREAM) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(vector.x) + * write_coord(vector.y) + * write_coord(vector.z) + * write_byte(color) + * write_byte(speed) + */ +#define TE_BLOODSTREAM 101 + +/** + * Line of particles every 5 units, dies in 30 seconds + * + * @note + * write_byte(TE_SHOWLINE) + * write_coord(startposition.x) + * write_coord(startposition.y) + * write_coord(startposition.z) + * write_coord(endposition.x) + * write_coord(endposition.y) + * write_coord(endposition.z) + */ +#define TE_SHOWLINE 102 + +/** + * Particle spray + * + * @note + * write_byte(TE_BLOOD) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(vector.x) + * write_coord(vector.y) + * write_coord(vector.z) + * write_byte(color) + * write_byte(speed) + */ +#define TE_BLOOD 103 + +/** + * Decal applied to a brush entity (not the world) + * + * @note + * write_byte(TE_DECAL) + * write_coord(position.x) decal position (center of texture in world) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(texture index of precached decal texture name) + * write_short(entity index) + */ +#define TE_DECAL 104 + +/** + * Create alpha sprites inside of entity, float upwards + * + * @note + * write_byte(TE_FIZZ) + * write_short(entity) + * write_short(sprite index) + * write_byte density) + */ +#define TE_FIZZ 105 + +/** + * Create a moving model that bounces and makes a sound when it hits + * + * @note + * write_byte(TE_MODEL) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(velocity.x) + * write_coord(velocity.y) + * write_coord(velocity.z) + * write_angle(initial yaw) + * write_short(model index) + * write_byte(bounce sound type) + * write_byte(life in 0.1's) + */ +#define TE_MODEL 106 + +/** + * Spherical shower of models, picks from set + * + * @note + * write_byte(TE_EXPLODEMODEL) + * write_coord(origin.x) + * write_coord(origin.y) + * write_coord(origin.z) + * write_coord(velocity.x) + * write_coord(velocity.y) + * write_coord(velocity.z) + * write_short(model index) + * write_short(count) + * write_byte(life in 0.1's) + */ +#define TE_EXPLODEMODEL 107 + +/** + * Box of models or sprites + * + * @note + * write_byte(TE_BREAKMODEL) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(size.x) + * write_coord(size.y) + * write_coord(size.z) + * write_coord(velocity.x) + * write_coord(velocity.y) + * write_coord(velocity.z) + * write_byte(random velocity in 10's) + * write_short(sprite or model index) + * write_byte(count) + * write_byte(life in 0.1 secs) + * write_byte(flags) + */ +#define TE_BREAKMODEL 108 + +/** + * Decal and ricochet sound + * + * @note + * write_byte(TE_GUNSHOTDECAL) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(entity index???) + * write_byte(decal???) + */ +#define TE_GUNSHOTDECAL 109 + +/** + * Spray of alpha sprites + * + * @note + * write_byte(TE_SPRITE_SPRAY) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(velocity.x) + * write_coord(velocity.y) + * write_coord(velocity.z) + * write_short(sprite index) + * write_byte(count) + * write_byte(speed) + * write_byte(noise) + */ +#define TE_SPRITE_SPRAY 110 + +/** + * Quick spark sprite, client ricochet sound. + * + * @note + * write_byte(TE_ARMOR_RICOCHET) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(scale in 0.1's) + */ +#define TE_ARMOR_RICOCHET 111 + +/** + * TE_PLAYERDECAL + * + * @note + * write_byte(TE_PLAYERDECAL) + * write_byte(playerindex) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(entity???) + * write_byte(decal number) + * [optional] write_short(model index) + */ +#define TE_PLAYERDECAL 112 + +/** + * Create alpha sprites inside of box, float upwards + * + * @note + * write_byte(TE_BUBBLES) + * write_coord(position.x) (min start position) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(position.x) (max start position) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(float height) + * write_short(model index) + * write_byte(count) + * write_coord(speed) + */ +#define TE_BUBBLES 113 + +/** + * Create alpha sprites along a line, float upwards + * + * @note + * write_byte(TE_BUBBLETRAIL) + * write_coord(position.x) (min start position) + * write_coord(position.y) (min start position) + * write_coord(position.z) (min start position) + * write_coord(position.x) (max start position) + * write_coord(position.y) (max start position) + * write_coord(position.z) (max start position) + * write_coord(float height) + * write_short(model index) + * write_byte(count) + * write_coord(speed) + */ +#define TE_BUBBLETRAIL 114 + +/** + * Spray of opaque sprite1's that fall, single sprite2 for 1..2 secs (this is a high-priority tent) + * + * @note + * write_byte(TE_BLOODSPRITE) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_short(sprite1 index) + * write_short(sprite2 index) + * write_byte(color) + * write_byte(scale) + */ +#define TE_BLOODSPRITE 115 + +/** + * Decal applied to the world brush + * + * @note + * write_byte(TE_WORLDDECAL) + * write_coord(position.x) decal position (center of texture in world) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(texture index of precached decal texture name) + */ +#define TE_WORLDDECAL 116 + +/** + * Decal (with texture index > 256) applied to world brush + * + * @note + * write_byte(TE_WORLDDECALHIGH) + * write_coord(position.x) decal position (center of texture in world) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(texture index of precached decal texture name - 256) + */ +#define TE_WORLDDECALHIGH 117 + +/** + * Same as TE_DECAL, but the texture index was greater than 256 + * + * @note + * write_byte(TE_DECALHIGH) + * write_coord(position.x) decal position (center of texture in world) + * write_coord(position.y) + * write_coord(position.z) + * write_byte(texture index of precached decal texture name - 256) + * write_short(entity index) + */ +#define TE_DECALHIGH 118 + +/** + * Makes a projectile (like a nail) (this is a high-priority tent) + * + * @note + * write_byte(TE_PROJECTILE) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(velocity.x) + * write_coord(velocity.y) + * write_coord(velocity.z) + * write_short(modelindex) + * write_byte(life) + * write_byte(owner) projectile won't collide with owner (if owner == 0, projectile will hit any client). + */ +#define TE_PROJECTILE 119 + +/** + * Throws a shower of sprites or models + * + * @note + * write_byte(TE_SPRAY) + * write_coord(position.x) + * write_coord(position.y) + * write_coord(position.z) + * write_coord(direction.x) + * write_coord(direction.y) + * write_coord(direction.z) + * write_short(modelindex) + * write_byte(count) + * write_byte(speed) + * write_byte(noise) + * write_byte(rendermode) + */ +#define TE_SPRAY 120 + +/** + * Sprites emit from a player's bounding box (ONLY use for players!) + * + * @note + * write_byte(TE_PLAYERSPRITES) + * write_short(playernum) + * write_short(sprite modelindex) + * write_byte(count) + * write_byte(variance) (0 = no variance in size) (10 = 10% variance in size) + */ +#define TE_PLAYERSPRITES 121 + +/** + * Very similar to lavasplash + * + * @note + * write_byte(TE_PARTICLEBURST) + * write_coord(origin) + * write_short(radius) + * write_byte(particle color) + * write_byte(duration * 10) (will be randomized a bit) + */ +#define TE_PARTICLEBURST 122 + +/** + * Makes a field of fire + * + * @note + * write_byte(TE_FIREFIELD) + * write_coord(origin) + * write_short(radius) (fire is made in a square around origin. -radius, -radius to radius, radius) + * write_short(modelindex) + * write_byte(count) + * write_byte(flags) + * write_byte(duration (in seconds) * 10) (will be randomized a bit) + */ +#define TE_FIREFIELD 123 + +/** + * Flags for the TE_FIREFIELD effect, controlling its performance and aesthetic + * features + */ +#define TEFIRE_FLAG_ALLFLOAT 1 // All sprites will drift upwards as they animate +#define TEFIRE_FLAG_SOMEFLOAT 2 // Some of the sprites will drift upwards. (50% chance) +#define TEFIRE_FLAG_LOOP 4 // If set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration. +#define TEFIRE_FLAG_ALPHA 8 // If set, sprite is rendered alpha blended at 50% else, opaque +#define TEFIRE_FLAG_PLANAR 16 // If set, all fire sprites have same initial Z instead of randomly filling a cube. + +/** + * Attaches a TENT to a player (this is a high-priority tent) + * + * @note + * write_byte(TE_PLAYERATTACHMENT) + * write_byte(entity index of player) + * write_coord(vertical offset) (attachment origin.z = player origin.z + vertical offset) + * write_short(model index) + * write_short(life * 10 ) + */ +#define TE_PLAYERATTACHMENT 124 + +/** + * Will expire all TENTS attached to a player. + * + * @note + * write_byte(TE_KILLPLAYERATTACHMENTS) + * write_byte(entity index of player) + */ +#define TE_KILLPLAYERATTACHMENTS 125 + +/** + * Much more compact shotgun message + * + * @note This message is used to make a client approximate a 'spray' of gunfire. + * Any weapon that fires more than one bullet per frame and fires in a bit + * of a spread is a good candidate for MULTIGUNSHOT use. (shotguns) + * @note This effect makes the client do traces for each bullet, these client + * traces ignore entities that have studio models.Traces are 4096 long. + * @note + * write_byte(TE_MULTIGUNSHOT) + * write_coord(origin.x) + * write_coord(origin.y) + * write_coord(origin.z) + * write_coord(direction.x) + * write_coord(direction.y) + * write_coord(direction.z) + * write_coord(x noise * 100) + * write_coord(y noise * 100) + * write_byte(count) + * write_byte(bullethole decal texture index) + */ +#define TE_MULTIGUNSHOT 126 + + +/** + * Larger message than the standard tracer, but allows some customization. + * + * @note + * write_byte(TE_USERTRACER) + * write_coord(origin.x) + * write_coord(origin.y) + * write_coord(origin.z) + * write_coord(velocity.x) + * write_coord(velocity.y) + * write_coord(velocity.z) + * write_byte(life * 10) + * write_byte(color) this is an index into an array of color vectors in the engine. (0 - ) + * write_byte(length * 10) + */ +#define TE_USERTRACER 127 + +/** + * @endsection + */ + +/** + * From hltv.h from the HLSDK, these are used in conjunction with SVC_DIRECTOR + * sub commands of svc_director + */ +#define DRC_CMD_NONE 0 // NULL director command +#define DRC_CMD_START 1 // start director mode +#define DRC_CMD_EVENT 2 // informs about director command +#define DRC_CMD_MODE 3 // switches camera modes +#define DRC_CMD_CAMERA 4 // sets camera registers +#define DRC_CMD_TIMESCALE 5 // sets time scale +#define DRC_CMD_MESSAGE 6 // send HUD centerprint +#define DRC_CMD_SOUND 7 // plays a particular sound +#define DRC_CMD_STATUS 8 // status info about broadcast +#define DRC_CMD_BANNER 9 // banner file name for HLTV gui +#define DRC_CMD_FADE 10 // send screen fade command +#define DRC_CMD_SHAKE 11 // send screen shake command +#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command + +#define DRC_CMD_LAST 12 + +/** + * HLTV_EVENT event flags + */ +#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important) +#define DRC_FLAG_SIDE (1<<4) // +#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene +#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo +#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc) +#define DRC_FLAG_INTRO (1<<8) // is a introduction scene +#define DRC_FLAG_FINAL (1<<9) // is a final scene +#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data + +#define MAX_DIRECTOR_CMD_PARAMETERS 4 +#define MAX_DIRECTOR_CMD_STRING 128 diff --git a/amxmodx/scripting/include/message_stocks.inc b/amxmodx/scripting/include/message_stocks.inc new file mode 100644 index 0000000..a916194 --- /dev/null +++ b/amxmodx/scripting/include/message_stocks.inc @@ -0,0 +1,161 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Message Stocks +// + +#if defined _message_stocks_included + #endinput +#endif +#define _message_stocks_included + +/** + * Sends a death message. + * + * @param killer Killer id + * @param victim Victim id + * @param weaponNUM Weapon index + * + * @noreturn + */ +stock dod_make_deathmsg(killer, victim, weaponNUM) +{ + static msgid = 0; + if (!msgid) + { + msgid = get_user_msgid("DeathMsg"); + } + message_begin(MSG_ALL, msgid, {0,0,0}, 0); + write_byte(killer); + write_byte(victim); + write_byte(weaponNUM); + message_end(); + + return 1; +} + +/** + * Kills a user without a message. + * + * @param index Client index + * @param flag If nonzero, the death will not affect the client's score + * + * @noreturn + */ +stock user_silentkill(index, flag = 1) +{ + static msgid = 0; + new msgblock; + if (!msgid) + { + msgid = get_user_msgid("DeathMsg"); + } + msgblock = get_msg_block(msgid); + set_msg_block(msgid, BLOCK_ONCE); + user_kill(index, flag); + set_msg_block(msgid, msgblock); + + return 1; +} + +/** + * Creates a death message. + * + * @param killer Killer id + * @param victim Victim id + * @param headshot Headshot + * @param weapon Weapon + * + * @noreturn + */ +stock make_deathmsg(killer, victim, headshot, const weapon[]) +{ + static msgid = 0; + if (!msgid) + { + msgid = get_user_msgid("DeathMsg"); + } + message_begin(MSG_ALL, msgid, {0,0,0}, 0); + write_byte(killer); + write_byte(victim); + + new mod_name[32]; + get_modname(mod_name, 31); + if (equal(mod_name, "cstrike") || equal(mod_name, "czero") || equal(mod_name, "csv15") || equal(mod_name, "cs13")) + write_byte(headshot); + write_string(weapon); + message_end(); + + return 1; +} + +/** + * Sends a predefined text message to player. + * Predefined texts are default game messages which will be translated + * to player's game language, e.g. #Game_join_ct. + * + * @note Set index to 0 to send text globally. + * + * @note There does not necessarily have to be a total of 6 arguments. + * It will depend if message takes arguments, e.g.: + * client_printex(id, print_chat, "#Game_join_ct", "Pimp Daddy") + * client_printex(id, print_chat, "1", "#Game_radio", "Pimp Daddy", "Hello world!") + * + * @param index Index of the player, use 0 to send to all players. + * @param type The message destination. See print_* constants. + * @param msg_name The custom or predefined message to send. + * @param msg_param1 Optional message argument. + * @param msg_param2 Optional message argument. + * @param msg_param3 Optional message argument. + * @param msg_param4 Optional message argument. + * + * @noreturn + */ +stock client_printex(index, type, const msg_name[], const msg_param1[] = "", const msg_param2[] = "", const msg_param3[] = "", const msg_param4[] = "") +{ + new ch = msg_name[0]; + + // If not a predefined message, we don't care about it and forward directly to client_print. + // Special case for radio message. msg_name is an index, msg_param1 #Game_radio*, etc. Checking index should be enough. + if (ch != '#' && (type != print_radio || !strtol(msg_name))) + { + return client_print(index, type, msg_name, msg_param1, msg_param2, msg_param3, msg_param4); + } + + // Even if message starts with '#', we should check its length for safety. + new length = strlen(msg_name); + + // If string is larger than expected, we forward to client_print which will cut message properly. + // This means also this can't be a predefined game message. + // Max console length: 128 = \n (126) + \0 (127) + // Max SayText length: 192 = \n (190) + \0 (191) + if ((length > 126 && (print_notify <= type <= print_console)) + || ( length > 190 && (print_chat <= type <= print_radio))) + { + return client_print(index, type, msg_name, msg_param1, msg_param2, msg_param3, msg_param4); + } + + static msgTextMsg; + if (!msgTextMsg) + { + msgTextMsg = get_user_msgid("TextMsg"); + } + + message_begin(index > 0 ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, msgTextMsg, {0,0,0}, index); + write_byte(type); + write_string(msg_name); + if (msg_param1[0]) { write_string(msg_param1); } + if (msg_param2[0]) { write_string(msg_param2); } + if (msg_param3[0]) { write_string(msg_param3); } + if (msg_param4[0]) { write_string(msg_param4); } + message_end(); + + return 1; +} diff --git a/amxmodx/scripting/include/messages.inc b/amxmodx/scripting/include/messages.inc new file mode 100644 index 0000000..c0ef156 --- /dev/null +++ b/amxmodx/scripting/include/messages.inc @@ -0,0 +1,604 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Message Functions +// + +#if defined _coremsg_included + #endinput +#endif +#define _coremsg_included + +#include + +/** + * Marks the beginning of a client message. + * + * @note You may generate menus, smoke, shockwaves, thunderlights, + * intermission and many other messages. + * @note For a list of HL game events, visit https://wiki.alliedmods.net/Half-Life_1_Game_Events + * @note For a list of HL engine messages, visit https://wiki.alliedmods.net/Half-Life_1_Engine_Messages + * @note You may also refer to the messages_const.inc file for examples. + * @note Each message starts with a message_begin() or message_begin_f() function + * and ends with message_end(). The specific message arguments go in between + * these two by using the write_*() functions found in messages.inc. + * + * @param dest Destination type (see MSG_* constants in messages_const.inc) + * @param msg_type Message id + * @param origin Message origin + * @param player Client index receiving the message or 0 for all clients + * + * @noreturn + * @error If an invalid message id is specified or an invalid number + * of parameters is passed, an error will be thrown. + */ +native message_begin(dest, msg_type, const origin[3] = {0,0,0}, player = 0); + +/** + * Marks the beginning of a client message. + * + * @note You may generate menus, smoke, shockwaves, thunderlights, + * intermission and many other messages. + * @note For a list of HL game events, visit https://wiki.alliedmods.net/Half-Life_1_Game_Events + * @note For a list of HL engine messages, visit https://wiki.alliedmods.net/Half-Life_1_Engine_Messages + * @note You may also refer to the messages_const.inc file for examples. + * @note This function is the same as message_begin(), but the origin + * argument accepts only float values in this one. + * @note Each message starts with a message_begin() or message_begin_f() function + * and ends with message_end(). The specific message arguments go in between + * these two by using the write_*() functions found in messages.inc. + * + * @param dest Destination type (see MSG_* constants in messages_const.inc) + * @param msg_type Message id + * @param origin Message origin + * @param player Client index receiving the message or 0 for all clients + * + * @noreturn + * @error If an invalid message id is specified or an invalid number + * of parameters is passed, an error will be thrown. + */ +native message_begin_f(dest, msg_type, const Float:origin[3] = {0.0,0.0,0.0}, player = 0); + +/** + * Ends a message that was started with message_begin() or message_begin_f(). + * + * @note If the function is called without using message_begin() or + * message_begin_f() first, the server will crash immediately. + * + * @noreturn + */ +native message_end(); + +/** + * Writes a single byte to a message. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Byte to write + * + * @noreturn + */ +native write_byte(x); + +/** + * Writes a single character to a message. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Character to write + * + * @noreturn + */ +native write_char(x); + +/** + * Writes a single number to a message (short). + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Number to write + * + * @noreturn + */ +native write_short(x); + +/** + * Writes a single number to a message (long). + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Number to write + * + * @noreturn + */ +native write_long(x); + +/** + * Writes an entity index to a message. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Entity index to write + * + * @noreturn + */ +native write_entity(x); + +/** + * Writes an angle entry to a message. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Angle to write + * + * @noreturn + */ +native write_angle(x); + +/** + * Writes an angle entry to a message using a float value. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Angle to write + * + * @noreturn + */ +native write_angle_f(Float:x); + +/** + * Writes a coordinate entry to a message. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Coordinate to write + * + * @noreturn + */ +native write_coord(x); + +/** + * Writes a coordinate entry to a message using a float value. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Coordinate to write + * + * @noreturn + */ +native write_coord_f(Float:x); + +/** + * Writes a string to a message. + * + * @note This function should only be used in between a message_begin() + * or message_begin_f() and a message_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x String to write + * + * @noreturn + */ +native write_string(const x[]); + +/** + * Marks the beginning of a client message. + * + * @note You may generate menus, smoke, shockwaves, thunderlights, + * intermission and many other messages. + * @note For a list of HL game events, visit https://wiki.alliedmods.net/Half-Life_1_Game_Events + * @note For a list of HL engine messages, visit https://wiki.alliedmods.net/Half-Life_1_Engine_Messages + * @note You may also refer to the messages_const.inc file for examples. + * @note This function is the same as message_begin(), except that the messages + * sent with this one are also sent to all other AMXX and Metamod plugins. + * This means that if you send one of these messages, other plugins will + * be notified of that message, which was previously impossible. + * @note BE CAREFUL! Using this incorrectly, or not for its intended purpose, + * could cause infinite recursion or something just as bad! + * @note Each message starts with a emessage_begin() or emessage_begin_f() function + * and ends with emessage_end(). The specific message arguments go in between + * these two by using the ewrite_*() functions found in messages.inc. + * + * @param dest Destination type (see MSG_* constants in messages_const.inc) + * @param msg_type Message id + * @param origin Message origin + * @param player Client index receiving the message or 0 for all clients + * + * @noreturn + * @error If an invalid message id is specified or an invalid number + * of parameters is passed, an error will be thrown. + */ +native emessage_begin(dest, msg_type, const origin[3] = {0,0,0}, player = 0); + +/** + * Marks the beginning of a client message. + * + * @note You may generate menus, smoke, shockwaves, thunderlights, + * intermission and many other messages. + * @note For a list of HL game events, visit https://wiki.alliedmods.net/Half-Life_1_Game_Events + * @note For a list of HL engine messages, visit https://wiki.alliedmods.net/Half-Life_1_Engine_Messages + * @note You may also refer to the messages_const.inc file for examples. + * @note This function is the same as message_begin_f(), except that the messages + * sent with this one are also sent to all other AMXX and Metamod plugins. + * This means that if you send one of these messages, other plugins will + * be notified of that message, which was previously impossible. + * @note BE CAREFUL! Using this incorrectly, or not for its intended purpose, + * could cause infinite recursion or something just as bad! + * @note This function is the same as emessage_begin(), but the origin + * argument accepts only float values in this one. + * @note Each message starts with a emessage_begin() or emessage_begin_f() function + * and ends with emessage_end(). The specific message arguments go in between + * these two by using the ewrite_*() functions found in messages.inc. + * + * @param dest Destination type (see MSG_* constants in messages_const.inc) + * @param msg_type Message id + * @param origin Message origin + * @param player Client index receiving the message or 0 for all clients + * + * @noreturn + * @error If an invalid message id is specified or an invalid number + * of parameters is passed, an error will be thrown. + */ +native emessage_begin_f(dest, msg_type, const Float:origin[3] = {0.0,0.0,0.0}, player = 0); + +/** + * Ends a message that was started with emessage_begin() or emessage_begin_f(). + * + * @note If the function is called without using emessage_begin() or + * emessage_begin_f() first, the server will crash immediately. + * + * @noreturn + */ +native emessage_end(); + +/** + * Writes a single byte to a message. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Byte to write + * + * @noreturn + */ +native ewrite_byte(x); + +/** + * Writes a single character to a message. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Character to write + * + * @noreturn + */ +native ewrite_char(x); + +/** + * Writes a single number to a message (short). + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Number to write + * + * @noreturn + */ +native ewrite_short(x); + +/** + * Writes a single number to a message (long). + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Number to write + * + * @noreturn + */ +native ewrite_long(x); + +/** + * Writes an entity index to a message. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Entity index to write + * + * @noreturn + */ +native ewrite_entity(x); + +/** + * Writes an angle entry to a message. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Angle to write + * + * @noreturn + */ +native ewrite_angle(x); + +/** + * Writes an angle entry to a message using a float value. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Angle to write + * + * @noreturn + */ +native ewrite_angle_f(Float:x); + +/** + * Writes a coordinate entry to a message. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Coordinate to write + * + * @noreturn + */ +native ewrite_coord(x); + +/** + * Writes a coordinate entry to a message using a float value. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x Coordinate to write + * + * @noreturn + */ +native ewrite_coord_f(Float:x); + +/** + * Writes a string to a message. + * + * @note This function should only be used in between a emessage_begin() + * or emessage_begin_f() and a emessage_end() function. Trying to use + * it outside of these functions will crash the server immediately. + * + * @param x String to write + * + * @noreturn + */ +native ewrite_string(const x[]); + +/** + * Sets whether or not an engine message will be blocked. + * + * @note For a list of message flags, have a look at the BLOCK_* constants + * in message_const.inc. + * + * @param iMessage Message id + * @param iMessageFlags BLOCK_* constant + * + * @noreturn + * @error If an invalid message id is specified, an error + * will be thrown. + */ +native set_msg_block(iMessage, iMessageFlags); + +/** + * Gets whether or not an engine message is blocked. + * + * @param iMessage Message id + * + * @return BLOCK_* constant + * @error If an invalid message id is specified, an error + * will be thrown. + */ +native get_msg_block(iMessage); + +/** + * Lets you directly hook a message in the engine. + * + * @note The function is called in the following manner: + * msg_id - Message id + * msg_dest - Destination type (see MSG_* constants in messages_const.inc) + * msg_entity - Entity receiving the message + * + * @note You can overwrite the message before anything happens by using the + * set_msg_arg_* functions and either let the message continue by + * returning PLUGIN_CONTINUE or fully block it with PLUGIN_HANDLED. + * @note If you hook a message, the message is stored but not sent. You have + * the opportunity to not only execute code, but to get/set the contents + * of the message before you choose to either block it or let it go on + * its way. + * @note The return value can be passed to unregister_message() in order to + * stop the message from being hooked. + * + * @param iMsgId Message id + * @param szFunction Function that will be called + * + * @return Id that can be passed to unregister_message() on + * success, or 0 if an invalid message id is passed + * @error If the specified function can't be found, an + * error will be thrown. + */ +native register_message(iMsgId, const szFunction[]); + +/** + * Unregisters a message hook previously created with register_message(). + * + * @note You must pass the proper message id and return value from the + * message to unregister the message successfully. + * + * @param iMsgId Message id + * @param registeredmsg Registered message id + * + * @return Id that can again be passed to register_message() on + * success, or 0 if an invalid message id is passed + * @error If an invalid registered message handle is passed, an + * error will be thrown. + */ +native unregister_message(iMsgId, registeredmsg); + +/** + * Gets number of arguments that were passed to a message. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @return Number of arguments + */ +native get_msg_args(); + +/** + * Gets the argument type of a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * + * @return Argument type (see ARG_* constants in message_const.inc) + */ +native get_msg_argtype(argn); + +/** + * Gets the integer value of a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * + * @return Argument value as an integer + * @error If an invalid message argument is passed, an + * error will be thrown. + */ +native get_msg_arg_int(argn); + +/** + * Gets the float value of a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * + * @return Argument value as a float + * @error If an invalid message argument is passed, an + * error will be thrown. + */ +native Float:get_msg_arg_float(argn); + +/** + * Gets the string value from a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * @param szReturn Buffer to store the value in + * @param iLength Maximum buffer length + * + * @return String length + * @error If an invalid message argument is passed, an + * error will be thrown. + */ +native get_msg_arg_string(argn, szReturn[], iLength); + +/** + * Sets the integer value of a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * @param argtype Argument type (see ARG_* constants in message_const.inc) + * @param iValue Argument value + * + * @noreturn + * @error If an invalid message argument is passed, an + * error will be thrown. + */ +native set_msg_arg_int(argn, argtype, iValue); + +/** + * Sets the float value of a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * @param argtype Argument type (see ARG_* constants in message_const.inc) + * @param fValue Argument value + * + * @noreturn + * @error If an invalid message argument is passed, an + * error will be thrown. + */ +native set_msg_arg_float(argn, argtype, Float:fValue); + +/** + * Sets the string value of a specified argument. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param argn Argument number + * @param szString Argument value + * + * @noreturn + * @error If an invalid message argument is passed, an + * error will be thrown. + */ +native set_msg_arg_string(argn, const szString[]); + +/** + * Gets the origin of a message. + * + * @note This function will fail if used outside a hooked message scope, thus + * it should never be used unless inside a registered message function. + * + * @param _Origin Array to store the origin in + * + * @noreturn + * @error If the function is used outside a message hook, an + * error will be thrown. + */ +native get_msg_origin(const Float:_Origin[3]); diff --git a/amxmodx/scripting/include/newmenus.inc b/amxmodx/scripting/include/newmenus.inc new file mode 100644 index 0000000..98d0fdd --- /dev/null +++ b/amxmodx/scripting/include/newmenus.inc @@ -0,0 +1,391 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +#if defined _newmenus_included + #endinput +#endif +#define _newmenus_included + +/** + * @section Menu properties for using in menu_setprop + */ + +/** + * Menu will have an exit option (default) + */ +#define MEXIT_ALL 1 + +/** + * Menu will have an exit option, even when pagination is disabled. + * There have to be less than 10 items in the menu or it won't appear. The exit + * option will be appended to the last item with no extra slot padding. If you + * want it in the 10th slot you have to pad it manually with menu_addblank2 + */ +#define MEXIT_FORCE 2 + +/** + * Menu will not have an exit option + */ +#define MEXIT_NEVER -1 + +/** + * Number of items per page (param1 = number, 0=no paginating, 7=default) + */ +#define MPROP_PERPAGE 1 + +/** + * Name of the back button (param1 = string) + */ +#define MPROP_BACKNAME 2 + +/** + * Name of the next button (param1 = string) + */ +#define MPROP_NEXTNAME 3 + +/** + * Name of the exit button (param1 = string) + */ +#define MPROP_EXITNAME 4 + +/** + * Menu title text (param1 = string) + */ +#define MPROP_TITLE 5 + +/** + * Exit functionality (param1 = number, see MEXIT constants) + */ +#define MPROP_EXIT 6 + +/** + * Sets whether colors are not auto (param1 = number, 0=default) + */ +#define MPROP_NOCOLORS 8 + +/** + * Color indicator to use for numbers (param1 = string, "\r"=default) + */ +#define MPROP_NUMBER_COLOR 10 + +/** + * Function to be called on Back and Next (param1 = string) + * public function(id, status, menu); where status is either MENU_BACK or MENU_MORE + * Pass NULL_STRING to disable the callback + */ +#define MPROP_PAGE_CALLBACK 11 + +/** + * Whether to show the page number in menu title (param1 = bool, true = default) + */ +#define MPROP_SHOWPAGE 12 + +/** + * @deprecated + */ +#define MEXIT_NORMAL 0 /* DEPRECATED, do not use (has no effect) */ +#define MENUPAD_NONE 0 /* DEPRECATED, do not use (has no effect) */ +#define MENUPAD_PAGE 1 /* DEPRECATED, do not use (has no effect) */ +#define MPROP_ORDER 7 /* DEPRECATED, do not use (has no effect) */ +#define MPROP_PADMENU 9 /* DEPRECATED, do not use (has no effect) */ + +/** @endsection */ + +/** + * @brief Creates a new menu object. + * + * The handler function should be prototyped as: + * + * public (id, menu, item) + * id - Client the menu is being acted upon. + * menu - Menu resource identifier. + * item - Item the client selected. If less than 0, the menu was + * cancelled and the item is a status code. menu_display + * should never be called immediately if the item is a status + * code, for re-entrancy reasons. + * + * The handler function should always return PLUGIN_HANDLED to block + * any old menu handlers from potentially feeding on the menu, unless + * that is the desired functionality. + * + * @param title Title the menu should use. + * @param handler Name of the handler function. The function will be invoked + * once and only once to every menu_display() call. + * @param ml If true, the menu title and items will be looked up as multilingual keys + * when the menu displays. + * @return Menu resource identifier which must be destroyed via + * menu_destroy(). All menus are destroyed when the plugin + * unloads. + * @error Function name not found. + */ +native menu_create(const title[], const handler[], bool:ml = false); + +/** + * Creates a menu item callback handler. + * + * The handler function should be prototyped as: + * + * public (id, menu, item) + * id - Client index being displayed to. + * menu - Menu resource identifier. + * item - Item being drawn. + * - ITEM_IGNORE to use the default functionality. ITEM_ENABLED to + * explicitly enable or ITEM_DISABLED to explicitly disable. + * + * @param function Function name. + * @return Menu callback ID. + */ +native menu_makecallback(const function[]); + +/** + * Adds an menu to a menu. + * + * @param menu Menu resource identifier. + * @param name Item text to display. + * @param info Item info string for internal information. + * @param paccess Access required by the player viewing the menu. + * @param callback If set to a valid ID from menu_makecallback(), the + * callback will be invoked before drawing the item. + * @noreturn + * @error Invalid menu resource. + */ +native menu_additem(menu, const name[], const info[]="", paccess=0, callback=-1); + +/** + * Returns the number of pages in a menu. + * + * @param menu Menu resource identifier. + * @return Number of pages in the menu. + * @error Invalid menu resource. + */ +native menu_pages(menu); + +/** + * Returns the number of items in a menu. + * + * @param menu Menu resource identifier. + * @return Number of items in the menu. + * @error Invalid menu resource. + */ +native menu_items(menu); + +/** + * Displays a menu to one client. This should never be called from a handler + * when the item is less than 0 (i.e. calling this from a cancelled menu will + * result in an error). + * + * Starting with 1.8.3 this allows to specify a menu timeout similar to the + * show_menu native. If the menu exists on the client past the timeout *any* + * further action will send the MENU_TIMEOUT status code to the menu handler. + * That includes actions which would otherwise send MENU_EXIT, such as the + * client selecting an item or disconnecting and calling menu_cancel or + * menu_destroy on a live menu. + * + * @param id Client index. + * @param menu Menu resource identifier. + * @param page Page to start from (starting from 0). + * @param time If >=0 menu will timeout after this many seconds + * @noreturn + * @error Invalid menu resource or client index. + */ +native menu_display(id, menu, page=0, time=-1); + +/** + * Given a page on a menu and a keypress on that page, returns the item id selected. + * If the item is less than 0, a special option was chosen (such as MENU_EXIT). + * + * @param menu Menu resource identifier. + * @param page Page on the menu. + * @param key Key pressed (from 1 to 10). + * @return Item identifier, or <0 for a special selection code. + * @error Invalid menu resource. + */ +native menu_find_id(menu, page, key); + +/** + * Retrieves info about a menu item. + * + * @param menu Menu resource identifier. + * @param item Item identifier. + * @param access Variable to store access value. + * @param info Buffer to store item info. + * @param infolen Item info buffer length. + * @param name Buffer to store item display text. + * @param namelen Item name buffer length. + * @param callback Callback ID. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + */ +native menu_item_getinfo(menu, item, &access = 0, info[] = "", infolen = 0, name[]="", namelen=0, &callback = 0); + +/** + * Sets an item's display text. + * + * @param menu Menu resource identifier. + * @param item Item identifier. + * @param name New item display text. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + */ +native menu_item_setname(menu, item, const name[]); + +/** + * Sets an item's info string. + * + * @param menu Menu resource identifier. + * @param item Item identifier. + * @param info New item info string. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + */ +native menu_item_setcmd(menu, item, const info[]); + +/** + * Sets an item's callback. + * + * @param menu Menu resource identifier. + * @param item Item identifier. + * @param callback New callback from menu_makecallback(), or -1 to clear. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + */ +native menu_item_setcall(menu, item, callback=-1); + +/** + * Sets an item's access. + * + * @param menu Menu resource identifier. + * @param item Item identifier. + * @param access New access required by the player for access to the item. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + */ +native menu_item_setaccess(menu, item, access=0); + +/** + * Destroys a menu. Player menus will be cancelled (although may still linger + * on the HUD), and future attempts to access the menu resource will result in + * an error. + * + * This must be called if you create menus dynamically, otherwise you will + * leak memory. For normal dynamic menus, you will destroy the menu in the + * handler function (remembering to handle the case of a menu being cancelled, + * it must still be destroyed). + * + * @param menu Menu resource identifier. + * @noreturn + * @error Invalid menu resource. + */ +native menu_destroy(menu); + +/** + * Returns information about a menu (if any) the client is currently viewing. + * + * If newmenu is valid, then the menu will refer to the menuid associated with + * the title. If newmenu is not valid, and the menu is valid, then the player + * is viewing a menu displayed with show_menu(). + * + * Both may be invalid if the player is not viewing a menu. + * + * @param id Client index. + * @param menu Variable to store old menu id. If none, then <1 will be + * stored. + * @param newmenu Variable to store new menu id. If none, then -1 will be + * stored. + * @param menupage Variable to store current page of the new menu, if any. + * @return 1 if the player is viewing a menu, 0 otherwise. + * @error Invalid client. + */ +native player_menu_info(id, &menu, &newmenu, &menupage=0); + +/** + * Adds a blank line to a menu. + * + * When using slot=1 this might break your menu. To achieve this functionality + * menu_addblank2 should be used. + * + * @param menu Menu resource identifier. + * @param slot 1 (default) if the line should shift the numbering down. + * 0 if the line should be a visual shift only. + * @noreturn + * @error Invalid menu resource. + */ +native menu_addblank(menu, slot=1); + +/** + * Adds a text line to a menu. Only available in amxmodx 1.8.1 and above. + * + * When using slot=1 this might break your menu. To achieve this functionality + * menu_addtext2 should be used. + * + * @param menu Menu resource identifier. + * @param text Text to add. + * @param slot 1 (default) if the line should shift the numbering down. + * 0 if the line should be a visual shift only. + * @noreturn + * @error Invalid menu resource. + */ +native menu_addtext(menu, const text[], slot=1); + +/** + * Adds a blank line to a menu, always shifting the numbering down. + * + * This will add a special item to create a blank line. It will affect the menu + * item count and pagination. These items can be modified later but will ignore + * access and item callback results. + * + * Only available in 1.8.3 and above. + * + * @param menu Menu resource identifier. + * + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + * Too many items on non-paginated menu (max is 10) + */ +native menu_addblank2( menu ); + +/** + * Adds a text line to a menu, always shifting the numbering down. + * + * This will add a special item to create a blank line. It will affect the menu + * item count and pagination. These items can be modified later but will ignore + * access and item callback results. + * + * Only available in 1.8.3 and above. + * + * @param menu Menu resource identifier. + * @param text Text to add. + * + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + * Too many items on non-paginated menu (max is 10) + */ +native menu_addtext2( menu, const text[] ); + +/** + * Sets a menu property. + * + * @param menu Menu resource identifier. + * @param prop MPROP_ constant. + * @param ... Property parameters. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource or property. + */ +native menu_setprop(menu, prop, ...); + +/** + * Cancels a player's menu, effectively forcing the player to select MENU_EXIT. + * The menu will still exist on their screen but any results are invalidated, + * and the callback is invoked. + * + * @param player Client index. + * @noreturn + * @error Invalid client index. + */ +native menu_cancel(player); diff --git a/amxmodx/scripting/include/ns.inc b/amxmodx/scripting/include/ns.inc new file mode 100644 index 0000000..75f1b5b --- /dev/null +++ b/amxmodx/scripting/include/ns.inc @@ -0,0 +1,754 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Natural Selection Module Functions +// + +#if defined NS_INC + #endinput +#endif +#define NS_INC + +#pragma reqlib ns +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib ns +#endif + +#include + + +/** + * Called whenever the client's class is changed. + * + * @param id The index of the player who changed. + * @param newclass The class the client changed to. Check the class enum in ns_const.inc. + * @param oldclass The class the client changed from. Check the class enum in ns_const.inc. + * @noreturn + */ +forward client_changeclass(id, newclass, oldclass); + +/** + * Called whenever the client builds a structure. + * + * @param idPlayer The player index who triggered the building. + * @param idStructure The structure index that was created. + * @param type The type of structure that was built (1 for marine, 2 for alien). + * @param impulse The impulse command that was issued to build this structure. + * @noreturn + */ +forward client_built(idPlayer, idStructure, type, impulse); + +/** + * Tell whether or not the map is combat. + * + * @return 1 if combat, 0 otherwise. + */ +native ns_is_combat(); + +/** + * Returns the gameplay type for the currently active map. + * Refer to ns_const.inc's NSGameplay enum for details. + * + * @note The earliest this is guaranteed to be accurate is during plugin_init(). It needs + * the info_gameplay entity to be properly set within the map, or it will return "Unknown", + * or "Cantfind". + * + * @return Return the gameplay mode, as accurate as the module can tell. + */ +native NSGameplay:ns_get_gameplay(); + +/** + * Exact syntax as get_user_team, but should be more accurate. + * + * @param id Player id. + * @param buff Buffer to store team name in. + * @param len Buffer length. + * @return The pev_team setting for the player. + */ +native ns_get_user_team(id, buff[], len); + +/** + * Send an NS-style popup message. + * + * @param target The client to receive the message. Set to 0 to send to everybody. + * @param szMsg The message to send, 180 characters max. + * @param ah Whether to only display the message on clients who have the cvar "cl_autohelp" set to 1. + * @noreturn + */ +native ns_popup(target, const szMsg[180], ah=0); + +/** + * Sets a player model. Omit the second parameter to return to default + * + * @note The model does not revert on death, teamswitch, gestation, etc. + * + * @param id The player id to change. + * @param szModel The model to change to. + * @noreturn + */ +native ns_set_player_model(id, const szModel[]=""); + +/** + * Sets a player skin. Omit the second parameter to return to default + * + * @note The skin does not revert on death, teamswitch, gestation, etc. + * + * @param id The player id to change. + * @param skin The skin number to change to. + * @noreturn + */ +native ns_set_player_skin(id, skin=-1); + +/** + * Sets a player body. Omit the second parameter to return to default + * + * @note The body does not revert on death, teamswitch, gestation, etc. + * + * @param id The player id to change. + * @param body The body number to change to. + * @noreturn + */ +native ns_set_player_body(id, body=-1); + +/** + * Set this to modify the player's speed by a certain amount. + * + * @note The speed does not revert on death, teamswitch, gestation, etc. + * + * @param id The player id to change. + * @param speedchange The speed to modify the player speed by. Set to 0 to revert to default speed. + * @noreturn + */ +native ns_set_speedchange(id, speedchange=0); + +/** + * Returns a client's current speed modifier. + * + * @param id The client id to check. + * @return The module's current speed modifier for the client. + */ +native ns_get_speedchange(id); + +/** + * Returns a client's maxspeed before the speed change modifier is factored in. + * + * @param id The client id to check. + * @return The maxspeed for the client. + */ +native ns_get_maxspeed(id); + +/* Returns whether or not this mask is set from the entity's iuser4 field. Use the "mask" enum for reference. */ +native ns_get_mask(id,mask); + +/* Sets or removes the mask from the entity's iuser4 field. Set "value" to 1 to turn the mask on, 0 to turn it off. */ +native ns_set_mask(id,mask,value); + +/* Returns built/unbuilt structures. + If: + builtOnly is 1 (default): + Only fully built structures are counted. + builtOnly is 0: + Any structure meeting the classname is counted. + + Number is 0 (default): + The total number of matching structures is returned. + Number is any other value: + The index of the #th matching structure is returned. +*/ +native ns_get_build(const classname[],builtOnly=1,Number=0); + +/* Returns if the player has the weapon or not in their pev->weapons field. + set "setweapon" to 0 to turn the bit off, set to 1 to turn it on. Or omit it to just return the value. */ +native ns_has_weapon(id,weapon,setweapon=-1); + +/* Gets spawn point for specified team (type). + If: + Team is equal to 0: + Ready room spawns are returned. + Team is greater than 0: + Spawns for the team are returned. + + Number is equal to 0: + Total number of spawns is returned. + Number is greater than 0: + The location of the specified spawn is returned. +*/ +native ns_get_spawn(team,number=0,Float:ret[3]); + +/* Returns the class of the player. Look in the classes enum in ns_const.inc for the value's meaning. */ +native ns_get_class(id); + +/** + * Gets the player's jetpack fuel reserve. + * + * @param id The player to get fuel from. + * @return The amount of fuel in the player's reserve. (0.0 through 100.0) + */ +native Float:ns_get_jpfuel(id); + +/** + * Sets the player's jetpack fuel reserve. + * + * @param id The player to set fuel. + * @param fuel The amount of fuel to set, as a percentage (0.0 through 100.0) + * @noreturn + */ +native ns_set_jpfuel(id, Float:fuel); + +/** + * Adds to the player's jetpack fuel reserve. + * + * @param id The player to add fuel to. + * @param amount The amount of fuel to add, as a percentage (0.0 through 100.0) + * @return The new amount of fuel in the player's reserve. (0.0 through 100.0) + */ +native Float:ns_add_jpfuel(id, Float:amount); + +/** + * Gets the player's energy percentage. + * + * @param id The player to get the energy from. + * @return The amount of energy the player has (0.0 through 100.0) + */ +native Float:ns_get_energy(id); + +/** + * Sets the player's energy percentage. + * + * @param id The player to set the energy on. + * @param energy The amount of energy to set (0.0 through 100.0) + * @noreturn + */ +native ns_set_energy(id, Float:energy); + +/** + * Adds to the player's energy percentage. + * + * @param id The player to add the energy to. + * @param amount The amount of energy to add to the player. + * @return The new amount of energy the player has (0.0 through 100.0) + */ +native Float:ns_add_energy(id, Float:amount); + + +/** + * Returns a player's resources. + * + * @note This is only for alien players. + * @param id The id of the player to check. + * @return Amount of resources this player has. + */ +native Float:ns_get_res(id); + +/** + * Sets a player's resources. + * + * @note This is only for alien players. + * @param id The id of the player to set. + * @param res Amount of resources to set on this player. + * @noreturn + */ +native ns_set_res(id, Float:res); + +/** + * Adds an amount of resources to the player. + * + * @note This is only for alien players. + * @param id The id of the player to add resources to. + * @param amount The amount to add to the player. + * @return The new amount of resources the player has. + */ +native Float:ns_add_res(id, Float:amount); + +/** + * Returns the team's resources. + * + * @param Team 1 for teama, 2 for teamb. (eg: in MvA maps, 1 is marines, + 2 is aliens. In mvm, 1 is marine1, 2 is marine2) + * @return The amount of resources in this team's resource pool. + */ +native Float:ns_get_teamres(Team); + +/** + * Sets the team's resources in the resource pool. + * + * @note If this is used on an alien team, the resources will be + * distributed between all of the players who need resources. + * @param Team 1 for teama, 2 for teamb. (eg: in MvA maps, 1 is marines, + * 2 is aliens. In mvm, 1 is marine1, 2 is marine2) + * @param value The amount to set the resources to set to. + * @noreturn + */ +native ns_set_teamres(Team, Float:value); + +/** + * Adds to the team's resources in the resource pool. + * + * @note If this is used on an alien team, the resources will be + * distributed between all of the players who need resources. + * @param Team 1 for teama, 2 for teamb. (eg: in MvA maps, 1 is marines, + * 2 is aliens. In mvm, 1 is marine1, 2 is marine2) + * @param value The amount to set the resources to add to the pool + * @return The new amount of resources in the resource pool. + */ +native Float:ns_add_teamres(Team,Float:value); + + +/** + * Returns the player's experience. + * + * @note Combat only. + * @param id The player to get experience value from. + * @return The amount of experience this player has. + */ +native Float:ns_get_exp(id); + +/** + * Sets the player's experience. + * + * @note Combat only. + * @param id The player to set experience value on. + * @param exp The amount of experience this player will have. + * @noreturn + */ +native ns_set_exp(id,Float:exp); + +/** + * Adds to the player's experience. + * + * @note Combat only. + * @param id The player to add experience value to. + * @param value The amount of experience this player will receive. + * @return The new amount of experience this player has. + */ +native Float:ns_add_exp(id, Float:value); + +/** + * Gets the player's points spent count in combat. + * + * @param id The player to check. + * @return The amount of points this player has spent. + */ +native ns_get_points(id); + +/** + * Sets the player's points spent count in combat. + * + * @param id The player to set this on. + * @param points The amount to set this to. + * @noreturn + */ +native ns_set_points(id, points); + +/** + * Adds to the player's points spent count in combat. + * + * @param id The player to add this to. + * @param value The value to add to the points spent. + * @return The new value of the points spent variable. + */ +native ns_add_points(id,points); + +/** + * Gets the damage for this weapon. + * + * @note Use weapon index, not player index! + * @param idWeapon The entity index of the weapon to check. + * @return The damage this weapon does. + */ +native Float:ns_get_weap_dmg(idWeapon); + +/** + * Sets the damage for this weapon. + * + * @note Use weapon index, not player index! + * @param idWeapon The entity index of the weapon to set. + * @param damage The damage to make this weapon cause. + * @noreturn + */ +native ns_set_weap_dmg(idWeapon, Float:damage); + +/** + * Gets the maximum range for this weapon. + * + * @note Use weapon index, not player index! + * @param idWeapon The entity index of the weapon to check. + * @return The maximum range this weapon has. + */ +native Float:ns_get_weap_range(idWeapon); + +/** + * Sets the maximum range for this weapon. + * + * @note Use weapon index, not player index! + * @param idWeapon The entity index of the weapon to set. + * @param range The maximum range this weapon will have. + * @noreturn + */ +native ns_set_weap_range(idWeapon, Float:range); + +/** + * Gets the weapon's clip ammo. + * + * @note Use weapon index, not player index! + * @param idWeapon The weapon to get the clip ammo from. + * @return The amount of ammunition in the weapon's clip. + */ +native ns_get_weap_clip(idWeapon); + +/** + * Sets the weapon's ammo in the clip. + * + * @note Use weapon index, not player index! + * @param idWeapon The weapon to set the clip ammo on. + * @param clipsize The amount of ammunition to set in the weapon's clip. + * @noreturn + */ +native ns_set_weap_clip(idWeapon, clipsize); + +/** + * Gets the player's weapon reserve (backpack ammo) for the specified + * type of weapon. + * + * @note Use player index, not weapon index! + * @param id The player id to check ammo count on. + * @param weapon The weapon type to check ammo count for. + * @return The ammunition count in the player's reserve. + */ +native ns_get_weap_reserve(id,weapon); + +/** + * Sets the player's weapon reserve (backpack ammo) for the specified + * type of weapon. + * + * @note Use player index, not weapon index! + * @param id The player id to set ammo count on. + * @param weapon The weapon type to set ammo count for. + * @param ammo The ammunition count to set. + * @noreturn + */ +native ns_set_weap_reserve(id,weapon,ammo); + +/** + * Gets the player's score. + * + * @note The score from level is automatically factored into the scoreboard in combat. + * @param idPlayer The player to get the score for. + * @return The player's score. + */ +native ns_get_score(idPlayer); + +/** + * Sets the player's score. + * + * @note The score from level is automatically factored into the scoreboard in combat. + * @param idPlayer The player to get the score for. + * @param score What to set the player's score as. + * @noreturn + */ +native ns_set_score(idPlayer, score); + +/* Adds to a player's score + * Returns the new score on success + */ +native ns_add_score(idPlayer,score); + +/* Gets a player's death count. */ +native ns_get_deaths(idPlayer); + +/* Sets a player's death count. */ +native ns_set_deaths(idPlayer,numdeaths); + +/* Adds to a player's death count + * Returns the new death count on success + */ +native ns_add_deaths(idPlayer,numdeaths); + +/* Gets the index of the owner of a structure. -1 for no owner. */ +native ns_get_struct_owner(idStructsure); + +/* Sets the index of the owner of a structure. -1 for no owner. */ +native ns_set_struct_owner(idStructure,indexOwner); + +/* Gets the trait type tied to the hive. Look at the hivetrait enum for the values. */ +native ns_get_hive_trait(idHive); + +/* Sets the trait type tied to the hive. Look at the hivetrait enum for the values. */ +native ns_set_hive_trait(idHive,trait); + +/* Sets the players field of view, set "_fov" to 0.0 (or omit it) to return to normal. FOV change will persist until disconnect unless reset by a plugin */ +native ns_set_fov(idPlayer,Float:_fov=0.0); + +/** + * Give the player an item. + * + * @param id The player to give the item to. + * @param class The map-classname of the entity to give to the player. + * @noreturn + */ +native ns_give_item(id, const class[]); + +/** + * Returns 1 if a player has the hive ability number. + * If ability is 0, it will return the number of active hives. + * + * @param idPlayer The player index to look up. + * @param ability The ability number to check, set to 0 to get number of active hives. + * @return If ability is != 0, returns 1 or 0 depending on if the client has the ability. + * If ability is 0, returns the number of active hives. + */ +native ns_get_hive_ability(idPlayer, ability=0); + +/** + * Triggered whenever a client's pev->team changes. + * + * @param id The id of the client. + * @param newteam The team number of the new team. + * @param oldteam The team number of the old team. + * @noreturn + */ +forward client_changeteam(id, newteam, oldteam); + +/** + * Triggered whenever a client's pev->deadflag changes from >0 to 0. + * + * @param id The id of the client. + * @noreturn + */ +forward client_spawn(id); + +/** + * Calls NS's private damage routine on the victim entity. + * + * @deprecated + * @note This is provided for backwards compatibility with peachy's module. + * It is suggested to use hamsandwich for this action instead. + * + * @param IDVictim The victim that is taking the damage. + * @param IDInflictor The entity that is causing the damage (weapon, etc). + * @param IDAttacker The attacker who is triggering the damage (person shooting). + * @param Damage The amount of damage being done. + * @param DamageType The damage type being done (bitmask). + */ +#pragma deprecated It is suggested to use hamsandwich for this action instead. +native ns_takedamage(IDVictim, IDInflictor, IDAttacker, Float:Damage, DamageType); + +/** + * Attempts to unstick a player. + * + * @param id Player to unstick. + * @param StartDistance Distance to start from the player to check for a new location. + * @param MaxAttempts How many attempts to try to find a new spot before giving up. + * @return 1 on success, 0 on cannot find a place to move player to, + * -1 on invalid state (stunned/webbed), -2 on invalid class (comm/egg) + * -3 if the player is dead or a spectator, -4 on invalid player, + * -5 if the player is not connected. + */ +native ns_unstick_player(id, StartDistance=32, MaxAttempts=128); + +/** + * Whether or not there is a game in progress. + * + * @return true if a game is in progress, false otherwise. + */ +native bool:ns_round_in_progress(); + +/** + * Called at the approximate time that a round is started. + * + * @noreturn + */ +forward round_start(); + +/** + * Called immediately when a round ends + * + * @param roundtime The length of the round in seconds. + * @noreturn + */ +forward round_end(Float:roundtime); + +forward map_reset(isload); + +native ns_get_weapon(idPlayer,weaponid,&weapontype=0); + +/* Returns the location name of the provided x/y position + * (z origin is ignored; can't have location over location) + * - + * Note that as of NS 3.2 beta 2, on the following maps + * the returned string should be passed through ns_lookup_title + * to be human readable: + * ns_bast, ns_hera, ns_nothing, ns_tanith, + * ns_nancy, ns_caged, ns_eclipse, ns_veil + * + * Passing the 5th parameter as non zero will auto look up + * the title if it exists. + */ +native ns_get_locationname(Float:x, Float:y, name[], len, titlelookup=0); + +/* Looks up a key from titles.txt + * Returns -1 if the key is not found + * Otherwise it returns the length of the output + */ +native ns_lookup_title(const KeyName[], Output[], length); + +/* Forces the structure to fully build + * Removes the ghost state from marine structures. + * Do not use this on hives! It wont work. + */ +native ns_build_structure(idStructure); + +/* Forces the structure to begin recycling + * Passing an index other than a marine structure will + * have undefined results! + * - + * Note: This calls a private NS function! + * Be careful when using this! + */ +native ns_recycle(idStructure); + +/* Forces the weldable to trigger + * Passing an index other than a weldable + * will have undefined results! + * - + * NS renames func_weldable to avhweldable + * at map load. + * - + * Note: This calls a private NS function! + * Be careful when using this! + */ +native ns_finish_weldable(idWeldable); + +/* Gets the total time needed to weld this + * func_weldable shut. + * Note: NS renames "func_weldable"s to "avhweldable"s + * at run time! + */ +native Float:ns_get_weld_time(idWeldable); + +/* Sets the total time needed to weld this + * func_weldable shut. + */ +native ns_set_weld_time(idWeldable,Float:value); + +/* Adds to the weldable's time required to open. + * Returns the new required time on success. + * Note this native clamps the low value to 0. + */ +native Float:ns_add_weld_time(idWeldable,Float:value); + +/* Gets the total time this func_weldable + * has been welded. + */ +native Float:ns_get_weld_done(idWeldable); + +/* Sets the total time this func_weldable + * has been welded. + */ +native ns_set_weld_done(idWeldable,Float:value); + +/* Adds to the total time this func_weldable + * has been welded. Returns the new value. + * Note this native clamps the low value to 0.0 + */ +native Float:ns_add_weld_done(idWeldable,Float:value); + +/* Gets/sets/adds to the energy pool of this observatory. */ +native Float:ns_get_obs_energy(idObs); +native ns_set_obs_energy(idObs,Float:value); +native Float:ns_add_obs_energy(idObs,Float:value); + +/** + * Removes an upgrade from the player's bought and active upgrade lists. + * This will not refund the points spent on the upgrade, nor will it + * immediately strip the upgrade if the player is alive. Rather, it will + * make it so the player no longer receives the upgrade on spawn. + * + * @note This only works in combat. + * @params idPlayer The player index to change upgrades for. + * @params ugprade The impulse number for the upgrade to strip. + * @return 2 for upgrade removed from player's bought and active list. + * 1 for upgrade removed from player's bought list only. + * 3 for upgrade removed from player's active list only (shouldn't happen, just incase.) + * 0 for the player didn't have the upgrade in either list. + */ +native ns_remove_upgrade(idPlayer, upgrade); + +/** + * Particle system natives + * - + * The particle system emulates a map-based custom particle system. + * Familiarity with the keyvalues from the map-based particle systems + * is recommended! You will be lost otherwise! + * - + * prsearle's NSPEdit is also recommended for designing the systems: + * http://homepage.ntlworld.com/pr.searle/NSPSEdit/NSPSEdit.html + */ + +/* Creates a handle to the a particle system to configure + * - + * Note! this is not a particle system you can pass to + * ns_fire_ps()! + */ +native RawPS:ns_create_ps(); + +/* Sets the name of the particle system. + * - + * This is used for things like ns_get_ps_id() + * and through calling another particle system + * through the "ps_to_gen" field + */ +native ns_set_ps_name(RawPS:system, const name[]); + +/* Sets the sprite to use for the particle system + * - + * You do NOT have to precache the sprite, BUT + * the sprite must obviously be on the client to + * display. + */ +native ns_set_ps_sprite(RawPS:system, const sprite[]); + +/* Finalizes the particle system. Do not configure it after this. + * A usable particle system handle is returned. + */ +native Particle:ns_spawn_ps(RawPS:system); + +/* Draws a particle system at the given origin (and angles) + * Flags are the FEV_* defines from hlsdk_const.inc + * Only use handles returned by ns_spawn_ps or ns_get_ps_id here! + */ +native ns_fire_ps(Particle:system,const Float:origin[3],const Float:angles[3]={0.0,0.0,0.0}, flags=0); + +/* Looks up a particle system by name + * Returns a usable particle system handle. + */ +native Particle:ns_get_ps_id(const Name[]); + +/* The following are the parameters for configuring the + * particle system. Look through the fgd and NSPSEdit + * for details! + */ +native ns_set_ps_genrate(RawPS:system, genrate); +native ns_set_ps_genshape(RawPS:system, NSPS_GenShape:genshape); +native ns_set_ps_genshape_params(RawPS:system, const params[]); +native ns_set_ps_spriteframes(RawPS:system, spriteframes); +native ns_set_ps_numparticles(RawPS:system, numparticles); +native ns_set_ps_size(RawPS:system, Float:size); +native ns_set_ps_vel_params(RawPS:system, const params[]); +native ns_set_ps_vel_shape(RawPS:system, NSPS_VelShape:shape); +native ns_set_ps_sys_life(RawPS:system, Float:lifetime); +native ns_set_ps_particle_life(RawPS:system, Float:lifetime); +native ns_set_ps_rendermode(RawPS:system, NSPS_RenderMode:rendermode); +native ns_set_ps_to_gen(RawPS:system, const name[]); +native ns_set_ps_anim_speed(RawPS:system, speed); +native ns_set_ps_spawn_flags(RawPS:system, NSPS_Flags:flags); +native ns_set_ps_base_color(RawPS:system, const colors[]); +native ns_set_ps_scale(RawPS:system, Float:scale); +native ns_set_ps_max_alpha(RawPS:system, Float:maxalpha); diff --git a/amxmodx/scripting/include/ns_const.inc b/amxmodx/scripting/include/ns_const.inc new file mode 100644 index 0000000..b1eb945 --- /dev/null +++ b/amxmodx/scripting/include/ns_const.inc @@ -0,0 +1,196 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Natural Selection Module Constants +// + +#if defined NS_CONST_INC + #endinput +#endif +#define NS_CONST_INC + + +enum NSGameplay +{ + NSGame_CantTell, /**< It is too soon to tell (can't find avhgameplay + entity or it doesn't have private data) */ + + NSGame_MarineVAlien, /**< Marine vs Aliens (standard) gameplay */ + NSGame_MarineVMarine, /**< Marine vs Marine */ + NSGame_AlienVAlien, /**< Alien vs Alien */ + + NSGame_Unknown, /**< Can find the gameplay entity, but can't + determine gameplay type. */ +}; + +// entity pev->iuser4 fields +enum { + MASK_NONE = 0, + MASK_SIGHTED = 1, + MASK_DETECTED = 2, + MASK_BUILDABLE = 4, + MASK_BASEBUILD0 = 8, // Base build slot #0 + MASK_WEAPONS1 = 8, // Marine weapons 1 + MASK_CARAPACE = 8, // Alien carapace + MASK_WEAPONS2 = 16, // Marines weapons 2 + MASK_REGENERATION = 16, // Alien regeneration + MASK_BASEBUILD1 = 16, // Base build slot #1 + MASK_WEAPONS3 = 32, // Marine weapons 3 + MASK_REDEMPTION = 32, // Alien redemption + MASK_BASEBUILD2 = 32, // Base build slot #2 + MASK_ARMOR1 = 64, // Marine armor 1 + MASK_CELERITY = 64, // Alien celerity + MASK_BASEBUILD3 = 64, // Base build slot #3 + MASK_ARMOR2 = 128, // Marine armor 2 + MASK_ADRENALINE = 128, // Alien adrenaline + MASK_BASEBUILD4 = 128, // Base build slot #4 + MASK_ARMOR3 = 256, // Marine armor 3 + MASK_SILENCE = 256, // Alien silence + MASK_BASEBUILD5 = 256, // Base build slot #5 + MASK_JETPACK = 512, // Marine jetpacks + MASK_CLOAKING = 512, // Alien cloaking + MASK_BASEBUILD6 = 512, // Base build slot #6 + MASK_FOCUS = 1024, // Alien focus + MASK_MOTION = 1024, // Marine motion tracking + MASK_BASEBUILD7 = 1024, // Base build slot #7 + MASK_SCENTOFFEAR = 2048, // Alien scent of fear + MASK_DEFENSE2 = 4096, // Defense level 2 + MASK_DEFENSE3 = 8192, // Defense level 3 + MASK_ELECTRICITY = 8192, // Electricy + MASK_MOVEMENT2 = 16384, // Movement level 2, + MASK_MOVEMENT3 = 32768, // Movement level 3 + MASK_HEAVYARMOR = 32768, // Marine heavy armor + MASK_SENSORY2 = 65536, // Sensory level 2 + MASK_SENSORY3 = 131072, // Sensory level 3 + MASK_ALIEN_MOVEMENT = 262144, // Onos is charging + MASK_WALLSTICKING = 524288, // Flag for wall-sticking + MASK_PRIMALSCREAM = 1048576, // Alien is in range of active primal scream + MASK_UMBRA = 2097152, // In umbra + MASK_DIGESTING = 4194304, // When set on a visible player, player is digesting. When set on invisible player, player is being digested + MASK_RECYCLING = 8388608, // Building is recycling + MASK_TOPDOWN = 16777216, // Commander view + MASK_PLAYER_STUNNED = 33554432, // Player has been stunned by stomp + MASK_ENSNARED = 67108864, // Webbed + MASK_ALIEN_EMBRYO = 134217728, // Gestating + MASK_SELECTABLE = 268435456, // ??? + MASK_PARASITED = 536870912, // Parasite flag + MASK_SENSORY_NEARBY = 1073741824 // Sensory chamber in range +}; + + +enum { + CLASS_UNKNOWN = 0, + CLASS_SKULK, + CLASS_GORGE, + CLASS_LERK, + CLASS_FADE, + CLASS_ONOS, + CLASS_MARINE, + CLASS_JETPACK, + CLASS_HEAVY, + CLASS_COMMANDER, + CLASS_GESTATE, + CLASS_DEAD, + CLASS_NOTEAM +}; + +enum { + WEAPON_NONE = 0, + WEAPON_CLAWS, + WEAPON_SPIT, + WEAPON_SPORES, + WEAPON_SPIKE, + WEAPON_BITE, + WEAPON_BITE2, + WEAPON_SWIPE, + WEAPON_WEBSPINNER, + WEAPON_METABOLIZE, + WEAPON_PARASITE, + WEAPON_BLINK, + WEAPON_DIVINEWIND, + WEAPON_KNIFE, + WEAPON_PISTOL, + WEAPON_LMG, + WEAPON_SHOTGUN, + WEAPON_HMG, + WEAPON_WELDER, + WEAPON_MINE, + WEAPON_GRENADE_GUN, + WEAPON_LEAP, + WEAPON_CHARGE, + WEAPON_UMBRA, + WEAPON_PRIMALSCREAM, + WEAPON_BILEBOMB, + WEAPON_ACIDROCKET, + WEAPON_HEALINGSPRAY, + WEAPON_GRENADE, + WEAPON_STOMP, + WEAPON_DEVOUR, + WEAPON_MAX +}; + +enum { + HIVETRAIT_NONE = 0, + HIVETRAIT_DC = 92, + HIVETRAIT_SC = 93, + HIVETRAIT_MC = 94 +}; + +enum NSPS_VelShape +{ + NSPS_VS_POINT = 1, + NSPS_VS_BOX, + NSPS_VS_SPHERE, + NSPS_VS_BLOB +}; + +/* Genshape used in ns_set_ps_genshape + * NOTE: The following are in the ns.ps file but + * are not listed in the .fgd file. Use + * at your own risk! + * Line, Triangle, Plane, Cylinder, + * Cone, Disc, Rectangle and None + */ +enum NSPS_GenShape +{ + NSPS_GS_POINT = 0, + NSPS_GS_LINE, + NSPS_GS_TRIANGLE, + NSPS_GS_PLANE, + NSPS_GS_BOX, + NSPS_GS_CYLINDER, + NSPS_GS_CONE, + NSPS_GS_BLOB, + NSPS_GS_DISC, + NSPS_GS_RECTANGLE, + NSPS_GS_NONE +}; +enum NSPS_RenderMode +{ + NSPS_R_NORMAL = 0, + NSPS_R_TRANSCOLOR, + NSPS_R_TRANSTEXTURE, + NSPS_R_GLOW, + NSPS_R_TRANSALPHA, + NSPS_R_ADDITIVE +}; +enum NSPS_Flags +{ + NSPS_FL_START_ON = 1, + NSPS_FL_PARTICLE_DENSITY = 2, + NSPS_FL_FADE_IN = 4, + NSPS_FL_FADE_OUT = 8, + NSPS_FL_USE_GRAVITY = 16, + NSPS_FL_USE_TRI = 32, + NSPS_FL_CONSTRAIN_PITCH = 128, + NSPS_FL_COLLIDE = 256, + NSPS_FL_HI_DETAIL = 512, + NSPS_FL_FACE_UP = 1024 +}; diff --git a/amxmodx/scripting/include/nvault.inc b/amxmodx/scripting/include/nvault.inc new file mode 100644 index 0000000..4c025c1 --- /dev/null +++ b/amxmodx/scripting/include/nvault.inc @@ -0,0 +1,154 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// NVault Functions +// + +#if defined _nvault_included + #endinput +#endif +#define _nvault_included + +#pragma reqlib nvault +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib nvault +#endif + +/** + * @global All timestamps are in UNIX epoch form. + */ + +/** + * Opens a vault by name. Creates a vault if it doesn't exist yet. + * + * @param name Name of the vault. The vault will be created in + * ${amxx_datadir}/vault directory. + * + * @return The vault handle to be used in other natives. + * INVALID_HANDLE (-1) if not successfully opened. + */ +native nvault_open(const name[]); + +/** + * Retrieves a value from the given key. + * + * @note An example of retrieving a string: + * nvault_get(vaultHandle, "myKey", myString, charsmax(myString)); + * + * @param vault A vault handle returned from nvault_open() + * @param key A key to get the value from + * @param ... If three argument are given, gets a float value and + * puts it in the third argument by reference. + * If four arguments are given, gets a string from the + * vault and copies it to the third argument, up to + * 4th argument characters. + * + * @return Result as integer if only the first two arguments + * of the function are used. + * 1 if only the first three arguments are used. + * String length if all four parameters are used. + * @error On invalid vault handle. + */ +native nvault_get(vault, const key[], any:...); + +/** + * Retrieves full information about a vault entry. + * + * @param vault A vault handle returned from nvault_open() + * @param key A key to get information from + * @param value A string where the value should be stored + * @param maxlen Maximum length of the @value string + * @param timestamp The timestamp of the entry + * + * @return 1 if an entry was found, 0 otherwise. + * @error On invalid vault handle. + */ +native nvault_lookup(vault, const key[], value[], maxlen, ×tamp); + +/** + * Sets value of a vault entry and updates the timestamp. + * + * @note A new entry is created if one with the given key doesn't exist. + * + * @param vault A vault handle returned from nvault_open() + * @param key A key to set the value for + * @param value A value to set + * + * @noreturn + * @error On invalid vault handle. + */ +native nvault_set(vault, const key[], const value[]); + +/** + * Sets value of a vault entry and makes it permanent (non-erasable with nvault_prune()). + * + * @note A new entry is created if one with the given key doesn't exist. + * @note Permanent entries have no timestamp. + * + * @param vault A vault handle returned from nvault_open() + * @param key A key to set the permanent value for + * @param value A permanent value to set + * + * @noreturn + * @error On invalid vault handle. + */ +native nvault_pset(vault, const key[], const value[]); + +/** + * Prunes the vault for entries that are within the given timestamps. + * + * @note This will not erase values set with nvault_pset(). + * @note An example of pruning all entries that are older than 24 hours: + * nvault_prune(vaultHandle, 0, get_systime() - (60 * 60 * 24)); + * + * @param vault A vault handle returned from nvault_open() + * @param start The timestamp to start erasing from + * @param end The timestamp to erase to + * + * @return Number of erased values. + * @error On invalid vault handle. + */ +native nvault_prune(vault, start, end); + +/** + * Closes a vault. + * + * @param vault A vault handle returned from nvault_open() + * + * @noreturn + * @error On invalid vault handle. + */ +native nvault_close(vault); + +/** + * Removes an entry from the vault by its key. + * + * @param vault A vault handle returned from nvault_open() + * @param key The key to remove from the vault + * + * @noreturn + * @error On invalid vault handle. + */ +native nvault_remove(vault, const key[]); + +/** + * "Touches" an entry in the vault, updating its timestamp. + * + * @note If timestamp is equal to -1, it will use the current time. + * @note An empty entry is created if one with the given key doesn't exist. + * + * @param vault A vault handle returned from nvault_open() + * @param key The key to search for + * @param timestamp Update an entry's timestamp to this one. Default is -1. + * + * @noreturn + * @error On invalid vault handle. + */ +native nvault_touch(vault, const key[], timestamp=-1); diff --git a/amxmodx/scripting/include/regex.inc b/amxmodx/scripting/include/regex.inc new file mode 100644 index 0000000..5c777e4 --- /dev/null +++ b/amxmodx/scripting/include/regex.inc @@ -0,0 +1,348 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Regular Expressions API +// + +#if defined _regex_included + #endinput +#endif +#define _regex_included + +#pragma reqlib regex +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib regex +#endif + + +enum Regex +{ + REGEX_MATCH_FAIL = -2, + REGEX_PATTERN_FAIL = -1, + REGEX_NO_MATCH = 0, + REGEX_OK = 1 +}; + +/** + * Flags for compiling regex expressions. + * These come directly from the pcre library and can be used in regex_compile_ex. + */ +#define PCRE_CASELESS 0x00000001 /* Ignore Case */ +#define PCRE_MULTILINE 0x00000002 /* Multilines (affects ^ and $ so that they match the start/end of a line rather than matching the start/end of the string). */ +#define PCRE_DOTALL 0x00000004 /* Single line (affects . so that it matches any character, even new line characters). */ +#define PCRE_EXTENDED 0x00000008 /* Pattern extension (ignore whitespace and # comments). */ +#define PCRE_ANCHORED 0x00000010 /* Force pattern anchoring. */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* $ not to match newline at end. */ +#define PCRE_UNGREEDY 0x00000200 /* Invert greediness of quantifiers */ +#define PCRE_NOTEMPTY 0x00000400 /* An empty string is not a valid match. */ +#define PCRE_UTF8 0x00000800 /* Use UTF-8 Chars */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) */ +#define PCRE_NEVER_UTF 0x00010000 /* Lock out interpretation of the pattern as UTF-8 */ +#define PCRE_FIRSTLINE 0x00040000 /* Force matching to be before newline */ +#define PCRE_DUPNAMES 0x00080000 /* Allow duplicate names for subpattern */ +#define PCRE_NEWLINE_CR 0x00100000 /* Specify that a newline is indicated by a single character CR ) */ +#define PCRE_NEWLINE_CRLF 0x00300000 /* specify that a newline is indicated by the two-character CRLF sequence ) Overrides the default */ +#define PCRE_NEWLINE_ANY 0x00400000 /* Specify that any Unicode newline sequence should be recognized. ) newline definition (LF) */ +#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Specify that any of CR, LF and CRLF sequences should be recognized ) */ +#define PCRE_UCP 0x20000000 /* Change the way PCRE processes \B, \b, \D, \d, \S, \s, \W, \w etc. to use Unicode properties */ + +/** + * Regex expression error codes. + * This can be used with regex_compile_ex and regex_match_ex. + */ +enum /*RegexError*/ +{ + REGEX_ERROR_NONE = 0, /* No error */ + REGEX_ERROR_NOMATCH = -1, /* No match was found */ + REGEX_ERROR_NULL = -2, + REGEX_ERROR_BADOPTION = -3, + REGEX_ERROR_BADMAGIC = -4, + REGEX_ERROR_UNKNOWN_OPCODE = -5, + REGEX_ERROR_NOMEMORY = -6, + REGEX_ERROR_NOSUBSTRING = -7, + REGEX_ERROR_MATCHLIMIT = -8, + REGEX_ERROR_CALLOUT = -9, /* Never used by PCRE itself */ + REGEX_ERROR_BADUTF8 = -10, + REGEX_ERROR_BADUTF8_OFFSET = -11, + REGEX_ERROR_PARTIAL = -12, + REGEX_ERROR_BADPARTIAL = -13, + REGEX_ERROR_INTERNAL = -14, + REGEX_ERROR_BADCOUNT = -15, + REGEX_ERROR_DFA_UITEM = -16, + REGEX_ERROR_DFA_UCOND = -17, + REGEX_ERROR_DFA_UMLIMIT = -18, + REGEX_ERROR_DFA_WSSIZE = -19, + REGEX_ERROR_DFA_RECURSE = -20, + REGEX_ERROR_RECURSIONLIMIT = -21, + REGEX_ERROR_NULLWSLIMIT = -22, /* No longer actually used */ + REGEX_ERROR_BADNEWLINE = -23, + REGEX_ERROR_BADOFFSET = -24, + REGEX_ERROR_SHORTUTF8 = -25, + REGEX_ERROR_RECURSELOOP = -26, + REGEX_ERROR_JIT_STACKLIMIT = -27, + REGEX_ERROR_BADMODE = -28, + REGEX_ERROR_BADENDIANNESS = -29, + REGEX_ERROR_DFA_BADRESTART = -30, + REGEX_ERROR_JIT_BADOPTION = -31, + REGEX_ERROR_BADLENGTH = -32, + REGEX_ERROR_UNSET = -33 +}; + +/** + * Precompile a regular expression. + * + * @note Use this if you intend on using the same expression multiple times. + * Pass the regex handle returned here to regex_match_c to check for matches. + * + * @note This handle is automatically freed on map change. However, + * if you are completely done with it before then, you should + * call regex_free on this handle. + * + * @note Consider using regex_compile_ex instead if you want to use PCRE_* flags. + * + * @param pattern The regular expression pattern. + * @param ret Error code encountered, if applicable. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -1 on error in the pattern, > valid regex handle (> 0) on success. + */ +native Regex:regex_compile(const pattern[], &ret = 0, error[] = "", maxLen = 0, const flags[]=""); + +/** + * Matches a string against a pre-compiled regular expression pattern. + * + * @note You should free the returned handle with regex_free() + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, if applicable, or number of results on success. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +native regex_match_c(const string[], Regex:pattern, &ret = 0); + +/** + * Matches a string against a regular expression pattern. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. + * + * @note Flags only exist in amxmodx 1.8 and later. + * + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, or result state of the match. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) + */ +native Regex:regex_match(const string[], const pattern[], &ret = 0, error[] = "", maxLen = 0, const flags[] = ""); + +/** + * Returns a matched substring from a regex handle. + * + * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding + * regex_match* function call. + * + * @param id The regex handle to extract data from. + * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. + * @param buffer The buffer to set to the matching substring. + * @param maxLen The maximum string length of the buffer. + * + * @return 1 on success, otherwise 0 on failure. + */ +native regex_substr(Regex:id, str_id, buffer[], maxLen); + +/** + * Frees the memory associated with a regex result, and sets the handle to 0. + * + * @note This must be called on all results from regex_match() when you are done extracting + * the results with regex_substr(). + * + * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c()) + * only need to be freed when you are done using the pattern. + * + * @note Do not use the handle again after freeing it! + * + * @param id The regex handle to free. + * @noreturn + */ +native regex_free(&Regex:id); + + +/** + * The following natives are only available in 1.8.3 and above. + */ + +/** + * Precompile a regular expression. + * + * @note Use this if you intend on using the same expression multiple times. + * Pass the regex handle returned here to regex_match_c() to check for matches. + * + * @note Unlike regex_compile(), this allows you to use PCRE flags directly. + * + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression, see PCRE_* defines. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return Valid regex handle (> 0) on success, or -1 on failure. + */ +native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); + +/** + * Matches a string against a pre-compiled regular expression pattern, matching all + * occurrences of the pattern inside the string. This is similar to using the "g" flag + * in perl regex. + * + * @note You should free the returned handle (with regex_free()) + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + * + * @param pattern The regular expression pattern. + * @param string The string to check. + * @param ret Error code, if applicable, or number of results on success. + * See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +native regex_match_all_c(const string[], Regex:pattern, &ret = 0); + +/** + * Matches a string against a regular expression pattern, matching all occurrences of the + * pattern inside the string. This is similar to using the "g" flag in perl regex. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. + * + * @note Flags only exist in amxmodx 1.8 and later. + * + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression, see PCRE_* defines. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) + */ +native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); + +/** + * Matches a string against a regular expression pattern. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using compile regex_compile_ex and regex_match* + * instead of making this function reparse the expression each time. + * + * @param str The string to check. + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Pattern error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0) +{ + new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen, errcode); + if (regex < REGEX_OK) + { + return -1; + } + new substrings = regex_match_c(str, regex); + regex_free(regex); + return substrings; +} + +/** + * Flags used with regex_replace to control the replacement behavior. + */ +#define REGEX_FORMAT_DEFAULT 0 /* Uses the standard formatting rules to replace matches */ +#define REGEX_FORMAT_NOCOPY (1<<0) /* The sections that do not match the regular expression are not copied when replacing matches. */ +#define REGEX_FORMAT_FIRSTONLY (1<<1) /* Only the first occurrence of a regular expression is replaced. */ + +/** + * Perform a regular expression search and replace. + * + * An optional parameter, flags, allows you to specify options on how the replacement is performed. + * Supported format specifiers for replace parameter: + * $number : Substitutes the substring matched by group number. + * n must be an integer value designating a valid backreference, greater than 0, and of two digits at most. + * ${name} : Substitutes the substring matched by the named group name (a maximum of 32 characters). + * $& : Substitutes a copy of the whole match. + * $` : Substitutes all the text of the input string before the match. + * $' : Substitutes all the text of the input string after the match. + * $+ : Substitutes the last group that was captured. + * $_ : Substitutes the entire input string. + * $$ : Substitutes a literal "$". + * As note, the character \ can be also used with format specifier, this is same hehavior as $. + * + * @param pattern The regular expression pattern. + * @param string The string to check. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param replace The string will be used to replace any matches. See above for format specifiers. + * @param flags General flags to control how the string is replaced. See REGEX_FORMAT_* defines. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of matches. + */ +native regex_replace(Regex:pattern, string[], maxLen, const replace[], flags = REGEX_FORMAT_DEFAULT, &errcode = 0); diff --git a/amxmodx/scripting/include/sockets.inc b/amxmodx/scripting/include/sockets.inc new file mode 100644 index 0000000..6102a9e --- /dev/null +++ b/amxmodx/scripting/include/sockets.inc @@ -0,0 +1,183 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Socket Functions +// + +#if defined _socket_included + #endinput +#endif +#define _socket_included + +#pragma reqlib sockets +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib sockets +#endif + +/** + * Socket connection type (TCP/UDP) + */ +#define SOCKET_TCP 1 +#define SOCKET_UDP 2 + +/** + * Socket flags + */ +#define SOCK_NON_BLOCKING (1 << 0) /* Set the socket a nonblocking */ +#define SOCK_LIBC_ERRORS (1 << 1) /* Enable libc error reporting */ + +/** + * Error reporting + */ +#define SOCK_ERROR_OK 0 /* No error */ +#define SOCK_ERROR_CREATE_SOCKET 1 /* Couldn't create a socket */ +#define SOCK_ERROR_SERVER_UNKNOWN 2 /* Server unknown */ +#define SOCK_ERROR_WHILE_CONNECTING 3 /* Error while connecting */ + +/** + * Connects to the given node and service via TCP/UDP. + * + * @note There's 2 types of error reporting on this function that you can use. + * @note Default error codes: + * 0 - No error + * 1 - Error while creating socket + * 2 - Couldn't resolve hostname + * 3 - Couldn't connect + * @note New, more expressive libc error codes: + * https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html + * https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/errno.h + * https://msdn.microsoft.com/en-us/library/ms740668.aspx + * + * @note The currently available bit flags are: + * - SOCK_NON_BLOCKING : if set, the socket will be on nonblocking mode + * - SOCK_LIBC_ERRORS : if set, the new libc errors will be seen on _error + * + * @note If no flags are set, the behaviour of the function will not be modified. + * + * @note Multiple flags may be set at the same time using the | operator. + * For example, SOCK_NON_BLOCKING|SOCK_LIBC_ERRORS will create a nonblocking socket with libc error codes. + * + * @note If you're creating a new nonblocking socket, _hostname should be numeric to avoid calling the + * name resolution server and potentially blocking the call. + * + * @note If the socket is a nonblocking one, the returned socket descriptor may be still connecting and + * further checks should be done with socket_is_writable() before trying to send data. + * + * @param _hostname Node to connect to + * @param _port Service to connect to + * @param _protocol Connect via SOCKET_TCP or SOCKET_UDP + * @param _error Set an error code here if anything goes wrong + * @param _flags Optional bit flags that change the behaviour of the function + * + * @return A socket descriptor (a positive integer) on success + * -1 on failure +*/ +native socket_open(const _hostname[], _port, _protocol = SOCKET_TCP, &_error, _flags = 0); + +/** + * Closes a socket. + * + * @param _socket Socket descriptor + * + * @return 1 on success + * 0 on failure + */ +native socket_close(_socket); + +/** + * Receives data. + * + * @note The amount of bytes than you end up receiving can be less than the one you expected. + * + * @note This function will completely block the server until some data arrives + * to the given socket. Use this only if you are sure there is some data + * to be retrieved. You can do that by polling with socket_is_readable(). + * + * @param _socket Socket descriptor + * @param _data Array to save the data + * @param _length Length of the array + * + * @return Amount of bytes received + * 0 if the peer closed the connection + * -1 on failure + */ +native socket_recv(_socket, _data[], _length); + +/** + * Sends data. + * + * @note The amount of bytes that end up being sent may be lower than the total length of the array, + * check the return value and send the rest if needed. + * + * @param _socket Socket descriptor + * @param _data Array with the data to send + * @param _length Length of the array + * + * @return Amount of bytes sent + * -1 on failure + */ +native socket_send(_socket, const _data[], _length); + +/** + * Sends data that can contain null bytes. + * + * @note The amount of bytes that end up being sent may be lower than the total length of the array, + * check the return value and send the rest if needed. + * + * @note strlen(_data) will return the wrong length if the array contains null bytes. + * + * @param _socket Socket descriptor + * @param _data Array with the data to send + * @param _length Length of the array + * + * @return Amount of bytes sent + * -1 on failure + */ +native socket_send2(_socket, const _data[], _length); + +/** + * Backwards compatible function. + * + * @deprecated Renamed to socket_is_readable() + */ +#pragma deprecated Use socket_is_readable() instead +native socket_change(_socket, _timeout = 100000); + +/** + * Checks if a socket is marked as readable. + * + * @note You can use this function to make sure there's something on the socket and avoid a blocking call. + * @note Set _timeout to 0 avoid blocking the call. + * @note A socket will become readable if there's any data or an EOF. + * + * @param _socket Socket descriptor + * @param _timeout Amount of time to block the call waiting for the socket to be marked as readable or + * for the timeout to expire, in µSeconds (1 sec = 1000000 µsec) + * + * @return 1 if the socket is marked as readable + * 0 otherwise + */ +native socket_is_readable(_socket, _timeout = 100000); + +/** + * Checks if a socket is marked as writable. + * + * @note Use this function to check if a nonblocking socket is ready to be used. + * @note Set _timeout to 0 avoid blocking the call. + * @note An UDP socket is always writable. + * + * @param _socket Socket descriptor + * @param _timeout Amount of time to block the call waiting for the socket to be marked as writable or + * for the timeout to expire, in µSeconds (1 sec = 1000000 µsec) + * + * @return 1 if the socket is marked as writable + * 0 otherwise + */ +native socket_is_writable(_socket, _timeout = 100000); diff --git a/amxmodx/scripting/include/sorting.inc b/amxmodx/scripting/include/sorting.inc new file mode 100644 index 0000000..f4b259b --- /dev/null +++ b/amxmodx/scripting/include/sorting.inc @@ -0,0 +1,107 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Sorting Functions +// + +// +// All sort functions are based off the qsort() function from the +// C standard library, which uses the Quick Sort algorithm. +// For more info, see: http://linux.wku.edu/~lamonml/algor/sort/sort.html +// + +#if defined _sorting_included + #endinput +#endif +#define _sorting_included + +/** + * Contains sorting orders. + */ +enum SortMethod +{ + Sort_Ascending = 0, + Sort_Descending, + Sort_Random, +}; + +/** + * Data types for ADT Array Sorts + */ +enum SortType +{ + Sort_Integer = 0, + Sort_Float, + Sort_String, +}; +/** + * Basic sorting functions below. + */ + +native SortIntegers(array[], array_size, SortMethod:order = Sort_Ascending); + +native SortFloats(Float:array[], array_size, SortMethod:order = Sort_Ascending); + +native SortStrings(array[][], num_strings, SortMethod:order = Sort_Ascending); + +/** + * Custom sorting functions below. + */ + +/** + * Sorts a custom 1D array. You must pass in a comparison function. + * The sorting algorithm then uses your comparison function to sort the data. + * The function is called in the following manner: + * + * public MySortFunc(elem1, elem2, const array[], const data[], data_size) + * + * elem1, elem2 - Current element pair being compared + * array[] - Array in its current mid-sorted state. + * data[] - Extra data array you passed to the sort func. + * data_size - Size of extra data you passed to the sort func. + * + * Your function should return: + * -1 if elem1 should go before elem2 + * 0 if elem1 and elem2 are equal + * 1 if elem1 should go after elem2 + * Note that the parameters after elem2 are all optional and you do not need to specify them. + */ +native SortCustom1D(array[], array_size, const comparefunc[], data[]="", data_size=0); + + +/** + * Sorts a custom 2D array. + * The sorting algorithm then uses your comparison function to sort the data. + * The function is called in the following manner: + * + * public MySortFunc(const elem1[], const elem2[], const array[], data[], data_size) + * + * elem1[], elem2[] - Current element array pairs being compared + * array[][] - Array in its currently being sorted state. + * data[] - Extra data array you passed to the sort func. + * data_size - Size of extra data you passed to the sort func. + * + * Your function should return: + * -1 if elem1[] should go before elem2[] + * 0 if elem1[] and elem2 are equal[] + * 1 if elem1[] should go after elem2[] + * Note that the parameters after elem2[] are all optional and you do not need to specify them. + */ +native SortCustom2D(array[][], array_size, const comparefunc[], data[]="", data_size=0); + +/** + * Sort an ADT Array. Specify the type as Integer, Float, or String. + * + * @param array Array Handle to sort + * @param order Sort order to use, same as other sorts. + * @param type Data type stored in the ADT Array + * @noreturn + */ +native SortADTArray(Array:array, SortMethod:order, SortType:type); diff --git a/amxmodx/scripting/include/sqlx.inc b/amxmodx/scripting/include/sqlx.inc new file mode 100644 index 0000000..1c70f04 --- /dev/null +++ b/amxmodx/scripting/include/sqlx.inc @@ -0,0 +1,582 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// SQLX - Newer SQL Database API +// + +#if defined _sqlx_included + #endinput +#endif +#define _sqlx_included + +//eh.. +#define SQL_NumRows SQL_NumResults + +#pragma reqclass sqlx +#if !defined AMXMODX_NOAUTOLOAD + #pragma defclasslib sqlx mysql +#endif + +enum Handle +{ + Empty_Handle +}; + +/** + * Creates a connection information tuple. This tuple must be passed + * into connection routines. + * + * @note Freeing the tuple is not necessary, but is a good idea if you create + * many of them. You can cache these handles globally. + * @note This does not connect to the DB; it only caches the connection information. + * + * @param host Database host + * @param user Database user + * @param pass Database password + * @param db Database name to use + * @param timeout Specifies how long connections should wait before giving up. + * If <= 0, the default of 60s is used. + * + * @return A newly created tuple handle to be used in connection routines. + */ +native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[], timeout=0); + + +/** + * Frees an SQL handle. + * + * @note The handle can be to anything (tuple, connection, query, results, etc). + * @note If you free the database connection handle, it closes the connection as well. + * + * @param h Handle to be freed. + * + * @noreturn + */ +native SQL_FreeHandle(Handle:h); + + +/** + * Opens a database connection. + * + * @param cn_tuple Tuple handle, returned from SQL_MakeDbTuple(). + * @param errcode An error code set by reference. + * @param error String where error string will be stored. + * @param maxlength Maximum length of the error buffer. + * + * @return Returns an SQL connection handle, which must be freed. + * Returns Empty_Handle on failure. + * @error Invalid info tuple handle. + */ +native Handle:SQL_Connect(Handle:cn_tuple, &errcode, error[], maxlength); + + +/** + * Sets the character set of the current connection. + * Like SET NAMES .. in mysql, but stays after connection problems. + * + * @note If a connection tuple is supplied, this should be called before SQL_Connect or SQL_ThreadQuery. + * @note The change will remain until you call this function with another value. + * @note This native does nothing in SQLite. + * + * Example: "utf8", "latin1" + * + * @param h Database or connection tuple Handle. + * @param charset The character set string to change to. + * + * @return True, if character set was changed, false otherwise. + */ +native bool:SQL_SetCharset(Handle:h, const charset[]); + + +/** + * Prepares a query. + * + * @note This does not actually do a query! + * + * @param db Connection handle, returned from SQL_Connect(). + * @param fmt Query string. Can be formated with format specifiers. + * @param ... Additional format specifiers used to format the query. + * + * @return Returns an SQL query handle, which must always be freed. + * Returns Empty_Handle on failure. + */ +native Handle:SQL_PrepareQuery(Handle:db, const fmt[], any:...); + + +/** + * Back-quotes characters in a string for database querying. + * + * @note The buffer's maximum size should be 2*strlen(string) to catch all scenarios. + * + * @param db Database handle for localization, or Empty_Handle + * for when a handle is not available. + * @param buffer Buffer to copy to. + * @param buflen Maximum size of the buffer. + * @param string String to backquote (should not overlap buffer). + * + * @return Length of new string, or -1 on failure. + * @error Invalid database handle. + */ +native SQL_QuoteString(Handle:db, buffer[], buflen, const string[]); + +/** + * Back-quotes characters in a string for database querying. + * Note: The buffer's maximum size should be 2*strlen(string) to catch + * all scenarios. + * + * @param db Database handle for localization, or Empty_Handle + * for when a handle is not available. + * @param buffer Buffer to copy to. + * @param buflen Maximum size of the buffer. + * @param fmt Format of string to backquote (should not overlap buffer). + * @param ... Format arguments. + * + * @return Length of new string, or -1 on failure. + */ +native SQL_QuoteStringFmt(Handle:db, buffer[], buflen, const fmt[], any:...); + + +/** + * Threaded query states. Used to check the state of a complete threaded query. + */ +#define TQUERY_CONNECT_FAILED -2 +#define TQUERY_QUERY_FAILED -1 +#define TQUERY_SUCCESS 0 + +/** + * Prepares and executes a threaded query. + * @note The handler should look like: + * public QueryHandler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime) + * failstate - One of the three TQUERY_ defines. + * query - Handle to the query, do not free it. + * error - An error message, if any. + * errnum - An error code, if any. + * data - Data array you passed in. + * size - Size of the data array you passed in. + * queuetime - Amount of gametime that passed while the query was resolving. + * @note This will not interrupt gameplay in the event of a poor/lossed + * connection, however, the interface is more complicated and + * asynchronous. Furthermore, a new connection/disconnection is + * made for each query to simplify driver support. + * @note The handle does not need to be freed. + * + * @param db_tuple Tuple handle, returned from SQL_MakeDbTuple(). + * @param handler A function to be called when the query finishes. It has to be public. + * @param query The query string. + * @param data Additional data array that will be passed to the handler function. + * @param dataSize The size of the additional data array. + * + * @noreturn + * @error Thread worker was unable to start. + * Invalid info tuple handle. + * Handler function not found. + */ +native SQL_ThreadQuery(Handle:db_tuple, const handler[], const query[], const data[]="", dataSize=0); + + +/** + * Executes an already prepared query. + * + * @note You can call this multiple times as long as its parent connection is kept open. + * Each time the result set from the previous call will be freed. + * + * @param query Handle of a prepared query to be executed. + * + * @return 1 if the query succeeded, 0 if the query failed. + * @error Invalid query handle. + */ +native SQL_Execute(Handle:query); + + +/** + * Gets information about a failed query error. + * + * @param query Handle of a query to extract the error from. + * @param error Buffer where to store the error string. + * @param maxlength The maximum length of the output buffer. + * + * @return The error code. + */ +native SQL_QueryError(Handle:query, error[], maxlength); + + +/** + * Checks whether there are more results to be read. + * + * @param query Handle of a query to check. + * + * @return 1 if there are more results, 0 otherwise. + * @error Invalid query handle. + */ +native SQL_MoreResults(Handle:query); + + +/** + * Tells whether a specific column in the current row is NULL or not. + * + * @param query Handle of a query to check. + * @param column Which column to check for NULL. + * + * @return 1 if the column is NULL, 0 otherwise. + * @error Invalid query handle. + * No result set in this query. + * Invalid column. + */ +native SQL_IsNull(Handle:query, column); + + +/** + * Retrieves the current result. + * + * @note A successful query starts at the first result, so you should not call + * SQL_NextRow() first. + * + * @note Example how to get different types of values: + * new num = SQL_ReadResult(query, 0) + * new Float:num2 + * new string[32] + * SQL_ReadResult(query, 1, num2) + * SQL_ReadResult(query, 2, string, charsmax(string)) + * + * @param query Handle of a query to read results from. + * @param column Which column to get the value from. + * @param ... Passing no extra arguments - returns an integer. + * Passing one extra argument - returns a float in the first extra argument + * Passing two extra params - returns a string in the first argument + * with a maximum string length in the second argument. + * + * @return If no extra arguments are passed, returns an integer value. + * @error Invalid query handle. + */ +native SQL_ReadResult(Handle:query, column, any:...); + + +/** + * Advances to the next result (row). + * + * @param query Handle of a query. + * + * @noreturn + * @error Invalid query handle. + * No result set in this query. + */ +native SQL_NextRow(Handle:query); + + +/** + * Returns the number of affected rows by a query. + * + * @param query Handle of a query to check. + * + * @return The number of affected rows. + * @error Invalid query handle. + */ +native SQL_AffectedRows(Handle:query); + + +/** + * The number of retrieved rows (results) after a query. + * + * @param query Handle of a query to check. + * + * @return The number of retrieved rows by the query. + * @error Invalid query handle. + */ +native SQL_NumResults(Handle:query); + + +/** + * Returns the total number of columns. + * + * @param query Handle of a query to check. + * + * @return The number of retrieved columns by the query. + * @error Invalid query handle. + * No result set in this query. + */ +native SQL_NumColumns(Handle:query); + + +/** + * Retrieves the name of a column by its index. + * + * @param query Handle of a query. + * @param num The number (index) of a column to retrieve the name from. + * @param name Buffer where to store the column's name. + * @param maxlength Maximum length of the output buffer. + * + * @noreturn + * @error Invalid query handle. + * No result set in this query. + * Invalid column index. + */ +native SQL_FieldNumToName(Handle:query, num, name[], maxlength); + + +/** + * Retrieves the number of a named column. + * + * @param query Handle of a query. + * @param name Name to search for. + * + * @return Column index if found (>= 0); -1 otherwise. + * @error Invalid query handle. + * No result set in this query. + */ +native SQL_FieldNameToNum(Handle:query, const name[]); + + +/** + * Rewinds a result set to the first row. + * + * @param query Handle of a query to rewind the result set of. + * + * @noreturn + * @error Invalid query handle. + * No result set in this query. + */ +native SQL_Rewind(Handle:query); + + +/** + * Retrieves the instert ID of the latest INSERT query. + * + * @param query Handle of a query. + * + * @return The insert ID of the latest INSERT query. + * @error Invalid query handle. + */ +native SQL_GetInsertId(Handle:query); + + +/** + * Retrieves which driver is this plugin currently bound to. + * + * @param driver Buffer to store the driver name in. + * @param maxlen Maximum length of the output buffer. + * + * @noreturn + */ +native SQL_GetAffinity(driver[], maxlen); + + +/** + * Sets driver affinity. You can use this to force a particular driver implementation. + * This will automatically change all SQL natives in your plugin to be "bound" to + * the module in question. + * + * @note Using this while you have open handles to another database type will + * cause problems. I.e., you cannot open a handle, switch affinity, + * then close the handle with a different driver. + * @note Switching affinity is an O(n * m) operation, where n is the number of + * SQL natives and m is the number of used natives in total. + * @note Intuitive programmers will note that this causes problems for + * threaded queries. You will have to either force your script to work + * under one affinity, or to pack the affinity type into the query data, + * check it against the current, then set the new affinity if necessary. + * Then, restore the old one for safety. + * + * @param driver The name of a driver to use. + * + * @return If no module with the given name is found, returns 0. + * Unless your plugin is bult to handle different driver + * types at once, you should let this error pass. + */ +native SQL_SetAffinity(const driver[]); + +/** + * Returns the original query string that a query handle used. + * + * @param query Handle of a query. + * @param buffer Buffer where to put the query string in. + * @param maxlength The maximum length of the output buffer. + * + * @noreturn + * @error Invalid query handle. + */ +native SQL_GetQueryString(Handle:query, buffer[], maxlength); + +/** + * For queries which return multiple result sets, this advances to the next + * result set if one is available. Otherwise, the current result set is + * destroyed and will no longer be accessible. + * + * @note This function will always return false on SQLite, and when using threaded + * queries in MySQL. Nonetheless, it has the same effect of removing the last + * result set. + * + * @param query Query Handle. + * + * @return True on success, false on failure. + * @error Invalid query handle. + * No result set in this query. + */ +native bool:SQL_NextResultSet(Handle:query); + + +/** + * This function can be used to find out if a table in a SQLite database exists. + * + * @param db Connection handle returned from SQL_Connect(). + * @param table The table name to check for. + * + * @return True if it exists, false otherwise. + */ +stock bool:sqlite_TableExists(Handle:db, const table[]) +{ + new Handle:query = SQL_PrepareQuery( + db, + "SELECT name FROM sqlite_master WHERE type='table' AND name='%s' LIMIT 1;", + table); + + if (!SQL_Execute(query) || !SQL_NumResults(query)) + { + SQL_FreeHandle(query); + return false; + } + + SQL_FreeHandle(query); + + return true; +} + +/** + * Use this for executing a query where you don't care about the result. + * + * @param db Connection handle returned from SQL_Connect(). + * @param query The query string. + * @param error If an error occurs, it will be placed into this buffer. + * @param maxlength Maximum length of the error buffer. + * @param rows Optional. If put, retrieves the number of rows the query returned. + * + * @return 1 on success, 0 on failure. + */ +stock SQL_SimpleQuery(Handle:db, const query[], error[]="", maxlength=0, &rows=0) +{ + new Handle:hQuery = SQL_PrepareQuery(db, "%s", query); + + if (!SQL_Execute(hQuery)) + { + SQL_QueryError(hQuery, error, maxlength); + SQL_FreeHandle(hQuery); + return 0; + } + + rows = SQL_NumResults(hQuery); + + SQL_FreeHandle(hQuery); + + return 1; +} + + +/** + * Use this for executing a query where you don't care about the result. + * + * @note Differs from SQL_SimpleQuery() because the query can be formated. + * + * @param db Connection handle returned from SQL_Connect(). + * @param error If an error occurs, it will be placed into this buffer. + * @param maxlength The maximum length of the error buffer. + * @param rows Optional. If put, retrieves the number of rows the query returned. + * @param fmt The query string that can be formated with format specifiers. + * @param ... Additional arguments for formating the query. + * + * @return 1 on success, 0 on failure. + */ +stock SQL_SimpleQueryFmt(Handle:db, error[]="", maxlength=0, &rows=0, const fmt[], any:...) +{ + static query_buf[2048]; + vformat(query_buf, 2047, fmt, 6); + + new Handle:hQuery = SQL_PrepareQuery(db, "%s", query_buf); + + if (!SQL_Execute(hQuery)) + { + SQL_QueryError(hQuery, error, maxlength); + SQL_FreeHandle(hQuery); + return 0; + } + + rows = SQL_NumResults(hQuery); + + SQL_FreeHandle(hQuery); + + return 1; +} + +/** + * Use this for executing a query and not caring about the error. + * + * @param db A connection handle returned from SQL_Connect(). + * @param queryfmt The query string that can be formated with format specifiers. + * @pram ... Additional arguments for formating the query. + * + * @return 1 on error. + * >= 0 on success (with the number of affected rows). + */ +stock SQL_QueryAndIgnore(Handle:db, const queryfmt[], any:...) +{ + static query[4096]; + new Handle:hQuery; + new ret; + + vformat(query, sizeof(query)-1, queryfmt, 3); + + hQuery = SQL_PrepareQuery(db, "%s", query); + + if (SQL_Execute(hQuery)) + { + ret = SQL_AffectedRows(hQuery); + } else { + ret = -1; + } + + SQL_FreeHandle(hQuery); + + return ret; +} + +/** + * Use this for making a standard DB Tuple, using AMXX's database info cvars. + * + * @param timeout Specifies how long connections should wait before giving up. + * If 0, the value is read from "amx_sql_timeout" cvar. + * + * @return A newly created tuple handle to be used in connection routines. + */ +stock Handle:SQL_MakeStdTuple(timeout = 0) +{ + static host[64], user[32], pass[32], db[128]; + static get_type[12], set_type[12]; + + get_cvar_string("amx_sql_host", host, 63); + get_cvar_string("amx_sql_user", user, 31); + get_cvar_string("amx_sql_pass", pass, 31); + get_cvar_string("amx_sql_type", set_type, 11); + get_cvar_string("amx_sql_db", db, 127); + + if (timeout <= 0) + { + timeout = get_cvar_num("amx_sql_timeout"); + } + + SQL_GetAffinity(get_type, 12); + + if (!equali(get_type, set_type)) + { + if (!SQL_SetAffinity(set_type)) + { + log_amx("Failed to set affinity from %s to %s.", get_type, set_type); + } + } + + return SQL_MakeDbTuple(host, user, pass, db, timeout); +} diff --git a/amxmodx/scripting/include/string.inc b/amxmodx/scripting/include/string.inc new file mode 100644 index 0000000..d21676d --- /dev/null +++ b/amxmodx/scripting/include/string.inc @@ -0,0 +1,786 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// String Manipulation +// + +#if defined _string_included + #endinput +#endif +#define _string_included + +#include + +/** + * @global Unless otherwise noted, all string functions which take in a + * writable buffer and maximum length should NOT have the null terminator INCLUDED + * in the length. This means that this is valid: + * copy(string, charsmax(string), ...) + */ + +/** + * Calculates the length of a string. + * + * @param string String to check. + * @return Number of valid character bytes in the string. + */ +native strlen(const string[]); + +/** + * Tests whether a string is found inside another string. + * + * @param source String to search in. + * @param string Substring to find inside the original string. + * + * @return -1 on failure (no match found). Any other value + * indicates a position in the string where the match starts. + */ +native contain(const source[], const string[]); + +/** + * Tests whether a string is found inside another string with case ignoring. + * + * @note This supports multi-byte characters (UTF-8) on comparison. + * + * @param source String to search in. + * @param string Substring to find inside the original string. + * + * @return -1 on failure (no match found). Any other value + * indicates a position in the string where the match starts. + */ +native containi(const source[], const string[]); + +/** + * Given a string, replaces the first occurrence of a search string with a + * replacement string. + * + * @param text String to perform search and replacements on. + * @param len Maximum length of the string buffer. + * @param what String to search for. + * @param with String to replace the search string with. + * + * @return The new string length after replacement, or 0 if no replacements were made. + */ +native replace(text[], len, const what[], const with[]); + +/** + * Given a string, replaces all occurrences of a search string with a + * replacement string. + * + * @note Similar to replace_all() stock, but implemented as native and + * with different algorithm. This native doesn't error on bad + * buffer size and will smartly cut off the string in a way + * that pushes old data out. + * + * @note Only available in 1.8.3 and above. + * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. + * + * @param text String to perform search and replacements on. + * @param maxlength Maximum length of the string buffer. + * @param search String to search for. + * @param replace String to replace the search string with. + * @param caseSensitive If true (default), search is case sensitive. + * + * @return Number of replacements that were performed. + */ +native replace_string(text[], maxlength, const search[], const replace[], bool:caseSensitive = true); + +/** + * Given a string, replaces the first occurrence of a search string with a + * replacement string. + * + * @note Similar to replace() native, but implemented with more options and + * with different algorithm. This native doesn't error on bad + * buffer size and will smartly cut off the string in a way + * that pushes old data out. + * + * @note Only available in 1.8.3 and above. + * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. + * + * @param text String to perform search and replacements on. + * @param maxlength Maximum length of the string buffer. + * @param search String to search for. + * @param replace String to replace the search string with. + * @param searchLen If higher than -1, its value will be used instead of + * a strlen() call on the search parameter. + * @param replaceLen If higher than -1, its value will be used instead of + * a strlen() call on the replace parameter. + * @param caseSensitive If true (default), search is case sensitive. + * + * @return Index into the buffer (relative to the start) from where + * the last replacement ended, or -1 if no replacements were + * made. + */ +native replace_stringex(text[], maxlength, const search[], const replace[], searchLen = -1, replaceLen = -1, bool:caseSensitive = true); + +/** + * Concatenates one string onto another. + * + * @param dest String to append to. + * @param len Maximum length of entire buffer. + * @param src Source string to concatenate. + * @param max Number of characters to add. + * + * @return Number of of all merged characters. + */ +native add(dest[],len,const src[],max=0); + +/** + * Formats a string according to the AMX Mod X format rules (see documentation). + * + * @note Example: format(dest, "Hello %s. You are %d years old", "Tom", 17). + * If any of your input buffers overlap with the destination buffer, + * format() falls back to a "copy-back" version as of 1.65. This is + * slower, so you should using a source string that is the same as + * the destination. + * + * @param output Destination string buffer. + * @param len Maximum length of output string buffer. + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * + * @return Number of cells written. + */ +native format(output[], len, const format[], any:...); + +/** + * Formats a string according to the AMX Mod X format rules (see documentation). + * + * @note Same as format(), except does not perform a "copy back" check. + * This means formatex() is faster, but DOES NOT ALLOW this type + * of call: + * formatex(buffer, len, "%s", buffer) + * formatex(buffer, len, buffer, buffer) + * formatex(buffer, len, "%s", buffer[5]) + * This is because the output is directly stored into "buffer", + * rather than copied back at the end. + * + * @param output Destination string buffer. + * @param len Maximum length of output string buffer. + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * + * @return Number of cells written. + */ +native formatex(output[], len, const format[], any:...); + +/** + * Formats and returns a string according to the AMX Mod X format rules + * (see documentation). + * + * @note Example: menu_additem(menu, fmt("My first %s", "item")). + * @note This should only be used for simple inline formatting like in the above example. + * Avoid using this function to store strings into variables as an additional + * copying step is required. + * @note The buffer size is defined by MAX_FMT_LENGTH. + * + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * + * @return Formatted string + */ +native [MAX_FMT_LENGTH]fmt(const format[], any:...); + +/** + * Formats a string according to the AMX Mod X format rules (see documentation). + * + * @note This is the same as format(), except it grabs parameters from a + * parent parameter stack, rather than a local. This is useful for + * implementing your own variable argument functions. + * + * @note Replacement for format_args. Much faster and %L compatible. + * This works exactly like vsnprintf() from C. + * You must pass in the output buffer and its size, + * the string to format, and the number of the FIRST variable + * argument parameter. For example, for: + * function (a, b, c, ...) + * You would pass 4 (a is 1, b is 2, c is 3, et cetera). + * There is no vformatex(). + * + * @param buffer Destination string buffer. + * @param len Maximum length of output string buffer. + * @param fmt Formatting rules. + * @param vararg Argument number which contains the '...' symbol. + * Note: Arguments start at 1. + * @return Number of bytes written. + */ +native vformat(buffer[], len, const fmt[], vararg); + +/** + * Formats a string according to the AMX Mod X format rules (see documentation). + * + * @note Same as vformat(), except works in normal style dynamic natives. + * Instead of passing the format arg string, you can only pass the + * actual format argument number itself. + * If you pass 0, it will read the format string from an optional + * fifth parameter. + * + * @param buffer Destination string buffer. + * @param len Maximum length of output string buffer. + * @param fmt_arg Argument number which contains the format. + * @param vararg Argument number which contains the '...' symbol. + * Note: Arguments start at 1. + * @return Number of bytes written. + */ +native vdformat(buffer[], len, fmt_arg, vararg, ...); + +/** + * Gets parameters from function as formated string. + * + * @param output Destination string buffer. + * @param len Maximum length of output string buffer. + * @param pos Argument number which contains the '...' symbol. + * + * @return Number of bytes written. + */ +native format_args(output[], len, pos = 0); + +/** + * Converts an integer to a string. + * + * @param num Integer to convert. + * @param string Buffer to store string in. + * @param len Maximum length of string buffer. + * + * @return Number of cells written to buffer. + */ +native num_to_str(num,string[],len); + +/** + * Converts a string to an integer. + * + * @param string String to convert. + * @return Integer conversion of string, or 0 on failure. + */ +native str_to_num(const string[]); + +/** + * Parses the 'string' interpreting its content as an integral number of the specified 'base', + * which is returned as integer value. The function also sets the value of 'endPos' to point + * to the position of the first character after the number. + * + * This is the same as C++ strtol function with a difference on second param. + * + * The function first discards as many whitespace characters as necessary until the first + * non-whitespace character is found. Then, starting from this character, takes as many + * characters as possible that are valid following a syntax that depends on the 'base' parameter, + * and interprets them as a numerical value. Finally, a position of the first character following + * the integer representation in 'string' is stored in 'endPos'. + * + * If the value of 'base' is zero, the syntax expected is similar to that of integer constants, + * which is formed by a succession of : + * An optional sign character (+ or -) + * An optional prefix indicating octal or hexadecimal base ("0" or "0x"/"0X" respectively) + * A sequence of decimal digits (if no base prefix was specified) or either octal or hexadecimal digits if a specific prefix is present + * + * If the 'base' value is between 2 and 36, the format expected for the integral number is a succession + * of any of the valid digits and/or letters needed to represent integers of the specified radix + * (starting from '0' and up to 'z'/'Z' for radix 36). The sequence may optionally be preceded by + * a sign (either + or -) and, if base is 16, an optional "0x" or "0X" prefix. + * + * If the first sequence of non-whitespace characters in 'string' is not a valid integral number + * as defined above, or if no such sequence exists because either 'string' is empty or it contains + * only whitespace characters, no conversion is performed. + * + * @param string The string to parse. + * @param endPos The position of the first character following the number. + * On success and when containing only numbers, position is at the end of string, meaning equal to 'string' length. + * On failure, position is sets always to 0. + * @param base The numerical base (radix) that determines the valid characters and their interpretation. + * If this is 0, the base used is determined by the format in the sequence. + * @return On success, the function returns the converted integral number as integer value. + * If no valid conversion could be performed, a zero value is returned. + * If the value read is out of the range of representable values by a cell, + * the function returns 'cellmin' or 'cellmax'. + */ +native strtol(const string[], &endPos = 0, base = 0); + +/** + * Parses the 'string' interpreting its content as an floating point number and returns its value as a float. + * The function also sets the value of 'endPos' to point to the position of the first character after the number. + * + * This is the same as C++ strtod function with a difference on second param. + * + * The function first discards as many whitespace characters as necessary until the first + * non-whitespace character is found. Then, starting from this character, takes as many + * characters as possible that are valid and interprets them as a numerical value. + * Finally, a position of the first character following the float representation in 'string' + * is stored in 'endPos'. + * + * If the first sequence of non-whitespace characters in 'string' is not a valid float number + * as defined above, or if no such sequence exists because either 'string' is empty or it contains + * only whitespace characters, no conversion is performed. + * + * @param string The string to parse. + * @param endPos The position of the first character following the number. + * On success and when containing only numbers, position is at the end of string, meaning equal to 'string' length. + * On failure, position is sets always to 0. + * @return On success, the function returns the converted floating point number as float value. + * If no valid conversion could be performed, a zero value is returned. + */ +native Float:strtof(const string[], &endPos = 0); + +/** + * Converts a floating point number to a string. + * + * @param fl Floating point number to convert. + * @param string Buffer to store string in. + * @param len Maximum length of string buffer. + * + * @return Number of cells written to buffer. + */ +native float_to_str(Float:fl, string[], len); + +/** + * Converts a string to a floating point number. + * + * @param string String to convert to a foat. + * @return Floating point result, or 0.0 on error. + */ +native Float:str_to_float(const string[]); + +/** + * Returns whether two strings are equal. + * + * @param a First string (left). + * @param b Second string (right). + * @param c Number of characters to compare. + * + * @return True if equal, false otherwise. + */ +native equal(const a[],const b[],c=0); + +/** + * Returns whether two strings are equal with case ignoring. + * + * @note This supports multi-byte characters (UTF-8) on comparison. + * + * @param a First string (left). + * @param b Second string (right). + * @param c Number of characters to compare. + * + * @return True if equal, false otherwise. + */ +native equali(const a[], const b[], c = 0); + +/** + * Copies one string to another string. + * + * @note If the destination buffer is too small to hold the source string, the + * destination will be truncated. + * + * @param dest Destination string buffer to copy to. + * @param len Destination buffer length. + * @param src Source string buffer to copy from. + * + * @return Number of cells written. + */ +native copy(dest[],len,const src[]); + +/** + * Copies one string to another string until ch is found. + * + * @param dest Destination string buffer to copy to. + * @param len Destination buffer length. + * @param src Source string buffer to copy from. + * @param ch Character to search for. + * + * @return Number of cells written. + */ +native copyc(dest[],len,const src[],ch); + +/** + * Sets string with given character. + * + * @param src Destination string buffer to copy to. + * @param len Destination buffer length. + * @param ch Character to set string. + * + * @noreturn + */ +native setc(src[],len,ch); + +/** + * Gets parameters from text. + * + * @note Example: to split text: "^"This is^" the best year", + * call function like this: parse(text,arg1,len1,arg2,len2,arg3,len3,arg4,len4) + * and you will get: "This is", "the", "best", "year" + * Function returns number of parsed parameters. + * + * @param text String to parse. + * @param ... Variable number of format parameters. + * + * @return Number of parsed parameters. + */ +native parse(const text[], ... ); + +/** + * Breaks a string in two by token. + * + * @note Trimming spaces is buggy. Consider strtok2 instead. + * + * @note See argbreak() for doing this with parameters. + * Example: + * str1[] = This *is*some text + * strtok(str1, left, 24, right, 24, '*') + * left will be "This " + * Right will be "is*some text" + * If you use trimSpaces, all spaces are trimmed from Left. + * + * @param text String to tokenize + * @param Left Buffer to store left half + * @param leftLen Size of left buffer + * @param Right Buffer to store right half + * @param rightLen Size of right buffer + * @param token Token to split by + * @param trimSpaces Whether spaces are trimmed. + * + * @noreturn + */ +native strtok(const text[], Left[], leftLen, Right[], rightLen, token=' ', trimSpaces=0); + +/** + * Breaks a string in two by token. + * + * @note Only available in 1.8.3 and above. + * + * @param text String to tokenize + * @param left Buffer to store left half + * @param llen Size of left buffer + * @param right Buffer to store right half + * @param rlen Size of right buffer + * @param token Token to split by + * @param trim Flags for trimming behavior, see above + * + * @return Returns position of token in string if found, + * -1 if token was not found + */ +native strtok2(const text[], left[], const llen, right[], const rlen, const token = ' ', const trim = 0); + +/** + * Removes whitespace characters from the beginning and end of a string. + * + * @param text The string to trim. + * @return Number of bytes written. + */ +native trim(text[]); + +/** + * Converts all chars in string to lower case. + * + * @param string The string to convert. + * @return Number of bytes written. + */ +native strtolower(string[]); + +/** + * Performs a multi-byte safe (UTF-8) conversion of all chars in string to lower case. + * + * @note Although most code points can be converted in-place, there are notable + * exceptions and the final length can vary. + * @note Case mapping is not reversible. That is, toUpper(toLower(x)) != toLower(toUpper(x)). + * + * @param string The string to convert. + * @param maxlength Optional size of the buffer. If 0, the length of the original string + * will be used instead. + * + * @return Number of bytes written. + */ +native mb_strtolower(string[], maxlength = 0); + +/** + * Converts all chars in string to upper case. + * + * @param string The string to convert. + * @return Number of bytes written. + */ +native strtoupper(string[]); + +/** + * Performs a multi-byte safe (UTF-8) conversion of all chars in string to upper case. + * + * @note Although most code points can be converted in-place, there are notable + * exceptions and the final length can vary. + * @note Case mapping is not reversible. That is, toUpper(toLower(x)) != toLower(toUpper(x)). + * + * @param string The string to convert. + * @param maxlength Optional size of the buffer. If 0, the length of the original string + * will be used instead. + * + * @return Number of bytes written. + */ +native mb_strtoupper(string[], maxlength = 0); + +/** + * Make a string's first character uppercase. + * + * @param string The string to convert. + * @return 1 on success, otherwise 0. + */ +native ucfirst(string[]); + +/** + * Performs a multi-byte safe (UTF-8) conversion of a string's first character to upper case. + * + * @note Although most code points can be converted in-place, there are notable + * exceptions and the final length can vary. + * + * @param string The string to convert. + * @param maxlength Optional size of the buffer. If 0, the length of the original string + * will be used instead. + * + * @return Number of bytes written. + */ +native mb_ucfirst(string[], maxlength = 0); + +/** + * Performs a multi-byte safe (UTF-8) conversion of all chars in string to title case. + * + * @note Although most code points can be converted in-place, there are notable + * exceptions and the final length can vary. + * @note Any type of punctuation can break up a word, even if this is + * not grammatically valid. This happens because the titlecasing algorithm + * does not and cannot take grammar rules into account. + * @note Examples: + * The running man | The Running Man + * NATO Alliance | Nato Alliance + * You're amazing at building libraries | You'Re Amazing At Building Libraries + * + * @param string The string to convert. + * @param maxlength Optional size of the buffer. If 0, the length of the original string + * will be used instead. + * + * @return Number of bytes written. + */ +native mb_strtotitle(string[], maxlength = 0); + +/** + * Checks if the input string conforms to the category specified by the flags. + * + * @note This function can be used to check if the code points in a string are part + * of a category. Valid flags are part of the UTF8C_* list of defines. + * The category for a code point is defined as part of the entry in + * UnicodeData.txt, the data file for the Unicode code point database. + * @note Flags parameter must be a combination of UTF8C_* flags or a single UTF8C_IS* flag. + * In order to main backwards compatibility with POSIX functions like `isdigit` + * and `isspace`, compatibility flags have been provided. Note, however, that + * the result is only guaranteed to be correct for code points in the Basic + * Latin range, between U+0000 and 0+007F. Combining a compatibility flag with + * a regular category flag will result in undefined behavior. + * @note The function is greedy. This means it will try to match as many code + * points with the matching category flags as possible and return the offset in + * the input in bytes. + * + * @param input The string to check + * @param input_size Size of the string, use 1 to check one character regardless its size + * @param flags Requested category, see UTF8C_* flags + * @param output_size Number of bytes in the input that conform to the specified + * category flags + * @return True if the whole input of `input_size` conforms to the specified + * category flags, false otherwise + */ +native bool:is_string_category(const input[], input_size, flags, &output_size = 0); + +/** + * Returns whether a character is numeric. + * + * @note Multi-byte characters will always return false. + * + * @param ch Character to test. + * @return True if character is numeric, otherwise false. + */ +native isdigit(ch); + +/** + * Returns whether a character is an ASCII alphabet character. + * + * @note Multi-byte characters will always return false. + * + * @param ch Character to test. + * @return True if character is alphabetical, otherwise false. + */ +native isalpha(ch); + +/** + * Returns whether a character is whitespace. + * + * @note Multi-byte characters will always return false. + * + * @param ch Character to test. + * @return True if character is whitespace, otherwise false. + */ +native isspace(ch); + +/** + * Returns whether a character is numeric or an ASCII alphabet character. + * + * @note Multi-byte characters will always return false. + * + * @param ch Character to test. + * @return True if character is numeric, otherwise false. + */ +native isalnum(ch); + +/** + * Returns if a character is multi-byte or not. + * + * @note Only available in 1.8.3 and above. + * + * @param ch Character to test. + * @return 0 for a normal 7-bit ASCII character, + * otherwise number of bytes in multi-byte character. + */ +native is_char_mb(ch); + +/** + * Returns whether an alphabetic character is uppercase. + * + * @note Only available in 1.8.3 and above. + * @note Multi-byte characters will always return false. + * + * @param ch Character to test. + * @return True if character is uppercase, otherwise false. + */ +native bool:is_char_upper(ch); + +/** + * Returns whether an alphabetic character is lowercase. + * + * @note Only available in 1.8.3 and above. + * @note Multi-byte characters will always return false. + * + * @param ch Character to test. + * @return True if character is lowercase, otherwise false. + */ +native bool:is_char_lower(ch); + +/** + * Returns the number of bytes a character is using. This is + * for multi-byte characters (UTF-8). For normal ASCII characters, + * this will return 1. + * + * @note Only available in 1.8.3 and above. + * + * @param source Source input string. + * @return Number of bytes the current character uses. + */ +native get_char_bytes(const source[]); + +/** + * Concatenates one string onto another. + * + * @param dest String to append to. + * @param source Source string to concatenate. + * @param maxlength Maximum length of entire buffer. + * @return Number of bytes written. + */ +native strcat(dest[], const source[], maxlength); + +/** + * Tests whether a string is found inside another string. + * + * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. + * + * @param string String to search in. + * @param sub Substring to find inside the original string. + * @param ignorecase If true, search is case insensitive. + * If false (default), search is case sensitive. + * @param pos Start position to search from. + * @return -1 on failure (no match found). Any other value + * indicates a position in the string where the match starts. + */ +native strfind(const string[], const sub[], bool:ignorecase = false, pos = 0); + +/** + * Compares two strings lexographically. + * + * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. + * + * @param string1 First string (left). + * @param string2 Second string (right). + * @param ignorecase If true, comparison is case insensitive. + * If false (default), comparison is case sensitive. + * @return -1 if string1 < string2 + * 0 if string1 == string2 + * 1 if string1 > string2 + */ +native strcmp(const string1[], const string2[], bool:ignorecase = false); + +/** + * Compares two strings parts lexographically. + * + * @note Only available in 1.8.3 and above. + * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. + * + * @param string1 First string (left). + * @param string2 Second string (right). + * @param num Number of characters to compare. + * @param ignorecase If true, comparison is case insensitive. + * If false (default), comparison is case sensitive. + * @return -1 if string1 < string2 + * 0 if string1 == string2 + * 1 if string1 > string2 + */ +native strncmp(const string1[], const string2[], num, bool:ignorecase = false); + +/** + * Parses an argument string to find the first argument. You can use this to + * replace strbreak(). + * + * @note Only available in 1.8.3 and above. + * + * @note You can use argparse() to break a string into all of its arguments: + * new arg[N], pos; + * while (true) { + * pos = argparse(string, pos, arg, sizeof(arg) - 1); + * if (pos == -1) + * break; + * } + * + * @note All initial whitespace is removed. Remaining characters are read until an + * argument separator is encountered. A separator is any whitespace not inside + * a double-quotation pair (i.e. "x b" is one argument). If only one quotation + * mark appears, argparse() acts as if one existed at the end of the string. + * Quotation marks are never written back, and do not act as separators. For + * example, "a""b""c" will return "abc". An empty quote pair ("") will count + * as an argument containing no characters. + * + * @note argparse() will write an empty string to argbuffer if no argument is found. + * + * @param text String to tokenize. + * @param pos Position to start parsing from. + * @param argbuffer Buffer to store first argument. + * @param maxlen Size of the buffer. + * @return If no argument was found, -1 is returned. Otherwise, + * the index to the next position to parse from is + * returned. This might be the very end of the string. + */ +native argparse(const text[], pos, argbuffer[], maxlen); + +/** + * Returns text in a string up until a certain character sequence is reached. + * + * @note Only available in 1.8.3 and above. + * + * @param source Source input string. + * @param split A string which specifies a search point to break at. + * @param part Buffer to store string part. + * @param partLen Maximum length of the string part buffer. + * + * @return -1 if no match was found; otherwise, an index into source + * marking the first index after the searched text. The + * index is always relative to the start of the input string. + */ +native split_string(const source[], const split[], part[], partLen); + + +// Always keep this at the bottom of this file. +#include diff --git a/amxmodx/scripting/include/string_const.inc b/amxmodx/scripting/include/string_const.inc new file mode 100644 index 0000000..989282e --- /dev/null +++ b/amxmodx/scripting/include/string_const.inc @@ -0,0 +1,156 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// String Manipulation Constants +// + +#if defined _string_const_included + #endinput +#endif +#define _string_const_included + +#define charsmax(%1) (sizeof(%1)-1) + +/** + * @global Unless otherwise noted, all string functions which take in a + * writable buffer and maximum length should NOT have the null terminator INCLUDED + * in the length. This means that this is valid: + * copy(string, charsmax(string), ...) + */ + +/** + * Buffer size used by fmt(). + */ +#define MAX_FMT_LENGTH 256 + +/** + * Below are the trim flags for strtok2 + * + * You can specify how the left and right buffers will + * be trimmed by strtok2. LTRIM trims spaces from the + * left side. RTRIM trims from the right side. + * + * The defines TRIM_INNER, TRIM_OUTER and TRIM_FULL are + * shorthands for commonly used flag combinations. + * + * When the initial string is trimmed, using TRIM_INNER + * for all subsequent strtok2 calls will ensure that left + * and right are always trimmed from both sides. + * + * Examples: + * str1[] = " This is * some text " + * strtok2(str1, left, 24, right, 24, '*', TRIM_FULL) + * left will be "This is", right will be "some text" + * + * str2[] = " Here is | an | example " + * trim(str2) + * strtok2(str2, left, 24, right, 24, '|', TRIM_INNER) + * left will be "Here is", right will be "an | example" + * strtok2(right, left, 24, right, 24, '|', TRIM_INNER) + * left will be "an", right will be "example" + * + * str3[] = " One - more " + * strtok2(str3, left, 24, right, 24, '-', TRIM_OUTER) + * left will be "One ", right will be " more" + * + * str4[] = " Final . example " + * strtok2(str4, left, 24, right, 24, '.', LTRIM_LEFT|LTRIM_RIGHT) + * left will be "Final ", right will be "example " +*/ +#define LTRIM_LEFT (1<<0) +#define RTRIM_LEFT (1<<1) +#define LTRIM_RIGHT (1<<2) +#define RTRIM_RIGHT (1<<3) + +#define TRIM_INNER RTRIM_LEFT|LTRIM_RIGHT +#define TRIM_OUTER LTRIM_LEFT|RTRIM_RIGHT +#define TRIM_FULL TRIM_OUTER|TRIM_INNER + +/** + * Category flags to be used with is_string_category(), to check whether code points in a + * string are part of that category. + */ +#define UTF8C_LETTER_UPPERCASE 0x00000001 // Uppercase letter code points, Lu in the Unicode database. +#define UTF8C_LETTER_LOWERCASE 0x00000002 // Lowercase letter code points, Ll in the Unicode database. +#define UTF8C_LETTER_TITLECASE 0x00000004 // Titlecase letter code points, Lt in the Unicode database. +#define UTF8C_LETTER_MODIFIER 0x00000008 // Modifier letter code points, Lm in the Unicode database. +#define UTF8C_LETTER_OTHER 0x00000010 // Other letter code points, Lo in the Unicode database. + +// Combined flag for all letter categories with case mapping +// Combined flag for all letter categories +const UTF8C_LETTER = (UTF8C_LETTER_UPPERCASE | UTF8C_LETTER_LOWERCASE | UTF8C_LETTER_TITLECASE | UTF8C_LETTER_MODIFIER | UTF8C_LETTER_OTHER); +const UTF8C_CASE_MAPPED = (UTF8C_LETTER_UPPERCASE | UTF8C_LETTER_LOWERCASE | UTF8C_LETTER_TITLECASE); + +#define UTF8C_MARK_NON_SPACING 0x00000020 // Non-spacing mark code points, Mn in the Unicode database. +#define UTF8C_MARK_SPACING 0x00000040 // Spacing mark code points, Mc in the Unicode database. +#define UTF8C_MARK_ENCLOSING 0x00000080 // Enclosing mark code points, Me in the Unicode database. + +// Combined flag for all mark categories. +const UTF8C_MARK = (UTF8C_MARK_NON_SPACING | UTF8C_MARK_SPACING | UTF8C_MARK_ENCLOSING); + +#define UTF8C_NUMBER_DECIMAL 0x00000100 // Decimal number code points, Nd in the Unicode database. +#define UTF8C_NUMBER_LETTER 0x00000200 // Letter number code points, Nl in the Unicode database. +#define UTF8C_NUMBER_OTHER 0x00000400 // Other number code points, No in the Unicode database. + +// Combined flag for all number categories. +const UTF8C_NUMBER = (UTF8C_NUMBER_DECIMAL | UTF8C_NUMBER_LETTER | UTF8C_NUMBER_OTHER); + +#define UTF8C_PUNCTUATION_CONNECTOR 0x00000800 // Connector punctuation category, Pc in the Unicode database. +#define UTF8C_PUNCTUATION_DASH 0x00001000 // Dash punctuation category, Pd in the Unicode database. +#define UTF8C_PUNCTUATION_OPEN 0x00002000 // Open punctuation category, Ps in the Unicode database. +#define UTF8C_PUNCTUATION_CLOSE 0x00004000 // Close punctuation category, Pe in the Unicode database. +#define UTF8C_PUNCTUATION_INITIAL 0x00008000 // Initial punctuation category, Pi in the Unicode database. +#define UTF8C_PUNCTUATION_FINAL 0x00010000 // Final punctuation category, Pf in the Unicode database. +#define UTF8C_PUNCTUATION_OTHER 0x00020000 // Other punctuation category, Po in the Unicode database. + +// Combined flag for all punctuation categories. +const UTF8C_PUNCTUATION = (UTF8C_PUNCTUATION_CONNECTOR | UTF8C_PUNCTUATION_DASH | UTF8C_PUNCTUATION_OPEN | \ + UTF8C_PUNCTUATION_CLOSE | UTF8C_PUNCTUATION_INITIAL | UTF8C_PUNCTUATION_FINAL | \ + UTF8C_PUNCTUATION_OTHER); + +#define UTF8C_SYMBOL_MATH 0x00040000 // Math symbol category, Sm in the Unicode database. +#define UTF8C_SYMBOL_CURRENCY 0x00080000 // Currency symbol category, Sc in the Unicode database. +#define UTF8C_SYMBOL_MODIFIER 0x00100000 // Modifier symbol category, Sk in the Unicode database. +#define UTF8C_SYMBOL_OTHER 0x00200000 // Other symbol category, So in the Unicode database. + +// Combined flag for all symbol categories. +const UTF8C_SYMBOL = (UTF8C_SYMBOL_MATH | UTF8C_SYMBOL_CURRENCY | UTF8C_SYMBOL_MODIFIER | UTF8C_SYMBOL_OTHER); + +#define UTF8C_SEPARATOR_SPACE 0x00400000 // Space separator category, Zs in the Unicode database. +#define UTF8C_SEPARATOR_LINE 0x00800000 // Line separator category, Zl in the Unicode database. +#define UTF8C_SEPARATOR_PARAGRAPH 0x01000000 // Paragraph separator category, Zp in the Unicode database. + +// Combined flag for all separator categories. +const UTF8C_SEPARATOR = (UTF8C_SEPARATOR_SPACE | UTF8C_SEPARATOR_LINE | UTF8C_SEPARATOR_PARAGRAPH); + +#define UTF8C_CONTROL 0x02000000 // Control category, Cc in the Unicode database. +#define UTF8C_FORMAT 0x04000000 // Format category, Cf in the Unicode database. +#define UTF8C_SURROGATE 0x08000000 // Surrogate category, Cs in the Unicode database. +#define UTF8C_PRIVATE_USE 0x10000000 // Private use category, Co in the Unicode database. +#define UTF8C_UNASSIGNED 0x20000000 // Unassigned category, Cn in the Unicode database. +#define UTF8C_COMPATIBILITY 0x40000000 // Flag used for maintaining backwards compatibility with POSIX +#define UTF8C_IGNORE_GRAPHEME_CLUSTER 0x80000000 // Flag used for checking only the general category of code points at the start of a grapheme cluster. + +// Flag used for maintaining backwards compatibility with POSIX function +const UTF8C_ISCNTRL = (UTF8C_COMPATIBILITY | UTF8C_CONTROL); +const UTF8C_ISPRINT = (UTF8C_COMPATIBILITY | UTF8C_LETTER | UTF8C_NUMBER | UTF8C_PUNCTUATION | UTF8C_SYMBOL | UTF8C_SEPARATOR); +const UTF8C_ISSPACE = (UTF8C_COMPATIBILITY | UTF8C_SEPARATOR_SPACE); +const UTF8C_ISBLANK = (UTF8C_COMPATIBILITY | UTF8C_SEPARATOR_SPACE | UTF8C_PRIVATE_USE); +const UTF8C_ISGRAPH = (UTF8C_COMPATIBILITY | UTF8C_LETTER | UTF8C_NUMBER | UTF8C_PUNCTUATION | UTF8C_SYMBOL); +const UTF8C_ISPUNCT = (UTF8C_COMPATIBILITY | UTF8C_PUNCTUATION | UTF8C_SYMBOL); +const UTF8C_ISALNUM = (UTF8C_COMPATIBILITY | UTF8C_LETTER | UTF8C_NUMBER); +const UTF8C_ISALPHA = (UTF8C_COMPATIBILITY | UTF8C_LETTER); +const UTF8C_ISUPPER = (UTF8C_COMPATIBILITY | UTF8C_LETTER_UPPERCASE); +const UTF8C_ISLOWER = (UTF8C_COMPATIBILITY | UTF8C_LETTER_LOWERCASE); +const UTF8C_ISDIGIT = (UTF8C_COMPATIBILITY | UTF8C_NUMBER); +const UTF8C_ISXDIGIT = (UTF8C_COMPATIBILITY | UTF8C_NUMBER | UTF8C_PRIVATE_USE); + +// All flags. +const UTF8C_ALL = 0xFFFFFFFF & (~UTF8C_COMPATIBILITY); diff --git a/amxmodx/scripting/include/string_stocks.inc b/amxmodx/scripting/include/string_stocks.inc new file mode 100644 index 0000000..67acbd0 --- /dev/null +++ b/amxmodx/scripting/include/string_stocks.inc @@ -0,0 +1,325 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// String Manipulation Stocks +// + +#if defined _string_stocks_included + #endinput +#endif +#define _string_stocks_included + +#if !defined _string_included + #include +#endif + +/** + * @global Unless otherwise noted, all string functions which take in a + * writable buffer and maximum length should NOT have the null terminator INCLUDED + * in the length. This means that this is valid: + * copy(string, charsmax(string), ...) + */ + +/** + * Returns whether a given string contains only digits. + * This returns false for zero-length strings. + * + * @param sString Character to test. + * @return True if string contains only digit, otherwise false. + */ +stock bool:is_str_num(const sString[]) +{ + new i = 0; + + while (sString[i] && isdigit(sString[i])) + { + ++i; + } + + return sString[i] == 0 && i != 0; +} + +/** + * Returns an uppercase character to a lowercase character. + * + * @note Only available in 1.8.3 and above. + * + * @param chr Characer to convert. + * @return Lowercase character on success, + * no change on failure. + */ +stock char_to_upper(chr) +{ + if (is_char_lower(chr)) + { + return (chr & ~(1<<5)); + } + + return chr; +} + +/** + * Returns a lowercase character to an uppercase character. + * + * @note Only available in 1.8.3 and above. + * + * @param chr Characer to convert. + * @return Uppercase character on success, + * no change on failure. + */ +stock char_to_lower(chr) +{ + if (is_char_upper(chr)) + { + return (chr | (1<<5)); + } + + return chr; +} + +/** + * Backwards compatibility stock - use argbreak or argparse. + * @deprecated this function does not work properly. + */ +#pragma deprecated Use argbreak() instead +stock strbreak(const text[], Left[], leftLen, Right[], rightLen) +{ + return argbreak(text, Left, leftLen, Right, rightLen); +} + +/** + * Emulates strbreak() using argparse(). + * + * @param text Source input string. + * @param left Buffer to store string left part. + * @param leftlen Maximum length of the string part buffer. + * @param right Buffer to store string right part. + * @param rightlen Maximum length of the string part buffer. + * + * @return -1 if no match was found; otherwise, an index into source + * marking the first index after the searched text. The + * index is always relative to the start of the input string. + */ +stock argbreak(const text[], left[], leftlen, right[], rightlen) +{ + new pos = argparse(text, 0, left, leftlen); + + if (pos == -1) + { + return -1; + } + + new textlen = strlen(text); + + while (pos < textlen && isspace(text[pos])) + { + pos++; + } + + copy(right, rightlen, text[pos]); + + return pos; +} + +/** + * It is basically strbreak but you have a delimiter that is more than one character in length. By Suicid3. + * + * @param szInput Source input string. + * @param szLeft Buffer to store left string part. + * @param pL_Max Maximum length of the string part buffer. + * @param szRight Buffer to store right string part. + * @param pR_Max Maximum length of the string part buffer. + * @param szDelim A string which specifies a search point to break at. + * + * @noreturn + */ +stock split(const szInput[], szLeft[], pL_Max, szRight[], pR_Max, const szDelim[]) +{ + new iEnd = contain(szInput, szDelim); + new iStart = iEnd + strlen(szDelim); + + // If delimiter isnt in Input just split the string at max lengths + if (iEnd == -1) + { + iStart = copy(szLeft, pL_Max, szInput); + copy(szRight, pR_Max, szInput[iStart]); + return; + } + + // If delimter is in Input then split at input for max lengths + if (pL_Max >= iEnd) + copy(szLeft, iEnd, szInput); + else + copy(szLeft, pL_Max, szInput); + + copy(szRight, pR_Max, szInput[iStart]); +} + +/** + * Removes a path from szFilePath leaving the name of the file in szFile for a pMax length. + * + * @param szFilePath String to perform search and replacements on. + * @param szFile Buffer to store file name. + * @param pMax Maximum length of the string buffer. + * + * @noreturn + */ +stock remove_filepath(const szFilePath[], szFile[], pMax) +{ + new len = strlen(szFilePath); + + while ((--len >= 0) && (szFilePath[len] != '/') && (szFilePath[len] != '\')) { } + + copy(szFile, pMax, szFilePath[len + 1]); + + return; +} + +/** + * Replaces a contained string iteratively. + * + * @note Consider using replace_string() instead. + * + * @note This ensures that no infinite replacements will take place by + * intelligently moving to the next string position each iteration. + * + * @param string String to perform search and replacements on. + * @param len Maximum length of the string buffer. + * @param what String to search for. + * @param with String to replace the search string with. + * + * @return Number of replacements on success, otherwise 0. + */ +stock replace_all(string[], len, const what[], const with[]) +{ + new pos = 0; + + if ((pos = contain(string, what)) == -1) + { + return 0; + } + + new total = 0; + new with_len = strlen(with); + new diff = strlen(what) - with_len; + new total_len = strlen(string); + new temp_pos = 0; + + while (replace(string[pos], len - pos, what, with) != 0) + { + total++; + + /* jump to position after replacement */ + pos += with_len; + + /* update cached length of string */ + total_len -= diff; + + /* will the next call be operating on the last character? */ + if (pos >= total_len) + { + break; + } + + /* find the next position from our offset */ + temp_pos = contain(string[pos], what); + + /* if it's invalid, we're done */ + if (temp_pos == -1) + { + break; + } + + /* otherwise, reposition and update counters */ + pos += temp_pos; + } + + return total; +} + +/** + * Breaks a string into pieces and stores each piece into an array of buffers. + * + * @param text The string to split. + * @param split The string to use as a split delimiter. + * @param buffers An array of string buffers (2D array). + * @param maxStrings Number of string buffers (first dimension size). + * @param maxStringLength Maximum length of each string buffer. + * @param copyRemainder False (default) discard excess pieces, true to ignore + * delimiters after last piece. + * @return Number of strings retrieved. + */ +stock explode_string(const text[], const split[], buffers[][], maxStrings, maxStringLength, bool:copyRemainder = false) +{ + new reloc_idx, idx, total; + + if (maxStrings < 1 || !split[0]) + { + return 0; + } + + while ((idx = split_string(text[reloc_idx], split, buffers[total], maxStringLength)) != -1) + { + reloc_idx += idx; + if (++total == maxStrings) + { + if (copyRemainder) + { + copy(buffers[total-1], maxStringLength, text[reloc_idx-idx]); + } + return total; + } + } + + copy(buffers[total++], maxStringLength, text[reloc_idx]); + + return total; +} + +/** + * Joins an array of strings into one string, with a "join" string inserted in + * between each given string. This function complements ExplodeString. + * + * @param strings An array of strings. + * @param numStrings Number of strings in the array. + * @param join The join string to insert between each string. + * @param buffer Output buffer to write the joined string to. + * @param maxLength Maximum length of the output buffer. + * @return Number of bytes written to the output buffer. + */ +stock implode_strings(const strings[][], numStrings, const join[], buffer[], maxLength) +{ + new total, length, part_length; + new join_length = strlen(join); + + for (new i=0; i + * + * Example file below. Note that the second line is technically invalid. + * The event handler must decide whether this should be allowed. + * --FILE BELOW-- + * [gaben] + * hi = clams + * bye = "NO CLAMS" + * + * [valve] + * cannot + * maintain + * products + */ + +/** + * Parser invalid code. + */ +enum INIParser +{ + Invalid_INIParser = 0 +}; + +/** + * Creates a new INI parser. + * This is used to set parse hooks. + * + * @return A new handle to an INI Parse structure. + */ +native INIParser:INI_CreateParser(); + +/** + * Disposes of an INI parser. + * + * @param handle Handle to an INI Parse structure. + * + * @return True if disposed, false otherwise. + */ +native INI_DestroyParser(&INIParser:handle); + +/** + * Parses an INI config file. + * + * @param handle A handle to an INI Parse structure. + * @param file A string containing the file path. + * @param line An optional by reference cell to store the last line number read. + * @param col An optional by reference cell to store the last column number read. + * @param data An optional handle or value to pass through to callback functions + * + * @return An SMCParseError result. + * @error Invalid or corrupt handle. + */ +native bool:INI_ParseFile(INIParser:handle, const file[], &line = 0, &col = 0, any:data = 0); + +/** + * Sets the INI_ParseStart function of a parse handle. + * + * @note Below is the prototype of callback: + * - + * Called when parsing is started. + * + * @param handle A handle to an INI Parse structure. + * @param data Handle or value passed in INI_ParseFile + * + * @noreturn + * + * public OnParseStart(INIParser:handle, any:data) + * - + * @param handle Handle to an INI Parse structure. + * @param func A ParseStart callback. + * + * @noreturn + * @error Invalid or corrupt handle. + */ +native INI_SetParseStart(INIParser:handle, const func[]); + +/** + * Sets the INI_ParseEnd function of a parse handle. + * + * @note Below is the prototype of callback: + * - + * Called when parsing is halted. + * + * @param handle A handle to an INI Parse structure. + * @param halted True if abnormally halted, false otherwise. + * @param data Handle or value passed in INI_ParseFile + * + * @noreturn + * + * public OnParseEnd(INIParser:handle, bool:halted, any:data) + * - + * @param handle Handle to an INI Parse structure. + * @param func A ParseEnd callback. + * + * @noreturn + * @error Invalid or corrupt handle. + */ +native INI_SetParseEnd(INIParser:handle, const func[]); + +/** + * Sets the two main reader functions. + * + * @note Below is the prototype of callback: + * - + * NewSection: + * Called when the parser finds a new section. + * + * @param handle Handle to an INI Parse structure. + * @param section Name of section in between the [ and ] characters. + * @param invalid_tokens True if invalid tokens were detected in the name. + * @param close_bracket True if a closing bracket was detected, false otherwise. + * @param extra_tokens True if extra tokens were detected on the line. + * @param curtok Contains current token in the line where the section name starts. + * You can add to this offset when failing to point to a token. + * @param data Handle or value passed in INI_ParseFile + * + * @return True to keep parsing, false otherwise. + * + * public bool:OnNewSection(INIParser:handle, const section[], bool:invalid_tokens, bool:close_bracket, bool:extra_tokens, curtok, any:data) + * + * KeyValue: + * Called when the parser finds a new key/value pair. + * + * @param handle Handle to an INI Parse structure. + * @param key Name of key. + * @param value String containing value (with quotes stripped, if any). + * @param invalid_tokens Whether or not the key contained invalid tokens. + * @param equal_token There was an '=' sign present (in case the value is missing). + * @param quotes Whether value was enclosed in quotes. + * @param curtok Contains the token index of the start of the value string. + * This can be changed when returning false. + * @param data Handle or value passed in INI_ParseFile + * + * @return True to keep parsing, false otherwise. + * + * public bool:OnKeyValue(INIParser:handle, const key[], const value[], bool:invalid_tokens, bool:equal_token, bool:quotes, curtok, any:data) + * - + * @param handle Handle to an INI Parse structure. + * @param kv A KeyValue callback. + * @param ns An optional NewSection callback. + * + * @noreturn + */ +native INI_SetReaders(INIParser:smc, const kvFunc[], const nsFunc[] = "" ); + +/** + * Sets a raw line reader on an INI parser handle. + * + * @note Below is the prototype of callback: + * - + * Called whenever a raw line is read. + * + * @param handle The INI Parse handle. + * @param line Contents of line. + * @param lineno The line number it occurs on. + * @param curtok Pointer to optionally store failed position in string. + * @param data Handle or value passed in INI_ParseFile + * + * @return True to keep parsing, false otherwise. + * + * public bool:OnRawLine(INIParser:smc, const line[], lineno, curtok, any:data) + * + * @param handle Handle to an INI Parse structure. + * @param func A RawLine callback. + * + * @noreturn + */ +native INI_SetRawLine(INIParser:handle, const func[]); diff --git a/amxmodx/scripting/include/textparse_smc.inc b/amxmodx/scripting/include/textparse_smc.inc new file mode 100644 index 0000000..f97f244 --- /dev/null +++ b/amxmodx/scripting/include/textparse_smc.inc @@ -0,0 +1,261 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// SMC Parser Functions +// + +#if defined _textparse_smc_included + #endinput +#endif +#define _textparse_smc_included + +/** + * Everything below describes the SMC Parse, or "SourceMod Configuration" format. + * This parser is entirely event based. You must hook events to receive data. + * The file format itself is nearly identical to Valve's KeyValues format (also known as VDF). + */ + +/** + * The SMC file format is defined as: + * WHITESPACE: 0x20, \n, \t, \r + * IDENTIFIER: Any ASCII character EXCLUDING ", {, }, ;, //, / *, or WHITESPACE. + * STRING : Any set of symbols enclosed in quotes. + * + * Note: if a STRING does not have quotes, it is parsed as an IDENTIFIER. + * + * Basic syntax is comprised of SECTIONBLOCKs. + * A SECTIONBLOCK defined as: + * + * SECTIONNAME + * { + * OPTION + * } + * + * OPTION can be repeated any number of times inside a SECTIONBLOCK. + * A new line will terminate an OPTION, but there can be more than one OPTION per line. + * OPTION is defined any of: + * "KEY" "VALUE" + * SECTIONBLOCK + * + * SECTIONNAME, KEY, VALUE, and SINGLEKEY are strings + * SECTIONNAME cannot have trailing characters if quoted, but the quotes can be optionally removed. + * If SECTIONNAME is not enclosed in quotes, the entire sectionname string is used (minus surrounding whitespace). + * If KEY is not enclosed in quotes, the key is terminated at first whitespace. + * If VALUE is not properly enclosed in quotes, the entire value string is used (minus surrounding whitespace). + * The VALUE may have inner quotes, but the key string may not. + * + * For an example, see scripting/testsuite/textparse_test.cfg + * + * WHITESPACE should be ignored. + * Comments are text occurring inside the following tokens, and should be stripped + * unless they are inside literal strings: + * ; + * // + * / * * / + */ + +/** + * Parser invalid code. + */ +enum SMCParser +{ + Invalid_SMCParser = 0 +}; + +/** + * Parse result directive. + */ +enum SMCResult +{ + SMCParse_Continue, /* Continue parsing */ + SMCParse_Halt, /* Stop parsing here */ + SMCParse_HaltFail /* Stop parsing and return failure */ +}; + +/** + * Parse error codes. + */ +enum SMCError +{ + SMCError_Okay = 0, /* No error */ + SMCError_StreamOpen, /* Stream failed to open */ + SMCError_StreamError, /* The stream died... somehow */ + SMCError_Custom, /* A custom handler threw an error */ + SMCError_InvalidSection1, /* A section was declared without quotes, and had extra tokens */ + SMCError_InvalidSection2, /* A section was declared without any header */ + SMCError_InvalidSection3, /* A section ending was declared with too many unknown tokens */ + SMCError_InvalidSection4, /* A section ending has no matching beginning */ + SMCError_InvalidSection5, /* A section beginning has no matching ending */ + SMCError_InvalidTokens, /* There were too many unidentifiable strings on one line */ + SMCError_TokenOverflow, /* The token buffer overflowed */ + SMCError_InvalidProperty1, /* A property was declared outside of any section */ +}; + +/** + * Creates a new SMC parser. + * This is used to set parse hooks. + * + * @return A new handle to an SMC Parse structure. + */ +native SMCParser:SMC_CreateParser(); + +/** + * Disposes of an SMC parser. + * + * @param handle Handle to an SMC Parse structure. + * + * @return True if disposed, false otherwise. + */ +native SMC_DestroyParser(&SMCParser:handle); + +/** + * Parses a config file. + * + * @param handle A handle to an SMC Parse structure. + * @param file A string containing the file path. + * @param line An optional by reference cell to store the last line number read. + * @param col An optional by reference cell to store the last column number read. + * @param data An optional handle or value to pass through to callback functions + * + * @return An SMCParseError result. + * @error Invalid or corrupt handle. + */ +native SMCError:SMC_ParseFile(SMCParser:handle, const file[], &line = 0, &col = 0, any:data = 0); + +/** + * Sets the SMC_ParseStart function of a parse handle. + * + * @note Below is the prototype of callback: + * - + * Called when parsing is started. + * + * @param handle Handle to an SMC Parse structure. + * @param data Handle or value passed in SMC_ParseFile + * + * @noreturn + * + * public OnParseStart(SMCParser:handle, any:data) + * - + * @param handle Handle to an SMC Parse structure. + * @param func A ParseStart callback. + * + * @noreturn + * @error Invalid or corrupt handle. + */ +native SMC_SetParseStart(SMCParser:handle, const func[]); + +/** + * Sets the SMC_ParseEnd function of a parse handle. + * + * @note Below is the prototype of callback: + * - + * Called when parsing is halted. + * + * @param handle Handle to an SMC Parse structure. + * @param halted True if abnormally halted, false otherwise. + * @param failed True if parsing failed, false otherwise. + * @param data Handle or value passed in SMC_ParseFile + * + * @noreturn + * + * public OnParseEnd(SMCParser:handle, bool:halted, bool:failed, any:data) + * - + * @param handle Handle to an SMC Parse structure. + * @param func A ParseEnd callback. + * + * @noreturn + * @error Invalid or corrupt handle. + */ +native SMC_SetParseEnd(SMCParser:handle, const func[]); + +/** + * Sets the three main reader functions. + * + * @note Enclosing quotes are always stripped. + * @note Below is the prototype of callbacks: + * - + * NewSection: + * Called when the parser finds a new section or sub-section. + * + * @param handle Handle to an SMC Parse structure. + * @param name String containing section name. + * @param data Handle or value passed in SMC_ParseFile + * + * @return An SMCResult action to take. + * + * public SMCResult:OnNewSection(SMCParser:handle, const name[], any:data) + * + * KeyValue: + * Called when the parser finds a new key/value pair. + * + * @param handle Handle to an SMC Parse structure. + * @param key String containing key name. + * @param value String containing value name. + * @param data Handle or value passed in SMC_ParseFile + * + * @return An SMCResult action to take. + * + * public SMCResult:OnKeyValue(SMCParser:handle, const key[], const value[], any:data) + * + * EndSection: + * Called when the parser finds the end of the current section. + * + * @param handle Handle to an SMC Parse structure. + * @param data Handle or value passed in SMC_ParseFile + * + * @return An SMCResult action to take. + * + * public SMCResult:OnEndSection(SMCParser:handle, any:data) + * - + * @param handle Handle to an SMC Parse structure. + * @param kv A KeyValue callback. + * @param ns An optional NewSection callback. + * @param es An optional EndSection callback. + * + * @noreturn + */ +native SMC_SetReaders(SMCParser:smc, const kvFunc[], const nsFunc[] = "", const esFunc[] = ""); + +/** + * Sets a raw line reader on an text parser handle. + * + * @note Below is the prototype of callbacks: + * - + * Called whenever a raw line is read. + * + * @param handle Handle to an SMC Parse structure. + * @param line A string containing the raw line from the file. + * @param lineno The line number it occurs on. + * @param data Handle or value passed in SMC_ParseFile + * + * @return An SMCResult action to take. + * + * public SMCResult:SMC_RawLine(SMCParser:handle, const line[], lineno, any:data) + * - + * @param handle Handle to an SMC Parse structure. + * @param func A RawLine callback. + * + * @noreturn + */ +native SMC_SetRawLine(SMCParser:handle, const func[]); + +/** + * Gets an error string for an SMCError code. + * + * @note SMCError_Okay returns false. + * @note SMCError_Custom (which is thrown on SMCParse_HaltFail) returns false. + * + * @param error The SMCParseError code. + * @param buffer A string buffer for the error (contents undefined on failure). + * @param buf_max The maximum size of the buffer. + * + * @return True on success, false otherwise. + */ +native bool:SMC_GetErrorString(SMCError:error, buffer[], buf_max); diff --git a/amxmodx/scripting/include/tfcconst.inc b/amxmodx/scripting/include/tfcconst.inc new file mode 100644 index 0000000..7c41a05 --- /dev/null +++ b/amxmodx/scripting/include/tfcconst.inc @@ -0,0 +1,84 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TFCX Constants +// + +#if defined _tfcconst_included + #endinput +#endif +#define _tfcconst_included + + +#define TFCMAX_WEAPONS 37 + +enum { + TFC_AMMO_SHELLS = 0, + TFC_AMMO_BULLETS, + TFC_AMMO_CELLS, + TFC_AMMO_ROCKETS, + TFC_AMMO_NADE1, + TFC_AMMO_NADE2, +}; + +enum { + TFC_WPN_NONE = 0, + TFC_WPN_TIMER,//TFC_WPN_UNK1, + TFC_WPN_SENTRYGUN,//TFC_WPN_UNK2, + TFC_WPN_MEDIKIT, + TFC_WPN_SPANNER, + TFC_WPN_AXE, + TFC_WPN_SNIPERRIFLE, + TFC_WPN_AUTORIFLE, + TFC_WPN_SHOTGUN, + TFC_WPN_SUPERSHOTGUN, + TFC_WPN_NG, + TFC_WPN_SUPERNG, + TFC_WPN_GL, + TFC_WPN_FLAMETHROWER, + TFC_WPN_RPG, + TFC_WPN_IC, + TFC_WPN_FLAMES,//TFC_WPN_UNK16, + TFC_WPN_AC, + TFC_WPN_UNK18, + TFC_WPN_UNK19, + TFC_WPN_TRANQ, + TFC_WPN_RAILGUN, + TFC_WPN_PL, + TFC_WPN_KNIFE, + TFC_WPN_CALTROP, // 24 + TFC_WPN_CONCUSSIONGRENADE, + TFC_WPN_NORMALGRENADE, + TFC_WPN_NAILGRENADE, + TFC_WPN_MIRVGRENADE, + TFC_WPN_NAPALMGRENADE, + TFC_WPN_GASGRENADE, + TFC_WPN_EMPGRENADE, +}; + +enum { + TFC_PC_SCOUT = 1, + TFC_PC_SNIPER, + TFC_PC_SOLDIER, + TFC_PC_DEMOMAN, + TFC_PC_MEDIC, + TFC_PC_HWGUY, + TFC_PC_PYRO, + TFC_PC_SPY, + TFC_PC_ENGENEER, // Typo; preserved for backward compatibility + TFC_PC_ENGINEER = 9, + TFC_PC_CIVILIAN = 11, +}; + +// Goal items +#define TFC_GOALITEM_BLUE (1 << 17) +#define TFC_GOALITEM_RED (1 << 18) +#define TFC_GOALITEM_YELLOW (1 << 24) +#define TFC_GOALITEM_GREEN (1 << 25) diff --git a/amxmodx/scripting/include/tfcstats.inc b/amxmodx/scripting/include/tfcstats.inc new file mode 100644 index 0000000..367406a --- /dev/null +++ b/amxmodx/scripting/include/tfcstats.inc @@ -0,0 +1,62 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TFCX Stats Functions +// + +#if defined _tfcstats_included + #endinput +#endif +#define _tfcstats_included + +/* Gets stats from given weapon index. If wpnindex is 0 +* then the stats are from all weapons. If weapon has not been used function +* returns 0 in other case 1. Fields in stats are: +* 0 - kills +* 1 - deaths +* 2 - headshots +* 3 - teamkilling +* 4 - shots +* 5 - hits +* 6 - damage +* For body hits fields see amxconst.inc. */ +native get_user_wstats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets round stats from given weapon index.*/ +native get_user_wrstats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets overall stats which are stored in file on server +* and updated on every respawn or user disconnect. +* Function returns the position in stats by diff. kills to deaths. */ +native get_user_stats(index,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets round stats of player. */ +native get_user_rstats(index,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets stats with which user have killed/hurt his victim. If victim is 0 +* then stats are from all victims. If victim has not been hurt, function +* returns 0 in other case 1. User stats are reset on his respawn. */ +native get_user_vstats(index,victim,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS],wpnname[]="",len=0); + +/* Gets stats with which user have been killed/hurt. If killer is 0 +* then stats are from all attacks. If killer has not hurt user, function +* returns 0 in other case 1. User stats are reset on his respawn. */ +native get_user_astats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS],wpnname[]="",len=0); + +/* Resets life, weapon, victims and attackers user stats. */ +native reset_user_wstats(index); + +/* Gets overall stats which stored in stats.dat file in amx folder +* and updated on every mapchange or user disconnect. +* Function returns next index of stats entry or 0 if no more exists. */ +native get_stats(index,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS],name[],len); + +/* Returns number of all entries in stats. */ +native get_statsnum(); diff --git a/amxmodx/scripting/include/tfcx.inc b/amxmodx/scripting/include/tfcx.inc new file mode 100644 index 0000000..0da0118 --- /dev/null +++ b/amxmodx/scripting/include/tfcx.inc @@ -0,0 +1,148 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TFCX Functions +// + +#if defined _tfcx_included + #endinput +#endif +#define _tfcx_included + +#include +#include + +#pragma reqclass xstats +#if !defined AMXMODX_NOAUTOLOAD + #pragma defclasslib xstats tfcx +#endif + +/************* Shared Natives Start ********************************/ + +/* Forward types */ +enum { + XMF_DAMAGE = 0, + XMF_DEATH, +}; + +/* Use this function to register forwards */ +native register_statsfwd( ftype ); + +/* Function is called after player to player attacks , +* if players were damaged by teammate TA is set to 1 */ +forward client_damage(attacker,victim,damage,wpnindex,hitplace,TA); + +/* Function is called after player death , +* if player was killed by teammate TK is set to 1 */ +forward client_death(killer,victim,wpnindex,hitplace,TK); + +/* Custom Weapon Support */ +/* function will return index of new weapon */ +native custom_weapon_add( const wpnname[],melee = 0,const logname[]="" ); +/* Function will pass damage done by this custom weapon to stats module and other plugins */ +native custom_weapon_dmg( weapon, att, vic, damage, hitplace=0 ); +/* Function will pass info about custom weapon shot to stats module */ +native custom_weapon_shot( weapon,index ); // weapon id , player id + +/* function will return 1 if true */ +native xmod_is_melee_wpn(wpnindex); + +/* Returns weapon name. */ +native xmod_get_wpnname(wpnindex,name[],len); + +/* Returns weapon logname. */ +native xmod_get_wpnlogname(wpnindex,name[],len); + +/* Returns weapons array size */ +native xmod_get_maxweapons(); + +/* Returns stats array size ex. 8 in TS , 9 in DoD */ +native xmod_get_stats_size(); + +/* Returns 1 if true */ +native xmod_is_custom_wpn(wpnindex); + +/************* Shared Natives End ********************************/ + +stock tfc_isgrenade( weapon ){ + switch( weapon ) + { + case TFC_WPN_CALTROP, + TFC_WPN_CONCUSSIONGRENADE, + TFC_WPN_NORMALGRENADE, + TFC_WPN_NAILGRENADE, + TFC_WPN_MIRVGRENADE, + TFC_WPN_NAPALMGRENADE, + TFC_WPN_GASGRENADE, + TFC_WPN_EMPGRENADE: + return 1; + default: return 0; + } + return 0; +} + +native tfc_userkill( index ); + +/* Use this function to set private data offsets if needed +Default offsets: + timer: 932 + sentrygun: 83 +from AssKicR + shells: 53 + bullets: 55 + cells: 57 + rockets: 59 + nade1: 14 + nade2: 15 +*/ +native tfc_setpddata(timer,sentrygun,shells,bullets,cells,rockets,nade1,nade2); + +/*********************************************************************/ + +native tfc_setmodel(index, const Model[], const Skin[]); +native tfc_clearmodel(index); + +/* Get amount of ammo in backpack on a user for a specific weapon */ +/* Ammo Types in tfcconst.inc */ +native tfc_getbammo(index, ammo); + +/* Set amount of ammo in backpack on a user for a specific weapon */ +native tfc_setbammo(index, ammo, value); + +/* Returns amount of ammo in weapon's clip (backpack) */ +/* Weapons list in tfcconst.inc */ +native tfc_getweaponbammo(index, weapon); + +/* Sets amount of ammo in weapon's clip (backpack) */ +native tfc_setweaponbammo(index, weapon, value); + +/* Returns amount of ammo in weapon's clip */ +/* Index must be weapon's entity index */ +native tfc_getweaponammo(index); + +/* Sets amount of ammo in weapon's clip */ +/* Index must be weapon's entity index */ +native tfc_setweaponammo(index, value); + +/* Returns 1 if user is carrying a goal item such as a flag or a keycard, else 0. + * Team is by reference parameter that will be set to owning team(s) of the goal item. + * Use the TFC_GOALITEM_* constants to determine the owning team. + */ +native tfc_get_user_goalitem(index, &team); + +/* Returns 1 if the player is a spy and is currently feigning death */ +native tfc_is_user_feigning(index); + +/* Returns 1 if the two teams are allies, 0 otherwise + * Note: Team must be 1->4 + * Team 0 will always return 0 + * Any other team will result in an error + */ +native tfc_is_team_ally(TeamA,TeamB); diff --git a/amxmodx/scripting/include/time.inc b/amxmodx/scripting/include/time.inc new file mode 100644 index 0000000..34b91f6 --- /dev/null +++ b/amxmodx/scripting/include/time.inc @@ -0,0 +1,100 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Time Specific Functions +// + +#if defined _time_included + #endinput +#endif +#define _time_included + +/* Time unit types for get_time_length() */ +enum +{ + timeunit_seconds = 0, + timeunit_minutes, + timeunit_hours, + timeunit_days, + timeunit_weeks, +}; + +/* Seconds in each time unit */ +#define SECONDS_IN_MINUTE 60 +#define SECONDS_IN_HOUR 3600 +#define SECONDS_IN_DAY 86400 +#define SECONDS_IN_WEEK 604800 + +/** + * Stock by Brad. + * + * @note You must add register_dictionary("time.txt") in plugin_init() + * + * @param id The player whose language the length should be translated to + * @param unitCnt The number of time units you want translated into verbose text + * @param type The type of unit (i.e. seconds, minutes, hours, days, weeks) that you are passing in + * @param output The variable you want the verbose text to be placed in + * @param outputLen The length of the output variable + * + * @noreturn + */ +stock get_time_length(id, unitCnt, type, output[], outputLen) +{ + if (unitCnt > 0) + { + // determine the number of each time unit there are + new weekCnt = 0, dayCnt = 0, hourCnt = 0, minuteCnt = 0, secondCnt = 0; + + switch (type) + { + case timeunit_seconds: secondCnt = unitCnt; + case timeunit_minutes: secondCnt = unitCnt * SECONDS_IN_MINUTE; + case timeunit_hours: secondCnt = unitCnt * SECONDS_IN_HOUR; + case timeunit_days: secondCnt = unitCnt * SECONDS_IN_DAY; + case timeunit_weeks: secondCnt = unitCnt * SECONDS_IN_WEEK; + } + + weekCnt = secondCnt / SECONDS_IN_WEEK; + secondCnt -= (weekCnt * SECONDS_IN_WEEK); + + dayCnt = secondCnt / SECONDS_IN_DAY; + secondCnt -= (dayCnt * SECONDS_IN_DAY); + + hourCnt = secondCnt / SECONDS_IN_HOUR; + secondCnt -= (hourCnt * SECONDS_IN_HOUR); + + minuteCnt = secondCnt / SECONDS_IN_MINUTE; + secondCnt -= (minuteCnt * SECONDS_IN_MINUTE); + + // translate the unit counts into verbose text + new maxElementIdx = -1; + new timeElement[5][33]; + + if (weekCnt > 0) + format(timeElement[++maxElementIdx], charsmax(timeElement[]), "%i %L", weekCnt, id, (weekCnt == 1) ? "TIME_ELEMENT_WEEK" : "TIME_ELEMENT_WEEKS"); + if (dayCnt > 0) + format(timeElement[++maxElementIdx], charsmax(timeElement[]), "%i %L", dayCnt, id, (dayCnt == 1) ? "TIME_ELEMENT_DAY" : "TIME_ELEMENT_DAYS"); + if (hourCnt > 0) + format(timeElement[++maxElementIdx], charsmax(timeElement[]), "%i %L", hourCnt, id, (hourCnt == 1) ? "TIME_ELEMENT_HOUR" : "TIME_ELEMENT_HOURS"); + if (minuteCnt > 0) + format(timeElement[++maxElementIdx], charsmax(timeElement[]), "%i %L", minuteCnt, id, (minuteCnt == 1) ? "TIME_ELEMENT_MINUTE" : "TIME_ELEMENT_MINUTES"); + if (secondCnt > 0) + format(timeElement[++maxElementIdx], charsmax(timeElement[]), "%i %L", secondCnt, id, (secondCnt == 1) ? "TIME_ELEMENT_SECOND" : "TIME_ELEMENT_SECONDS"); + + switch(maxElementIdx) + { + case 0: formatex(output, outputLen, "%s", timeElement[0]); + case 1: formatex(output, outputLen, "%s %L %s", timeElement[0], id, "TIME_ELEMENT_AND", timeElement[1]); + case 2: formatex(output, outputLen, "%s, %s %L %s", timeElement[0], timeElement[1], id, "TIME_ELEMENT_AND", timeElement[2]); + case 3: formatex(output, outputLen, "%s, %s, %s %L %s", timeElement[0], timeElement[1], timeElement[2], id, "TIME_ELEMENT_AND", timeElement[3]); + case 4: formatex(output, outputLen, "%s, %s, %s, %s %L %s", timeElement[0], timeElement[1], timeElement[2], timeElement[3], id, "TIME_ELEMENT_AND", timeElement[4]); + } + } +} diff --git a/amxmodx/scripting/include/tsconst.inc b/amxmodx/scripting/include/tsconst.inc new file mode 100644 index 0000000..b41a2c5 --- /dev/null +++ b/amxmodx/scripting/include/tsconst.inc @@ -0,0 +1,154 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// Copyright (C) 2005 Suzuka. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TSFUN Constants +// + +#if defined _tsconst_included + #endinput +#endif +#define _tsconst_included + +#define TSMAX_WEAPONS 44 // 37 + throwing knife + brekable + 5 custom weapon slots + +#define TSPWUP_NONE 0 +#define TSPWUP_RANDOM 0 +#define TSPWUP_SLOWMO 1 +#define TSPWUP_INFAMMO 2 +#define TSPWUP_KUNGFU 4 +#define TSPWUP_SLOWPAUSE 8 +#define TSPWUP_DFIRERATE 16 +#define TSPWUP_GRENADE 32 +#define TSPWUP_HEALTH 64 +#define TSPWUP_ARMOR 128 +#define TSPWUP_SUPERJUMP 256 + +#define TSITEM_KUNGFU 1<<0 +#define TSITEM_SUPERJUMP 1<<1 + +#define TSKF_STUNTKILL 1<<0 +#define TSKF_SLIDINGKILL 1<<1 +#define TSKF_DOUBLEKILL 1<<2 +#define TSKF_ISSPEC 1<<3 +#define TSKF_KILLEDSPEC 1<<4 + +#define TSA_SILENCER 1 +#define TSA_LASERSIGHT 2 +#define TSA_FLASHLIGHT 4 +#define TSA_SCOPE 8 + +#define TSMSG_NORMAL 6 +#define TSMSG_WAITING 11 +#define TSMSG_DEAD 1 +#define TSMSG_KILLER 2 +#define TSMSG_DEMOLITION 3 +#define TSMSG_SPECIALIST 4 +#define TSMSG_UNSTOPPABLE 5 +#define TSMSG_THEONE 10 + +#define STUNT_NONE 0 +#define STUNT_DUCK 1 +#define STUNT_ROLL 2 +#define STUNT_DIVE 3 +#define STUNT_GETUP 4 +#define STUNT_FLIP 5 + +enum { + TSW_GLOCK18 = 1, + TSW_UNK1, + TSW_UZI, + TSW_M3, + TSW_M4A1, + TSW_MP5SD, + TSW_MP5K, + TSW_ABERETTAS, + TSW_MK23, + TSW_AMK23, + TSW_USAS, + TSW_DEAGLE, + TSW_AK47, + TSW_57, + TSW_AUG, + TSW_AUZI, + TSW_TMP, + TSW_M82A1, + TSW_MP7, + TSW_SPAS, + TSW_GCOLTS, + TSW_GLOCK20, + TSW_UMP, + TSW_M61GRENADE, + TSW_CKNIFE, + TSW_MOSSBERG, + TSW_M16A4, + TSW_MK1, + TSW_C4, + TSW_A57, + TSW_RBULL, + TSW_M60E3, + TSW_SAWED_OFF, + TSW_KATANA, + TSW_SKNIFE, + TSW_KUNG_FU, + TSW_TKNIFE, +}; + +/* +valid tsweaponid in TS_GiveWeapon + +1: "Glock 18" +3: "Mini Uzi" +4: "Benelli M3" +5: "M4A1" +6: "MP5SD" +7: "MP5K" +8: "Akimbo Berettas" +9: "Socom Mk23" +11: "Usas12" +12: "Desert Eagle" +13: "Ak47" +14: "FiveSeven" +15: "Steyr Aug" +17: "Steyr Tmp" +18: "Barrett M82" +19: "HK Pdw" +20: "Spas12" +21: "Akimbo colts" +22: "Glock 20" +23: "Mac10" +25: "Combat Knife" +26: "Mossberg 500" +27: "M16A4" +28: "Ruger Mk1" +24: "M61 Grenade" +29: "C4" +31: "Raging Bull" +32: "M60" +33: "Sawed off" +34: "Katana" +35: "Seal Knife" + +valid pwuptype in TS_GivePwUp + +0: "Random" +1: "Slow Motion" +2: "Infinite Clip" +4: "Kung Fu" +8: "Slow Pause" +16: "Double Firerate" +32: "Grenade" +64: "Health" +128: "Armor" +256: "Superjump" + +*/ + + diff --git a/amxmodx/scripting/include/tsfun.inc b/amxmodx/scripting/include/tsfun.inc new file mode 100644 index 0000000..c224275 --- /dev/null +++ b/amxmodx/scripting/include/tsfun.inc @@ -0,0 +1,198 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TSFUN Functions +// + +#if defined _tsxfun_included + #endinput +#endif +#define _tsxfun_included + +#include +#include + +/************* Shared Natives Start ********************************/ + +/* Forward types */ +enum { + XMF_DAMAGE = 0, + XMF_DEATH, +}; + +#pragma reqlib tsfun +#if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib tsfun +#endif + +/************* Shared Natives End ********************************/ + +/* Function is called just before a kung foo attack is done, + * damage and time length may be altered with natives. + * Return PLUGIN_HANDLED to stop attack. + * UNAVAILABLE IN 1.70 + */ +forward Melee_Attack(id,Float:time,Float:damage,UNAVAILABLE); + + +// Returns when someone stunts, after they do it. +//UNAVAILABLE IN 1.70 +forward client_stunt(id,stunttype,UNAVAILABLE); + +/* Function is called when powerups are ran, + * Returns value of powerup. Use TSPWUP_*'s + * to find exactly which one it is. + * UNAVAILABLE IN 1.70 + */ +forward client_powerup(id,powerup,UNAVAILABLE); + +/* weapon logname to weapon name convertion */ +native ts_wpnlogtoname(const logname[],name[],len); + +/* weapon logname to weapon index convertion */ +native ts_wpnlogtoid(const logname[]); + +//UNAVAILABLE IN 1.70 +//native Float:ts_getusertime( index ); //! +//native ts_setusertime( index, Float:time ); //! + +native ts_getusercash( index ); +native ts_setusercash( index, money ); + +native ts_getuserslots( index ); +native ts_setuserslots( index, slots ); + +native ts_getuserstate( index ); +native ts_getuserwpn( index,&clip=0,&ammo=0,&mode=0,&extra=0 ); +native ts_getuserspace( index ); + +native ts_getuserkillflags(killer); +native ts_getkillingstreak( index ); +native ts_getuserlastfrag( index ); + +native ts_giveweapon( index,weapon,clips,extra ); + +native ts_getuserpwup( index ); + +stock ts_has_slowmo(id) { + return (ts_getuserpwup(id) &TSPWUP_SLOWMO); +} + +stock ts_has_infammo(id) { + return (ts_getuserpwup(id) &TSPWUP_INFAMMO); +} + +stock ts_has_slowpause(id) { + return (ts_getuserpwup(id) &TSPWUP_SLOWPAUSE); +} + +stock ts_has_dfirerate(id) { + return (ts_getuserpwup(id) &TSPWUP_DFIRERATE); +} + +stock ts_has_grenade(id) { + return (ts_getuserpwup(id) &TSPWUP_GRENADE); +} + +stock ts_has_health(id) { + return (ts_getuserpwup(id) &TSPWUP_HEALTH); +} + +stock ts_has_armor(id) { + return (ts_getuserpwup(id) &TSPWUP_ARMOR); +} + +/* Function will create pwup entity and return its index (pwupent) */ +native ts_createpwup( pwup ); + +native ts_givepwup( index,pwupent ); + +native ts_setpddata( knifeoffset ); + +// Alters a fu attack. Use with fu forward +// UNAVAILABLE IN 1.70 +// native ts_set_fuattack(id,Float:time,Float:damage); //! + +// Changes board message +native ts_set_message(id,message); + +// Gets the message board message +native ts_get_message(id); + +stock ts_is_normal(id) +{ + new msg = ts_get_message(id); + if( (msg > 11) || (msg > 6 && msg < 10) ) return 1; + return 0; +} + +stock ts_is_waiting(id) { + return (ts_get_message(id) == TSMSG_WAITING); +} + +stock ts_is_dead(id) { + return (ts_get_message(id) == TSMSG_DEAD); +} + +stock ts_is_killer(id) { + return (ts_get_message(id) == TSMSG_KILLER); +} + +stock ts_is_demolition(id) { + return (ts_get_message(id) == TSMSG_DEMOLITION); +} + +stock ts_is_specialist(id) { + return (ts_get_message(id) == TSMSG_SPECIALIST); +} + +stock ts_is_unstoppable(id) { + return (ts_get_message(id) == TSMSG_UNSTOPPABLE); +} + +stock ts_is_theone(id) { + return (ts_get_message(id) == TSMSG_THEONE); +} + +// Return one on true, 0 on false +// UNAVAILABLE IN 1.70 +native ts_has_superjump(id); //! +native ts_has_fupowerup(id); //! +native ts_is_in_slowmo(id); + +// Get and set consecutive frags +//UNAVAILABLE IN 1.70 +//native ts_get_cons_frags(id); +//native ts_set_cons_frags(id,num); + +// Set to see cool bullet trails. Only id will see them. +native ts_set_bullettrail(id,yesorno); + +// Sets fake versions of slow mo and slow pause. Use ts_set_speed for more options. +native ts_set_fakeslowmo(id,Float:time); +native ts_set_fakeslowpause(id,Float:time); + +/* Sets speed artificially. 1.0 is default, Go into fractions and decimals for slower +* and put in higher numbers for higher speeds. Aura is how far things around you are effected +* Time is the time until it wears off. 0.0 for speed will freeze people. Do not use negatives. */ + +native ts_set_speed(id,Float:speed,Float:auradist,Float:time); + +/* Sets physics speed artificially. Things like sparks and sounds will be effected. +* Any negative number will render all physics paused. */ +native ts_set_physics_speed(id,Float:speed); + +// Returns 0 if no powerup is running. Returns the powerup type otherwise. +native ts_is_running_powerup(id); + +// Highly experimental command which overrides powerup types. +// Use if a powerup is already running, or if a powerup is not running. +// Safe to use in powerup forward. +native ts_force_run_powerup(id,PWUP_TYPE); diff --git a/amxmodx/scripting/include/tsstats.inc b/amxmodx/scripting/include/tsstats.inc new file mode 100644 index 0000000..dd2ba60 --- /dev/null +++ b/amxmodx/scripting/include/tsstats.inc @@ -0,0 +1,65 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TSX Stats Functions +// + +#if defined _tsstats_included + #endinput +#endif +#define _tsstats_included + +/* Gets stats from given weapon index. If wpnindex is 0 +* then the stats are from all weapons. If weapon has not been used function +* returns 0 in other case 1. Fields in stats are: +* 0 - kills +* 1 - deaths +* 2 - headshots +* 3 - teamkilling +* 4 - shots +* 5 - hits +* 6 - damage +* For body hits fields see amxconst.inc. */ +native get_user_wstats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets round stats from given weapon index.*/ +native get_user_wrstats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets life (from spawn to spawn) stats from given weapon index.*/ +native get_user_wlstats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets overall stats which are stored in file on server +* and updated on every respawn or user disconnect. +* Function returns the position in stats by diff. kills to deaths. */ +native get_user_stats(index,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets round stats of player. */ +native get_user_rstats(index,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS]); + +/* Gets stats with which user have killed/hurt his victim. If victim is 0 +* then stats are from all victims. If victim has not been hurt, function +* returns 0 in other case 1. User stats are reset on his respawn. */ +native get_user_vstats(index,victim,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS],wpnname[]="",len=0); + +/* Gets stats with which user have been killed/hurt. If killer is 0 +* then stats are from all attacks. If killer has not hurt user, function +* returns 0 in other case 1. User stats are reset on his respawn. */ +native get_user_astats(index,wpnindex,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS],wpnname[]="",len=0); + +/* Resets life, weapon, victims and attackers user stats. */ +native reset_user_wstats(index); + +/* Gets overall stats which stored in stats.dat file in amx folder +* and updated on every mapchange or user disconnect. +* Function returns next index of stats entry or 0 if no more exists. */ +native get_stats(index,stats[STATSX_MAX_STATS],bodyhits[MAX_BODYHITS],name[],len); + +/* Returns number of all entries in stats. */ +native get_statsnum(); diff --git a/amxmodx/scripting/include/tsx.inc b/amxmodx/scripting/include/tsx.inc new file mode 100644 index 0000000..e9592af --- /dev/null +++ b/amxmodx/scripting/include/tsx.inc @@ -0,0 +1,88 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// TSX Functions +// + +#if defined _tsx_included + #endinput +#endif +#define _tsx_included + +#include + +#pragma reqclass xstats +#if !defined AMXMODX_NOAUTOLOAD + #pragma defclasslib xstats tsx +#endif + +/************* Shared Natives Start ********************************/ + +/* Forward types */ +enum { + XMF_DAMAGE = 0, + XMF_DEATH, +}; + +/* Use this function to register forwards + * DEPRECATED + */ +native register_statsfwd( ftype ); + +/* Function is called after player to player attacks , +* if players were damaged by teammate TA is set to 1 */ +forward client_damage(attacker,victim,damage,wpnindex,hitplace,TA); + +/* Function is called after player death , +* if player was killed by teammate TK is set to 1 */ +forward client_death(killer,victim,wpnindex,hitplace,TK); + +/* Custom Weapon Support */ +/* function will return index of new weapon */ +native custom_weapon_add( const wpnname[],melee = 0,const logname[]="" ); +/* Function will pass damage done by this custom weapon to stats module and other plugins */ +native custom_weapon_dmg( weapon, att, vic, damage, hitplace=0 ); +/* Function will pass info about custom weapon shot to stats module */ +native custom_weapon_shot( weapon,index ); // weapon id , player id + +/* function will return 1 if true */ +native xmod_is_melee_wpn(wpnindex); + +/* Returns weapon name. */ +native xmod_get_wpnname(wpnindex,name[],len); + +/* Returns weapon logname. */ +native xmod_get_wpnlogname(wpnindex,name[],len); + +/* Returns weapons array size */ +native xmod_get_maxweapons(); + +/* Returns stats array size ex. 8 in TS , 9 in DoD */ +native xmod_get_stats_size(); + +/* Returns 1 if true */ +native xmod_is_custom_wpn(wpnindex); + +/************* Shared Natives End ********************************/ + +/* Spawns a Weapon */ +stock ts_weaponspawn(const weaponid[], const duration[], const extraclip[], const spawnflags[], const Float:Origin[3]) +{ + new ent = create_entity("ts_groundweapon"); + + DispatchKeyValue(ent, "tsweaponid", weaponid); + DispatchKeyValue(ent, "wduration", duration); + DispatchKeyValue(ent, "wextraclip", extraclip); + DispatchKeyValue(ent, "spawnflags", spawnflags); + DispatchSpawn(ent); + + entity_set_origin(ent, Origin); + return PLUGIN_HANDLED; +} diff --git a/amxmodx/scripting/include/uq_jumpstats_sql.inc b/amxmodx/scripting/include/uq_jumpstats_sql.inc new file mode 100644 index 0000000..72dc2a0 --- /dev/null +++ b/amxmodx/scripting/include/uq_jumpstats_sql.inc @@ -0,0 +1,306 @@ +#define TASK_CHECK_SQL_PLAYER 13378 + +public retrying_getinfo(id) { + id = id - 213134; + player_load_info(id); +} +public player_load_info(id) { + if(is_user_bot(id)) + return PLUGIN_HANDLED; + + new Handle:query,error[128],sql_query[128],quoted_name[65]; + + SQL_QuoteString(SqlConnection, quoted_name, 64, g_playername[id]); + + if(strlen(g_playerip[id]) < 1) { + log_amx("STEAM BUG; output: %s; player id: %d", g_playersteam[id], get_user_userid(id)); + get_user_authid(id, g_playersteam[id], 64); + } + + query = SQL_PrepareQuery(SqlConnection, "SELECT `id` FROM kzp_players WHERE auth LIKE '%s'", g_playersteam[id]); + + if(!SQL_Execute(query)) { + SQL_QueryError(query, error, 127); + + new tmp_error; + SqlConnection = SQL_Connect(DB_TUPLE, tmp_error, g_error, 511); + + set_task(2.0, "retrying_getinfo", 213134 + id); + } + else if(!SQL_NumResults(query)) { + new cData[1]; + cData[0] = id; + formatex(sql_query, 511, "INSERT INTO kzp_players(name,ip,auth) VALUES('%s','%s','%s')", quoted_name, g_playerip[id], g_playersteam[id]); + SQL_ThreadQuery(DB_TUPLE, "QueryHandle_newPlayer", sql_query, cData, strlen(cData[0])); + } + else { + new cData[1]; + cData[0] = id; + g_sql_pid[id] = SQL_ReadResult(query, 0); + + format(sql_query, 511, "SELECT type,distance,maxspeed,prestrafe,strafes,sync,ddbh,pspeed,wpn FROM uq_jumps%s WHERE pid=%d", get_pcvar_num(sv_airaccelerate) == 100 ? "_100aa" : "", g_sql_pid[id]); + SQL_ThreadQuery(DB_TUPLE,"QueryHandle_LoadPlayerTops", sql_query, cData, strlen(cData[0])); + format(sql_query, 511, "SELECT type,distance,jumpoff,block,pspeed,wpn FROM uq_block_tops%s WHERE pid=%d", get_pcvar_num(sv_airaccelerate) == 100 ? "_100aa" : "", g_sql_pid[id]); + SQL_ThreadQuery(DB_TUPLE,"QueryHandle_LoadPlayerTopsBlock", sql_query, cData, strlen(cData[0])); + + format(sql_query, 511, "UPDATE kzp_players SET name='%s',ip='%s',auth='%s' WHERE `id`=%d", quoted_name, g_playerip[id], g_playersteam[id], g_sql_pid[id]); + + SQL_ThreadQuery(DB_TUPLE, "QueryHandle", sql_query); + } + + return PLUGIN_CONTINUE; +} + +public QueryHandle_LoadPlayerTops(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime) { + if(iFailState != TQUERY_SUCCESS) { + log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError); + return PLUGIN_HANDLED; + } + + new type[64], distance, maxspeed, prestrafe, strafes, sync, ddbh, tmp_str[12], pspeed, wpn[33]; + + while(SQL_MoreResults(hQuery)) { + SQL_ReadResult(hQuery,0,type,64); + distance = SQL_ReadResult(hQuery,1); + maxspeed = SQL_ReadResult(hQuery,2); + prestrafe = SQL_ReadResult(hQuery,3); + strafes = SQL_ReadResult(hQuery,4); + sync = SQL_ReadResult(hQuery,5); + ddbh = SQL_ReadResult(hQuery,6); + pspeed = SQL_ReadResult(hQuery,7); + SQL_ReadResult(hQuery,8,wpn,32); + + new Trie:JumpStat; + JumpStat = TrieCreate(); + + TrieSetString(JumpStat, "type", type); + TrieSetCell(JumpStat, "distance", distance); + TrieSetCell(JumpStat, "maxspeed", maxspeed); + TrieSetCell(JumpStat, "prestrafe", prestrafe); + TrieSetCell(JumpStat, "strafes", strafes); + TrieSetCell(JumpStat, "sync", sync); + TrieSetCell(JumpStat, "ddbh", ddbh); + TrieSetCell(JumpStat, "pspeed", pspeed); + TrieSetString(JumpStat, "wpn", wpn); + + num_to_str(g_sql_pid[cData[0]],tmp_str,11); + + format(type, 64, "%s_%s_%d", tmp_str, type, pspeed); + TrieSetCell(JumpPlayers, type, JumpStat); + + SQL_NextRow(hQuery); + } + + SQL_FreeHandle(hQuery); + return PLUGIN_CONTINUE; +} + +public QueryHandle_LoadPlayerTopsBlock(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime) { + if(iFailState != TQUERY_SUCCESS) { + log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError); + return PLUGIN_HANDLED; + } + + new type[65],distance,jumpoff,block,tmp_str[12],pspeed,wpn[33]; + + while(SQL_MoreResults(hQuery)) { + SQL_ReadResult(hQuery,0,type,64); + distance = SQL_ReadResult(hQuery,1); + jumpoff = SQL_ReadResult(hQuery,2); + block = SQL_ReadResult(hQuery,3); + pspeed = SQL_ReadResult(hQuery,4); + SQL_ReadResult(hQuery,5,wpn,32); + + new Trie:JumpStat; + JumpStat = TrieCreate(); + + TrieSetString(JumpStat, "type", type); + TrieSetCell(JumpStat, "distance", distance); + TrieSetCell(JumpStat, "jumpoff", jumpoff); + TrieSetCell(JumpStat, "block", block); + TrieSetCell(JumpStat, "pspeed", pspeed); + TrieSetString(JumpStat, "wpn", wpn); + + num_to_str(g_sql_pid[cData[0]],tmp_str,11); + format(type, 64, "block_%s_%s_%d", tmp_str, type, pspeed); + + TrieSetCell(JumpPlayers, type, JumpStat); + + SQL_NextRow(hQuery); + } + + SQL_FreeHandle(hQuery); + return PLUGIN_CONTINUE; +} + +public QueryHandle_newPlayer(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime) { + if(iFailState != TQUERY_SUCCESS) { + log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError); + return PLUGIN_HANDLED; + } + + new task_data[2]; + task_data[0] = SQL_GetInsertId(hQuery); + task_data[1] = cData[0]; + + set_task(1.0, "sql_check_reg", TASK_CHECK_SQL_PLAYER + cData[0], task_data, 2); + + SQL_FreeHandle(hQuery); + return PLUGIN_CONTINUE; +} + +public sql_check_reg(args[]) { + new id = args[1]; + new inserted_id = args[0]; + + if(0 > id || id > get_maxplayers()) { + log_amx("Invalid id (%d) in sql_check_reg()", id); + return PLUGIN_HANDLED; + } + else { + if(inserted_id > 0) { + new tmp_str[12]; + new Trie:JumpData; + JumpData = TrieCreate(); + + g_sql_pid[id] = inserted_id; + num_to_str(inserted_id, tmp_str, 11); + TrieSetCell(JumpPlayers, tmp_str, JumpData); + } + else { + log_amx("Bug? %s sql_id is %d; Retrying.", g_playername[id], inserted_id); + player_load_info(id); + } + } + + return PLUGIN_HANDLED; +} + +public PlayerSaveData_to_SQL(id, cData[]) { + new jt_str[65], Trie:JS, tmp_str[12], distance, query[512], wpn[33], type[33]; + num_to_str(g_sql_pid[id], tmp_str, 11); + + if(cData[8]) { + get_weaponname(cData[8], wpn, 32); + replace(wpn, 32, "weapon_", ""); + } + else + formatex(wpn, 32, "Unknow"); + + formatex(type,32,"%s",Type_List[cData[6]]); + formatex(jt_str,64,"%s_%s_%d",tmp_str,Type_List[cData[6]],cData[7]); + + if(TrieKeyExists(JumpPlayers, jt_str)) { // player is in trie + TrieGetCell(JumpPlayers, jt_str, JS); + + if(TrieKeyExists(JS, "distance")) { // get distance + TrieGetCell(JS, "distance", distance); + + if(distance < cData[0]) { // jumpdist > old jumpdist, updating + formatex(query, 511, "UPDATE uq_jumps%s SET distance=%d,maxspeed=%d,prestrafe=%d,strafes=%d,sync=%d,ddbh=%d,pspeed=%d,wpn='%s' WHERE pid=%d AND type LIKE '%s' AND pspeed=%d", get_pcvar_num(sv_airaccelerate) == 100 ? "_100aa" : "", cData[0], cData[1], cData[2], cData[3], cData[4], cData[5], cData[7], wpn, g_sql_pid[id], type, cData[7]); + + SQL_ThreadQuery(DB_TUPLE,"QueryHandle", query); + TrieSetString(JS, "type", type); + TrieSetCell(JS, "distance", cData[0]); + TrieSetCell(JS, "maxspeed", cData[1]); + TrieSetCell(JS, "prestrafe", cData[2]); + TrieSetCell(JS, "strafes", cData[3]); + TrieSetCell(JS, "sync", cData[4]); + TrieSetCell(JS, "ddbh", cData[5]); + TrieSetCell(JS, "pspeed", cData[7]); + TrieSetString(JS, "wpn", wpn); + + TrieSetCell(JumpPlayers, jt_str, JS); + } + } + else + log_amx("WTF?!"); + } + else { // new jumptype to player, insert + formatex(query, 511, "INSERT INTO uq_jumps%s(pid,type,distance,maxspeed,prestrafe,strafes,sync,ddbh,pspeed,wpn) VALUES(%d,'%s',%d,%d,%d,%d,%d,%d,%d,'%s')", get_pcvar_num(sv_airaccelerate) == 100 ? "_100aa" : "", g_sql_pid[id], type, cData[0], cData[1], cData[2], cData[3], cData[4], cData[5], cData[7], wpn); + + new Trie:JumpStat; + JumpStat = TrieCreate(); + + SQL_ThreadQuery(DB_TUPLE,"QueryHandle", query); + TrieSetString(JumpStat, "type", type); + TrieSetCell(JumpStat, "distance", cData[0]); + TrieSetCell(JumpStat, "maxspeed", cData[1]); + TrieSetCell(JumpStat, "prestrafe", cData[2]); + TrieSetCell(JumpStat, "strafes", cData[3]); + TrieSetCell(JumpStat, "sync", cData[4]); + TrieSetCell(JumpStat, "ddbh", cData[5]); + TrieSetCell(JumpStat, "pspeed", cData[7]); + TrieSetString(JumpStat, "wpn", wpn); + + TrieSetCell(JumpPlayers, jt_str, JumpStat); + } +} +public PlayerSaveData_to_SQL_block(id, cData[]) { + new block,jt_str[65], Trie:JS, tmp_str[12], distance, query[512], wpn[33], type[33]; + num_to_str(g_sql_pid[id], tmp_str, 11); + + if(cData[5]) { + get_weaponname(cData[5], wpn, 32); + replace(wpn, 32, "weapon_", ""); + } + else + formatex(wpn, 32, "Unknown"); + + if(cData[3] == 6) { + formatex(type, 32, "hj"); + formatex(jt_str, 64, "block_%s_hj_%d", tmp_str, cData[4]); + } + else { + formatex(type, 32, "%s", Type_List[cData[3]]); + formatex(jt_str, 64, "block_%s_%s_%d", tmp_str, Type_List[cData[3]], cData[4]); + } + + if(TrieKeyExists(JumpPlayers, jt_str)) { // player is in trie + TrieGetCell(JumpPlayers, jt_str, JS); + + if(TrieKeyExists(JS, "block")) { // get block + TrieGetCell(JS, "block", block); + + if(block <= cData[2]) { // block >= oldblock + if(TrieKeyExists(JS, "distance")) { // get distance + TrieGetCell(JS, "distance", distance); + + if((distance < cData[0] && block==cData[2]) || (block old jumpdist if block=oldblock or update if block 0) + return 227.0; + else if(height <= 16 && height > 8) + return 225.0; + else if(height <= 24 && height > 16) + return 223.0; + else if(height <= 32 && height > 24) + return 221.0; + else if(height <= 40 && height > 32) + return 219.0; + else if(height <= 48 && height > 40) + return 217.0; + else if(height <= 56 && height > 48) + return 215.0; + else if(height <= 64 && height > 56) + return 213.0; + return 0.0; +} + +stock Float:GetFailedDistance(Float:ExDist, bool:ducking, Float:gravity, Float:jumpoff_origin[3], Float:current_velocity[3], Float:failed_origin[3], Float:failed_velocity[3]) { + static Float:airtime, Float:land_origin[3], Float:distance; + if(ducking) + jumpoff_origin[2] -= 18.0; + + airtime = ((floatsqroot((failed_velocity[2] * failed_velocity[2]) - (2.0 * -gravity * (failed_origin[2] - jumpoff_origin[2])))*-1) - failed_velocity[2] ) / -gravity; + land_origin[0] = floatabs(failed_origin[0] - jumpoff_origin[0]) + floatabs(current_velocity[0] * airtime); + land_origin[1] = floatabs(failed_origin[1] - jumpoff_origin[1]) + floatabs(current_velocity[1] * airtime); + + distance = vector_length(land_origin) + ExDist; + + if(ducking) + jumpoff_origin[2] += 18.0; + + return distance; +} + +stock weapon_rank(maxspeed) { + new rank; + switch(maxspeed) { + case 0: rank = -1; + case 210: rank = 1; + case 220: rank = 2; + case 221: rank = 3; + case 230: rank = 4; + case 235: rank = 5; + case 240: rank = 6; + case 245: rank = 7; + case 250: rank = 0; + } + return rank; +} + +stock weapon_maxspeed(rank) { + new maxspeed; + switch(rank) { + case 0: maxspeed = 250; + case 1: maxspeed = 210; + case 2: maxspeed = 220; + case 3: maxspeed = 221; + case 4: maxspeed = 230; + case 5: maxspeed = 235; + case 6: maxspeed = 240; + case 7: maxspeed = 245; + } + return maxspeed; +} + +stock Float:LandingCalculate(id,Float:landing_orig[3], Float:jumpoff_origin[3]) { + new Float:tmplandorg[3],Float:tmplandorigin[3]; + for(new i=0,ii=-18;i<3;i++,ii=ii+18) { + if(floatabs(landing_orig[0]-jumpoff_origin[0])>floatabs(landing_orig[1]-jumpoff_origin[1])) { + tmplandorigin=landing_orig; + tmplandorigin[1]=tmplandorigin[1]+ii; + if(landing_orig[0]-jumpoff_origin[0]>0) { + tmplandorigin[0]=tmplandorigin[0]+16; + tmplandorg[0]=landing_orig[0]-330; + tmplandorg[1]=landing_orig[1]+ii; + tmplandorg[2]=landing_orig[2]; + } + else if(landing_orig[0]-jumpoff_origin[0]<0) { + tmplandorigin[0]=tmplandorigin[0]-16; + tmplandorg[0]=landing_orig[0]+330; + tmplandorg[1]=landing_orig[1]+ii; + tmplandorg[2]=landing_orig[2]; + } + } + else if(floatabs(landing_orig[0]-jumpoff_origin[0])0) { + tmplandorigin[1]=tmplandorigin[1]+16; + tmplandorg[0]=landing_orig[0]+ii; + tmplandorg[1]=landing_orig[1]-330; + tmplandorg[2]=landing_orig[2]; + } + else if(landing_orig[1]-jumpoff_origin[1]<0) { + tmplandorigin[1]=tmplandorigin[1]-16; + tmplandorg[0]=landing_orig[0]+ii; + tmplandorg[1]=landing_orig[1]+330; + tmplandorg[2]=landing_orig[2]; + } + } + new Float:Orgland[3],Float:startOrgland[3]; + + engfunc(EngFunc_TraceLine,tmplandorigin, tmplandorg, IGNORE_GLASS | IGNORE_MONSTERS, id, 0); + get_tr2(0, TR_vecEndPos, Orgland); + + engfunc(EngFunc_TraceLine,Orgland, tmplandorigin, IGNORE_GLASS | IGNORE_MONSTERS, id, 0); + get_tr2(0, TR_vecEndPos, startOrgland); + + if(get_distance_f(tmplandorigin,startOrgland)!=0.0) + return get_distance_f(tmplandorigin,startOrgland); + } + return 0.0; +} + +stock kz_get_configsfile(name[], len) { + new lalin[64]; + get_localinfo("amxx_configsdir", lalin,63); + return formatex(name, len, "%s/uqjumpstats.cfg", lalin); +} diff --git a/amxmodx/scripting/include/vault.inc b/amxmodx/scripting/include/vault.inc new file mode 100644 index 0000000..9982dfb --- /dev/null +++ b/amxmodx/scripting/include/vault.inc @@ -0,0 +1,60 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Vault Functions +// + +#if defined _vault_included + #endinput +#endif +#define _vault_included + + /** + * Reads data from a given key. + * + * + * @param key Key to get the value from + * @param data Buffer to copy the value to + * @param len Buffer size. If len is set to 0 then the function will + * return the value as a number + * + * @return If len is not 0 the function will return the number of characters written. + If len is 0 the function will return the numerical value associated with the key. + */ +native get_vaultdata(const key[], data[] = "", len = 0); + + +/** + * Sets data for a given key. + * + * @param key Key to set the value for + * @param data Data to set for the given key + * + * @noreturn + */ +native set_vaultdata(const key[], const data[] = ""); + +/** + * Removes a key and its data from the vault. + * + * @param key Key to remove + * + * @noreturn + */ +native remove_vaultdata(const key[]); + +/** + * Checks if a key exists in the vault. + * + * @param key Key to check + * + * @return 1 if an entry was found, 0 otherwise. + */ +native vaultdata_exists(const key[]); diff --git a/amxmodx/scripting/include/vector.inc b/amxmodx/scripting/include/vector.inc new file mode 100644 index 0000000..ee76429 --- /dev/null +++ b/amxmodx/scripting/include/vector.inc @@ -0,0 +1,131 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Vector Functions +// + +#if defined _corevector_included + #endinput +#endif +#define _corevector_included + +/** + * Used for angle_vector() + */ +#define ANGLEVECTOR_FORWARD 1 +#define ANGLEVECTOR_RIGHT 2 +#define ANGLEVECTOR_UP 3 + +/** + * Calculates the distance between two input vectors. + * + * @param origin1 The first vector + * @param origin2 The second vector + * + * @return The distance between two input vectors + */ +native get_distance(const origin1[3], const origin2[3]); + +/** + * Calculates the distance between two input float vectors. + * + * @param origin1 The first vector + * @param origin2 The second vector + * + * @return The distance between two input vectors + */ +native Float:get_distance_f(const Float:Origin1[3], const Float:Origin2[3]); + +/** + * Calculates velocity in the direction player is looking. + * + * @param iIndex Client index + * @param iVelocity Multiply vRetValue length by this much + * @param vRetValue Store the calculated velocity in this vector. + * + * @noreturn + * @error If client is not connected or client index is not + * within the range of 1 to MaxClients. + */ +native velocity_by_aim(iIndex, iVelocity, Float:vRetValue[3]); + +/** + * Changes a vector into an angle vector. + * + * @param fVector Input vector + * @param vReturn Output angle vector + * + * @noreturn + */ +native vector_to_angle(const Float:fVector[3], Float:vReturn[3]); + +/** + * Changes an angle vector into a vector. + * + * @param vector Input angle vector + * @param FRU One of the ANGLEVECTOR_* constants + * @param ret Output vector + * + * @noreturn + */ +native angle_vector(const Float:vector[3], FRU, Float:ret[3]); + +/** + * Calculates the length of a vector. + * + * @param vVector Input vector + * + * @return Length of the input vector + */ +native Float:vector_length(const Float:vVector[3]); + +/** + * Calculates the distance between two vectors. + * + * @param vVector The first vector + * @param vVector2 The second vector + * + * @return Distance between two input vectors + */ +native Float:vector_distance(const Float:vVector[3], const Float:vVector2[3]); + +/** + * Converts an integer vector to a floating point vector. + * + * @param IVec Input integer vector + * @param FVec Output float vector + * + * @noreturn + */ +stock IVecFVec(const IVec[3], Float:FVec[3]) +{ + FVec[0] = float(IVec[0]); + FVec[1] = float(IVec[1]); + FVec[2] = float(IVec[2]); + + return 1; +} + +/** + * Converts a floating point vector into an integer vector. + * + * @param FVec Input float vector + * @param IVec Output integer vector + * + * @noreturn + */ +stock FVecIVec(const Float:FVec[3], IVec[3]) +{ + IVec[0] = floatround(FVec[0]); + IVec[1] = floatround(FVec[1]); + IVec[2] = floatround(FVec[2]); + + return 1; +} diff --git a/amxmodx/scripting/include/xs.inc b/amxmodx/scripting/include/xs.inc new file mode 100644 index 0000000..2d85f72 --- /dev/null +++ b/amxmodx/scripting/include/xs.inc @@ -0,0 +1,1570 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// Copyright (C) 2004 Pavol "PM" Marko +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +/** + * XS Library + * Version 0.1 + * + * MACROS THAT YOU CAN DEFINE BEFORE INCLUDING XS.INC: + * XS_FLEQ_TOLERANCE: + * Tolerance that is used for XS_FLEQ float nearly-equal comparisions + * DEFAULT: 0.000005 + * XS_DEBUG + * Turn debug logging on + * DEFAULT: 0 + * XS_LOGBUFFER_SIZE + * Buffer size for logging + * DEFAULT: 512 + * XS_TASK_MAXPARAMS + * Maximal parameter count for managed tasks + * DEFAULT: 8 + * XS_TASK_MAXPARAMSIZE + * Maximal size of string parameter for tasks + * Has to be power of 2 and has to be >= 8 + * DEFAULT: 512 + * XS_TASK_MANAGEDIDS + * Number of managed IDs for tasks. + * DEFAULT: 2048 + * XS_REPLACEBUF_SIZE + * DEFAULT: 3072 + * + * NOTES: + * On AMX, VexdUM is required for some math functions + * xs__ / XS__ (2 underscores) stuff is meant to be intern + * untested: never tested + * half-tested: succesfully used in other applications; not extensively tested in xs though + * tested: fully tested + * If you have any useful functions / ideas for functions, please tell me. +*/ + +#if defined _xs_included + #endinput +#endif +#define _xs_included + +// **** CONFIG CHECK + +#if !defined XS_FLEQ_TOLERANCE + #define XS_FLEQ_TOLERANCE 0.000005 +#endif + +#if !defined XS_DEBUG + #define XS_DEBUG 0 +#endif + +#if !defined XS_LOGBUFFER_SIZE + #define XS_LOGBUFFER_SIZE 512 +#endif + +#if !defined XS_TASK_MAXPARAMS + #define XS_TASK_MAXPARAMS 8 +#endif + +#if !defined XS_TASK_MAXPARAMSIZE + #define XS_TASK_MAXPARAMSIZE 512 +#endif + +#if !defined XS_TASK_MANAGEDIDS + #define XS_TASK_MANAGEDIDS 2048 +#endif + +#if !defined XS_REPLACEBUF_SIZE + #define XS_REPLACEBUF_SIZE 3072 +#endif + + +/****** DEBUGGING / LOGING FUNCTIONS ******/ +enum xs_logtypes +{ + xs_debug, + xs_message, + xs_warning, + xs_error, + xs_fatalerror, + xs__assertionfailed, + + // must come last + xs_logtypes_count +} + +stock const xs__logtypenames[xs_logtypes_count][] = {"DEBUG", "", "WARNING", "ERROR", "FATAL ERROR", "DEBUG ASSERTION FAILED"}; + +// tested +stock xs_log(xs_logtypes:logtype, any:...) +{ + // WARNING: Don't try to use assert in here; it uses this func + + // Don't log debug if not in debug mode + #if !XS_DEBUG + if (logtype == xs_debug) + return; + #endif + + new buffer[XS_LOGBUFFER_SIZE+1]; + buffer[XS_LOGBUFFER_SIZE]=0; + format_args(buffer, XS_LOGBUFFER_SIZE, 1 /* go from SECOND argument*/); + new bool:addLogTypeName = strlen(xs__logtypenames[logtype]) ? true : false; + + // Use AMXX's logging system + log_amx("%s%s%s", addLogTypeName ? xs__logtypenames[logtype] : "", + addLogTypeName ? ": " : "", buffer); +} + +// Assertion +// tested +stock xs_assertfunc(any:exp, const desc[]) +{ + // Check exp + if (exp) + return 1; // ok + + // not ok + + // print info + xs_log(xs__assertionfailed, "%s", desc); + + return 0; +} +#define xs_assert(%1,%2) if (!xs_assertfunc(%1,%2)) xs__global_null /= xs__global_null + + +// Assertion; only in debug mode +// untested; logical flow says it should work +#if XS_DEBUG + #define xs_assert_dbg(%1,%2) if (!xs_assertfunc(%1,%2)) xs__global_null /= xs__global_null +#else + #define xs_assert_dbg(%1,%2) +#endif + +new xs__global_null = 0; + +/****** MATH FUNCTIONS ******/ + +/****** BASIC STUFF ******/ + +/** + * Gets the sign of a value. + * + * @param num Number to get the sign from. + * + * @return -1 if the number is negative, + * 0 if the number is equal to 0, + * 1 if the number is positive. + */ +stock xs_sign(num) +{ + return (num < 0) ? -1 : ((num == 0) ? 0 : 1); +} + +/** + * Gets the sign of a float value. + * + * @param num Number to get the sign from. + * + * @return -1 if the number is negative, + * 0 if the number is equal to 0, + * 1 if the number is positive. + */ +stock xs_fsign(Float:num) +{ + return (num < 0.0) ? -1 : ((num == 0.0) ? 0 : 1); +} + +/** + * Gets the absolute value of a number. + * + * @param num Number to get the absolute value from. + * + * @return Absolute value of the input number. + */ +stock xs_abs(num) +{ + return (num < 0) ? -num : num; +} + +/** + * Checks if the number is a power of 2. + * + * @param x Number to check. + * + * @return 1 if it is a power of 2, 0 otherwise. + */ +stock xs_is_2power(x) +{ + return (x!=0) && ((x&(x-1))==0); +} + +/** + * Converts degrees to radians. + * + * @param x Input degrees. + * + * @return Degrees converted to radians. + */ +stock Float:xs_deg2rad(Float:x) +{ + return x * 0.017453292519943; +} + +/** + * Converts radians to degrees. + * + * @param x Input radians. + * + * @return Radians converted to degrees. + */ +stock Float:xs_rad2deg(Float:x) +{ + return x * 57.29577951308232; +} + +/** + * Converts gradians to radians. + * + * @param x Input gradians. + * + * @return Gradians converted to radians. + */ +stock Float:xs_gra2rad(Float:x) +{ + return x * 0.015707963267948; +} + +/** + * Converts radians to gradians. + * + * @param x Input radians. + * + * @return Radians converted to gradians. + */ +stock Float:xs_rad2gra(Float:x) +{ + return x * 63.66197723675813; +} + +/** + * Checks if two floating point values are nearly equal. + * + * @param %1 The first value to compare. + * @param %2 The second value to compare. + * + * @return 1 if they are nearly equal, 0 otherwise. + */ +#define XS_FLEQ(%1,%2) (((%1) <= ((%2) + XS_FLEQ_TOLERANCE)) && ((%1) >= ((%2) - XS_FLEQ_TOLERANCE))) + +/** + * Calculates the reciprocal of the square root of the input value. + * + * @param x The input value. + * + * @return The reciprocal of the square root of the input value. + */ +stock Float:xs_rsqrt(Float:x) +{ + return 1.0 / floatsqroot(x); +} + +/** + * Calculates the square root of the input value. + * + * @note This is an alias for floatsqroot(). + * + * @param x The input value. + * + * @return The square root of the input value. + */ +stock Float:xs_sqrt(Float:x) +{ + return floatsqroot(x); +} + +// These functions generate errors if you use the macros with wrong parameter count. +stock Float:xs_fabs(Float:pa) +{ + #pragma unused pa + new rawr = you_need_one_param_for_fabs; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} +stock Float:xs_asin(Float:pa,Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_asin; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} +stock Float:xs_sin(Float:pa,Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_sin; + #pragma unused rawr +} +stock Float:xs_acos(Float:pa,Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_acos; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} +stock Float:xs_cos(Float:pa,Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_cos; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} +stock Float:xs_atan(Float:pa,Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_atan; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} +stock Float:xs_atan2(Float:pa,Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_atan2; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} +stock Float:xs_tan(Float:pa, Float:pb) +{ + #pragma unused pa,pb + new rawr = you_need_two_params_for_tan; + rawr = warning_below_shows_line_number; + #pragma unused rawr +} + +#define xs_fabs(%1) floatabs(%1) +#define xs_asin(%1,%2) floatasin(%1, %2) +#define xs_sin(%1,%2) floatsin(%1, %2) +#define xs_acos(%1,%2) floatacos(%1, %2) +#define xs_cos(%1,%2) floatcos(%1, %2) +#define xs_atan(%1,%2) floatatan(%1, %2) +#define xs_atan2(%1,%2) floatatan2(%1, %2) +#define xs_tan(%1,%2) floattan(%1, %2) + +/****** RANDOM NUMBERS ******/ +// This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley +// (ISBN 0-201-47960-5). This is a "multiplicative congruential random number +// generator" that has been extended to 31-bits + +stock xs__internalseed=0x546875; + +#define XS__IL_RMULT 1103515245 + +/** + * Sets the seed for the random number generation. + * + * @param x The seed to set. + * + * @noreturn + */ +stock xs_seed(seed) +{ + xs__internalseed = seed; +} + +/** + * Retrieves a random integer. + * + * @return A random integer. + */ +stock xs_irand() +{ + new lo, hi, ll, lh, hh, hl; + new result; + + lo = xs__internalseed & 0xffff; + hi = xs__internalseed >> 16; + xs__internalseed = xs__internalseed * XS__IL_RMULT + 12345; + ll = lo * (XS__IL_RMULT & 0xffff); + lh = lo * (XS__IL_RMULT >> 16 ); + hl = hi * (XS__IL_RMULT & 0xffff); + hh = hi * (XS__IL_RMULT >> 16 ); + result = xs_abs(((ll + 12345) >> 16) + lh + hl + (hh << 16)); + return result; +} + +/** + * Retrieves a random float. + * + * @return A random float. + */ +stock Float:xs_frand() +{ + return float(xs_irand()) / float(xs_get_maxnum()); // -1/2 should be the biggest possible positive number +} + +/** + * Retrieves a random integer between the specified values. + * + * @note @pmax has to be greater than @pmin! + * + * @param pmin The minimum value. + * @param pmax The maximum value. + * + * @return A random integer. + */ +stock xs_irand_range(pmin, pmax) +{ + xs_assert_dbg(pmax - pmin >= 0, "xs_irand_range: pmin > pmax"); + new i = pmin + floatround(xs_frand() * float(pmax - pmin)); + if (i > pmax) + i = pmax; + return i; +} + +/****** VECTORS & PLANES ******/ + +// *** vectors + +/** + * Sets vector's components to specified values. + * + * @param vec The vector to set values to. + * @param x The X component to be set. + * @param y The Y component to be set. + * @param z The Z component to be set. + * + * @noreturn + */ +stock xs_vec_set(Float:vec[], Float:x, Float:y, Float:z) +{ + vec[0] = x; + vec[1] = y; + vec[2] = z; +} + +/** + * Adds two vectors. + * + * @param in1 The first vector to add. + * @param in2 The second vector to add. + * @param out The output vector. Can be one of the input vectors. + * + * @noreturn + */ +stock xs_vec_add(const Float:in1[], const Float:in2[], Float:out[]) +{ + out[0] = in1[0] + in2[0]; + out[1] = in1[1] + in2[1]; + out[2] = in1[2] + in2[2]; +} + +/** + * Subtracts one vector from another one. + * + * @param in1 Vector to subtract from. + * @param in2 Vector to subtract from the first one. + * @param out The output vector. Can be one of the input vectors. + * + * @noreturn + */ +stock xs_vec_sub(const Float:in1[], const Float:in2[], Float:out[]) +{ + out[0] = in1[0] - in2[0]; + out[1] = in1[1] - in2[1]; + out[2] = in1[2] - in2[2]; +} + +/** + * Adds the second vector scaled by a scalar to the first. + * + * @param in1 Vector to add to. + * @param in2 Vector to scale and add. + * @param scalar Scalar to scale the second vector with. + * @param out The output vector. Can be one of the input vectors. + * + * @noreturn + */ +stock xs_vec_add_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) +{ + out[0] = in1[0] + in2[0] * scalar; + out[1] = in1[1] + in2[1] * scalar; + out[2] = in1[2] + in2[2] * scalar; +} + +/** + * Subtracts the second vector scaled by a scalar from the first one. + * + * @param in1 Vector to subtract from. + * @param in2 Vector to scale and subtract. + * @param scalar Scalar to scale the second vector with. + * @param out The output vector. Can be one of the input vectors. + * + * @noreturn + */ +stock xs_vec_sub_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) +{ + out[0] = in1[0] - in2[0] * scalar; + out[1] = in1[1] - in2[1] * scalar; + out[2] = in1[2] - in2[2] * scalar; +} + +/** + * Checks if two vectors are equal. + * + * @note If you need to check if two vectors are nearly equal, + * take a look at xs_vec_nearlyequal(). + * + * @param vec1 The first input vector to check. + * @param vec2 The second input vector to check. + * + * @return 1 if vectors are equal, 0 otherwise. + */ +stock bool:xs_vec_equal(const Float:vec1[], const Float:vec2[]) +{ + return (vec1[0] == vec2[0]) && (vec1[1] == vec2[1]) && (vec1[2] == vec2[2]); +} + +/** + * Checks if two vectors are nearly equal. + * + * @note If you need to check if two vectors are exactly equal, + * take a look at xs_vec_equal(). + * + * @param vec1 The first input vector to check. + * @param vec2 The second input vector to check. + * + * @return 1 if vectors are equal, 0 otherwise. + */ +stock bool:xs_vec_nearlyequal(const Float:vec1[], const Float:vec2[]) +{ + return XS_FLEQ(vec1[0], vec2[0]) && XS_FLEQ(vec1[1], vec2[1]) && XS_FLEQ(vec1[2], vec2[2]); +} + +/** + * Multiply a vector by a scalar value. + * + * @param vec The vector to be multiplied. + * @param scalar The scalar value to multiply the vector with. + * @param out The output vector. Can be the same as the input vector. + * + * @noreturn + */ +stock xs_vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[]) +{ + out[0] = vec[0] * scalar; + out[1] = vec[1] * scalar; + out[2] = vec[2] * scalar; +} + +/** + * Divide a vector by a scalar value. + * + * @param vec The vector to be divided. + * @param scalar The scalar value to divide the vector with. + * @param out The output vector. Can be the same as the input vector. + * + * @noreturn + */ +stock xs_vec_div_scalar(const Float:vec[], Float:scalar, Float:out[]) +{ + new Float:__tmp = 1.0 / scalar; + out[0] = vec[0] * __tmp; + out[1] = vec[1] * __tmp; + out[2] = vec[2] * __tmp; +} + +/** + * Computes the length of a vector. + * + * @param vec The vector to compute the length of. + * + * @return The length of the input vector. + */ +stock Float:xs_vec_len(const Float:vec[]) +{ + return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); +} + +/** + * Computes the length of a 2D vector. + * + * @param vec The vector to compute the length of. + * + * @return The length of the input vector. + */ +stock Float:xs_vec_len_2d(const Float:vec[]) +{ + return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1]); +} + +/** + * Computes the distance between two vectors (points). + * + * @param vec1 First vector. + * @param vec2 Second vector. + * + * @return The distance between two vectors. + */ +stock Float:xs_vec_distance(const Float:vec1[], const Float:vec2[]) +{ + return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) + + (vec1[2]-vec2[2]) * (vec1[2]-vec2[2])); +} + +/** + * Computes the distance between two 2D vectors (points). + * + * @param vec1 First vector. + * @param vec2 Second vector. + * + * @return The distance between two vectors. + */ +stock Float:xs_vec_distance_2d(const Float:vec1[], const Float:vec2[]) +{ + return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1])); +} + +/** + * Computes the square of the distance between two vectors (points). + * This is faster than the distance. + * + * @param vec1 First vector. + * @param vec2 Second vector. + * + * @return The square of the distance between two vectors. + */ +stock Float:xs_vec_sqdistance(const Float:vec1[], const Float:vec2[]) +{ + return (vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) + + (vec1[2]-vec2[2]) * (vec1[2]-vec2[2]); +} + +/** + * Computes the square of the distance between two 2D vectors (points). + * This is faster than the distance. + * + * @param vec1 First vector. + * @param vec2 Second vector. + * + * @return The square of the distance between two vectors. + */ +stock Float:xs_vec_sqdistance_2d(const Float:vec1[], const Float:vec2[]) +{ + return (vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]); +} + +/** + * Normalizes a vector. Normalized vector is a vector with the length of 1 unit, + * but with the same direction as the original vector. + * + * @param vec The vector to be normalized. + * @param out The output vector. Can be the same as the input vector. + * + * @noreturn + */ +stock xs_vec_normalize(const Float:vec[], Float:out[]) +{ + new Float:invlen = xs_rsqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); + out[0] = vec[0] * invlen; + out[1] = vec[1] * invlen; + out[2] = vec[2] * invlen; +} + +/** + * Computes the cross product of two vectors. + * + * @param vec1 The first vector operand of the cross operation. + * @param vec2 The second vector operand of the cross operation. + * @param out The output vector. *Can't* be one of the input vectors. + * + * @noreturn + */ +stock xs_vec_cross(const Float:vec1[], const Float:vec2[], Float:out[]) +{ + out[0] = vec1[1]*vec2[2] - vec1[2]*vec2[1]; + out[1] = vec1[2]*vec2[0] - vec1[0]*vec2[2]; + out[2] = vec1[0]*vec2[1] - vec1[1]*vec2[0]; +} + +/** + * Computes the dot product of two vectors. + * + * @param vec1 The first vector operand of the dot operation. + * @param vec2 The second vector operand of the dot operation. + * + * @return The dot product of two input vectors. + */ +stock Float:xs_vec_dot(const Float:vec1[], const Float:vec2[]) +{ + return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]; +} + +/** + * Negates a vector. + * + * @param vec The vector to negate. + * @param out The output vector. Can be the same as the input vector. + * + * @noreturn + */ +stock xs_vec_neg(const Float:vec[], Float:out[]) +{ + out[0] = -vec[0]; + out[1] = -vec[1]; + out[2] = -vec[2]; +} + +/** + * Copies a vector into another one. + * + * @param vecIn The vector to copy. + * @param vecOut The output vector where to copy the input vector. + * + * @noreturn + */ +stock xs_vec_copy(const Float:vecIn[], Float:vecOut[]) +{ + vecOut[0] = vecIn[0]; + vecOut[1] = vecIn[1]; + vecOut[2] = vecIn[2]; +} + +/** + * Computes the angle between two vectors. + * + * @param vec1 The first vector. + * @param vec2 The second vector. + * + * @return The angle between two input vectors in degrees. + */ +stock Float:xs_vec_angle(const Float:vec1[], const Float:vec2[]) +{ + return xs_rad2deg(xs_acos(xs_vec_dot(vec1, vec2), radian)); +} + +/** + * Reflects a vector about a normal. + * + * @param vec The vector to be reflected. + * @param normal The normal vector about which to reflect. + * @param out The output reflected vector. + * + * @noreturn + */ +stock xs_vec_reflect(const Float:vec[], const Float:normal[], Float:out[]) +{ + // normalize(vec) - (normal * 2.0 * (tmp . normal)) * length(vec) + + new Float:tmp1[3]; + xs_vec_normalize(vec, tmp1); + + // tmp1 - (normal * 2.0 * (tmp . normal)) * length(vec) + + new Float:tmp2[3]; + xs_vec_mul_scalar(normal, 2.0, tmp2); + xs_vec_mul_scalar(tmp2, xs_vec_dot(tmp1, normal), tmp2); + + // tmp1 - tmp2 * length(vec) + xs_vec_mul_scalar(tmp2, xs_vec_len(vec), tmp2); + + // tmp1 - tmp2 + xs_vec_sub(tmp1, tmp2, out); +} + +/** + * Turns a 3D vector into a 2D vector. + * + * @note This function just ignores the Z (3rd) component of a 3D vector. + * + * @param vec A 3D vector to turn into a 2D vector. + * @param out The output 2D vector. + * + * @noreturn + */ +stock xs_vec_make2d(const Float:vec[3], Float:out[2]) +{ + out[0] = vec[0]; + out[1] = vec[1]; +} + +// *** planes + +// normal +#define XS_PLANE_A 0 +#define XS_PLANE_B 1 +#define XS_PLANE_C 2 +// plane shift distance +#define XS_PLANE_D 3 + + +/** + * Sets a plane to the specified values. + * + * @param plane The plane to set the values to. It's a 4D vector. + * @param a The first component of a plane to be set. + * @param b The second component of a plane to be set. + * @param c The third component of a plane to be set. + * @param d The fouth component of a plane to be set. + * + * @noreturn + */ +stock xs_plane_set(Float:plane[], Float:a, Float:b, Float:c, Float:d) +{ + plane[XS_PLANE_A] = a; + plane[XS_PLANE_B] = b; + plane[XS_PLANE_C] = c; + plane[XS_PLANE_D] = d; +} + +/** + * Constructs a plane out of 4 points in space. + * + * @param plane The output plane to store the newly created plane. + * @param p1 The first point of a plane. + * @param p2 The second point of a plane. + * @param p3 The third point of a plane. + * + * @noreturn + */ +stock xs_plane_3p(Float:plane[], const Float:p1[], const Float:p2[], const Float:p3[]) +{ + new Float:normalA[3], Float:normalB[3]; + + // normalA = Normalize(p3 - p1); + normalA[0] = p3[0] - p1[0]; + normalA[1] = p3[1] - p1[1]; + normalA[2] = p3[2] - p1[2]; + xs_vec_normalize(normalA, normalA); + + // normalB = Normalize(p3 - p2); + normalB[0] = p3[0] - p2[0]; + normalB[1] = p3[1] - p2[1]; + normalB[2] = p3[2] - p2[2]; + xs_vec_normalize(normalB, normalB); + + // plane normal = Normalize(normalA cross normalB) + xs_vec_cross(normalA, normalB, plane); + xs_vec_normalize(plane, plane); + + // plane shift distance = (-p1) dot plane normal + new Float:__tmp[3]; + xs_vec_neg(plane, __tmp); + plane[XS_PLANE_D] = xs_vec_dot(__tmp, p1); + +} + +/** + * Checks if two planes are equal. + * + * @note If you have to check if two planes are just nearly equal, + * take a look at xs_plane_nearlyequal(). + * + * @param plane1 The first plane to check. + * @param plane2 The second plane to check. + * + * @return 1 if planes are equal, 0 otherwise. + */ +stock bool:xs_plane_equal(const Float:plane1[], const Float:plane2[]) +{ + if ( (plane1[0] == plane2[0]) && + (plane1[1] == plane2[1]) && + (plane1[2] == plane2[2]) && + (plane1[3] == plane2[3])) + return true; + return false; +} + +/** + * Checks if two planes are nearly equal. + * + * @note If you have to check if two planes are exactly equal, + * take a look at xs_plane_equal(). + * + * @param plane1 The first plane to check. + * @param plane2 The second plane to check. + * + * @return 1 if planes are nearly equal, 0 otherwise. + */ +stock bool:xs_plane_nearlyequal(const Float:plane1[], const Float:plane2[]) +{ + if ( XS_FLEQ(plane1[0], plane2[0]) && + XS_FLEQ(plane1[1], plane2[1]) && + XS_FLEQ(plane1[2], plane2[2]) && + XS_FLEQ(plane1[3], plane2[3])) + return true; + return false; +} + +/** + * Computes the distance between a plane and a point. + * + * @param plane The plane to check the distance from. + * @param point The point to check the distance to. + * + * @return The distance between the input plane and point. + */ +stock Float:xs_plane_dst2point(const Float:plane[], const Float:point[]) +{ + // return normal dot point + D + return xs_vec_dot(plane, point) + plane[XS_PLANE_D]; +} + +/** + * Checks whether a plane intersects with the ray starting at @rayStart and + * going to @rayDir direction. + * If it does intersect, outputs the intersection point in @out. + * + * @param plane The plane to check intersection with. + * @param rayStart The starting point of the ray. + * @param rayDir Direction in which the ray is going. + * @param out The vector to copy the intersection point to, if it exists. + * + * @return true if they intersect, false otherwise. + */ +stock bool:xs_plane_rayintersect(const Float:plane[], const Float:rayStart[], const Float:rayDir[], Float:out[]) +{ + new Float:a = xs_vec_dot(plane, rayDir); + + if (a == 0.0) + return false; // ray is parallel to plane + + // if (distance plane<->(rayStart + rayDir) > distance plane<->rayStart) and both have the same sign, the ray + // goes away from the plane + new Float:rsplusrd[3]; + xs_vec_add(rayStart, rayDir, rsplusrd); + new Float:dst1 = xs_plane_dst2point(plane, rsplusrd); + new Float:dst2 = xs_plane_dst2point(plane, rayStart); + if (xs_fabs(dst1) > xs_fabs(dst2) && xs_fsign(dst1) == xs_fsign(dst2)) + return false; + + + // out = rayStart - rayDir * ((distance plane<->rayStart) / a) + new Float:__tmp[3]; + xs_vec_mul_scalar(rayDir, xs_plane_dst2point(plane, rayStart) / a, __tmp); + // out = rayStart - tmp + xs_vec_sub(rayStart, __tmp, out); + + return true; +} + +/** + * Checks if a point is on a specified plane. + * + * @param plane The plane to check. + * @param point The point to check. + * + * @return true if the point is on the plane, false otherwise. + */ +stock bool:xs_point_onplane(const Float:plane[], const Float:point[]) +{ + return XS_FLEQ(xs_plane_dst2point(plane, point), 0.0); +} + +/** + * Projects a point on the plane. Stores the projected point in @out. + * + * @param plane The plane to project the point onto. + * @param point The point to project onto the plane. + * @param out The vector to copy the projected point into. + * + * @noreturn + */ +stock xs_projpoint_onplane(const Float:plane[], const Float:point[], Float:out[]) +{ + new Float:__tmp[3]; + // out = point - (plane normal * distance point<->plane) + xs_vec_copy(plane, __tmp); + xs_vec_mul_scalar(__tmp, xs_plane_dst2point(plane, point), __tmp); + xs_vec_sub(point, __tmp, out); +} + +/** + * Copies a plane. + * + * @param planeIn The plane to copy. + * @param planeOut The plane to store the copy into. + * + * @noreturn + */ +stock xs_plane_copy(const Float:planeIn[], Float:planeOut[]) +{ + planeOut[0] = planeIn[0]; + planeOut[1] = planeIn[1]; + planeOut[2] = planeIn[2]; + planeOut[3] = planeIn[3]; +} + +/****** HL ENGINE SPECIFIC STUFF ******/ + +// angle indexes +#define XS_PITCH 0 // up / down +#define XS_YAW 1 // left / right +#define XS_ROLL 2 // fall over + +/** + * Computes forward, right and up vectors from given angles. + * + * @param angles Angles to compute vectors from. + * @param fwd The vector to store the forward vector into. + * @param right The vector to store the right vector into. + * @param up The vector to store the up vector into. + * + * @noreturn + */ +stock xs_anglevectors(const Float:angles[3], Float:fwd[3], Float:right[3], Float:up[3]) +{ + // sin (s) and cos (c) for yaw (y), pitch (p) and roll (r) + new Float:sr, Float:sp, Float:sy, Float:cr, Float:cp, Float:cy; + + sy = xs_sin(angles[XS_YAW], degrees); + cy = xs_cos(angles[XS_YAW], degrees); + sp = xs_sin(angles[XS_PITCH], degrees); + cp = xs_cos(angles[XS_PITCH], degrees); + sr = xs_sin(angles[XS_ROLL], degrees); + cr = xs_cos(angles[XS_ROLL], degrees); + + fwd[0] = cp*cy; + fwd[1] = cp*sy; + fwd[2] = -sp; + + right[0] = (-1*sr*sp*cy + -1*cr*-sy); + right[1] = (-1*sr*sp*sy + -1*cr*cy); + right[2] = -1*sr*cp; + + up[0] = (cr*sp*cy + -sr*-sy); + up[1] = (cr*sp*sy + -sr*cy); + up[2] = cr*cp; +} +/****** STRING FUNCS *******/ + +/** + * Finds a character in a string and returns its position in the string. + * + * @param str The string to search in. + * @param chr The character to search for in the string. + * + * @return The character position if found, -1 otherwise. + */ +stock xs_strchr(const str[], chr) +{ + for (new i = 0; str[i] != 0; ++i) + { + if (str[i] == chr) + return i; + } + return -1; +} + +/** + * Remove @charstotrim number of characters from @stringtotrim, + * either from the beginning or the end of the string. + * + * @param stringtotrim The string to be trimmed. + * @param charstostrim The number of characters to trim. + * @param fromleft If set to true, the string will be trimmer from the left. + * If false, it will be trimmed from the right. + * + * @noreturn + */ +stock xs_strtrim(stringtotrim[], charstotrim, bool:fromleft = true) +{ + if (charstotrim <= 0) + return; + + if (fromleft) + { + new maxlen = strlen(stringtotrim); + if (charstotrim > maxlen) + charstotrim = maxlen; + + // In format, input and output regions can overlap + format(stringtotrim, maxlen, "%s", stringtotrim[charstotrim]); + } + else + { + new maxlen = strlen(stringtotrim) - charstotrim; + if (maxlen < 0) + maxlen = 0; + + // In format, input and output regions can overlap + format(stringtotrim, maxlen, "%s", stringtotrim); + } +} + +/** + * Copies characters from @oldmsg to @newmsg, starting at @start and ending + * at @end (includes the end character). + * + * @param oldmsg The string to copy from. + * @param newmsg The string to copy to. + * @param start Starting position of the @oldmsg string to copy from. + * @param end Ending position of the @oldmsg string to copy from. + * @param outlen If positive, specifies the maximum number of characters + * to be copied. Otherwise, the function assumes that + * newmsg is at least @end - @start + 1 characters long. + * + * @noreturn + */ +stock xs_strmid(const oldmsg[], newmsg[], start, end, outlen=-1) +{ + new len = strlen(oldmsg); + + if(start < 0) + start = 0; + + ++end; // Include end + + if(end <= start || end > len) + end = len; + + new j = 0, i = start; + for(; (i < end) && (outlen--);) + newmsg[j++] = oldmsg[i++]; + + newmsg[j] = 0; +} + +/** + * "Explodes" a string, breaking it at the @delimeter character and putting + * each exploded part into the @output array. + * + * @param input The input string to be exploded. + * @param output The output array of string where exploded string will be stored. + * @param delimeter The character to break the string at. + * @param maxelems Maximum amount of elements in @output. + * @param elemsize Maximum size of each string in the @output array. + * + * @return The number of strings successfully exploded. + */ +stock xs_explode(const input[], output[][], delimiter, maxelems, elemsize) +{ + new nIdx = 0; + new nLen = 0; + + new copied = 0; + while(nLen < strlen(input) && nIdx < maxelems) + { + copied = copyc(output[nIdx++], elemsize, input[nLen], delimiter); + if (copied == elemsize) + { + // maybe it got force-stopped because of maxsize + // so check whether we have to skip something + if (input[nLen + copied] != delimiter && input[nLen + copied] != 0) + { + new found = xs_strchr(input[nLen + copied], delimiter); + if (found == -1) + break; + copied += found; + } + } + + nLen += copied + 1; // +1: skip delimiter + } + return nIdx; +} + +/** + * The opposite of xs_explode(). Takes an array of strings and puts them together + * in a single string, delimeted by the @delimeter character. + * + * @param output The string to store the impoded string into. + * @param outsize The size of the output buffer. + * @param delimeter The character to put between imploded strings. + * @param input The array of strings to implode. + * @param elemsnum The number of strings in the input array. + * + * @return The number of characters in the final output buffer. + */ +stock xs_implode(output[], outsize, delimiter, const input[][], elemsnum) +{ + new pos = 0; + new copied; + for (new i = 0; i < elemsnum; ++i) + { + copied = copy(output[pos], outsize - pos, input[i]); + pos += copied; + if (pos >= outsize) + return outsize; + // append delimiter + output[pos] = delimiter; + ++pos; + // last check + if (pos >= outsize) + return outsize; + } + + output[--pos] = 0; // The last char would be delimiter, so skip it. + return pos; +} + + +stock xs__replace_buf[XS_REPLACEBUF_SIZE]; + +/** + * Replaces all occurencies of @what in @text with @with. + * + * @param text The text to search in. + * @param len The maximum size of the @text buffer. + * @param what What to search for. + * @param with What to replace occurencies with. + * + * @return Returns the number of replaced items. + */ +stock xs_replace(text[], len, const what[], const with[]) +{ + new occur = 0; + new i = 0; + new bufPos = 0; + new replaceLen = strlen(with); + new whatLen = strlen(what); + for (; text[i]; ++i) + { + if (text[i] == what[0]) + { + new posInWhat=0; + new j; + for (j = i; j-i < replaceLen && text[j]; ++j, ++posInWhat) + { + if (text[j] != what[posInWhat]) + break; + } + if (whatLen == posInWhat) + { + for (new i2 = 0; i2 < replaceLen && bufPos < XS_REPLACEBUF_SIZE; ++i2) + xs__replace_buf[bufPos++] = with[i2]; + i = j - 1; + ++occur; + if (bufPos >= XS_REPLACEBUF_SIZE) + return occur; + continue; + } + } + if (bufPos >= XS_REPLACEBUF_SIZE) + return occur; + xs__replace_buf[bufPos++] = text[i]; + } + xs__replace_buf[bufPos] = 0; + copy(text, len, xs__replace_buf); + return occur; +} + +/** + * Replaces all occurencies of @what character in @text with @with character. + * + * @param text The text to search in. + * @param len The maximum size of the @text buffer. + * @param what What character to search for. + * @param with What charactear to replace occurencies with. + * + * @return The number of replaced characters. + */ +stock xs_replace_char(text[], len, what, with) +{ + // let the xs_replace function do the work + new arr[4]; + arr[0] = what; + arr[1] = 0; + arr[2] = with; + arr[3] = 0; + + return xs_replace(text, len, arr[0], arr[2]); +} + +/****** MISC FUNCS *******/ + +/** + * Retrieves the name of a command identified by its ID. + * + * @param cid The command ID. + * @param namestr The buffer where to store command's name. + * @param namelen The maximum size of the output buffer. + * + * @noreturn + */ +stock xs_concmd_name(cid, namestr[], namelen) +{ + new dummy1; + new dummy2[1]; + get_concmd(cid, namestr, namelen, dummy1, dummy2, 0, 0); +} + +/** + * Checks whether there are at least @num free visible slots. + * + * @param num The number of slots to check. + * + * @return true if there are at least that many free, false otherwise. + */ +stock bool:xs_freevisibleslots(num) +{ + new maxplayers = get_cvar_num("sv_visiblemaxplayers"); + if (maxplayers <= 0) + maxplayers = MaxClients; + + return (get_playersnum(1) <= maxplayers-num) ? true : false; +} + +stock xs__maxnum = 0; + +/** + * Returns the biggest possible positive number. + * + * @return The biggest possible positive number. + */ +stock xs_get_maxnum() +{ + if (!xs__maxnum) + { + // build it + xs__maxnum = ((1 << (cellbits - 2)) - 1 ) | (1 << (cellbits - 2)); + /* + new bits = get_cellsize() * 8 - 1; + for (new i = 0; i < bits; ++i) + xs__maxnum |= 1 << i; + */ + } + return xs__maxnum; +} + +/** + * Returns the smallest possible negative number. + * + * @return The smallest possible negative number. + */ +stock xs_get_minnum() +{ + return xs_get_maxnum() + 1; +} + + +// *** The following two functions were created by Damaged Soul. + +// Max messages reserved by engine (DO NOT MODIFY) +#define XS__MAX_ENGINE_MESSAGES 63 +// Max possible messages for mod, is 255 really the limit? +#define XS__MAX_POSSIBLE_MESSAGES 255 + +// Returns max number of messages for mod +stock xs_get_maxmessages() +{ + new name[2]; + + for (new i = XS__MAX_ENGINE_MESSAGES + 1; i <= XS__MAX_POSSIBLE_MESSAGES; i++) + if (!get_user_msgname(i, name, 1)) + return i - 1; + + return XS__MAX_POSSIBLE_MESSAGES; +} + +// Returns true if msgid is a valid message +stock bool:xs_is_msg_valid(msgid) +{ + new name[2]; + new retval = get_user_msgname(msgid, name, 1); + + if (msgid < 1 || (msgid > XS__MAX_ENGINE_MESSAGES && !retval)) + return false; + + return true; +} + +/****** MANAGED TASKS ******/ + +// ***** managed task ids +stock xs_find_freetaskid() +{ + for (new i = 1; i <= XS_TASK_MANAGEDIDS; ++i) + { + if (!task_exists(i)) + return i; + } + return -1; +} + +// ***** managed tasks +enum xs_paramtypes +{ + xs_invalid = 0, + xs_int, + xs_float, + xs_string +} + +// new task +stock xs__TaskParam[ 1 + // number of parameters + XS_TASK_MAXPARAMS + // parameter types + (XS_TASK_MAXPARAMSIZE char) * XS_TASK_MAXPARAMS]; // space for len + value + +stock Float:xs__TaskInterval = 0.0; +stock xs__TaskFlags[5]; +stock xs__TaskFunc[48]; +stock xs__TaskId; +stock xs__TaskRepeat; + +#define xs__TaskParamCount xs__TaskParam[0] +#define xs__TaskParamType[%1] xs__TaskParam[1 + %1] + +#define xs__TaskParamValue[%1] xs__TaskParam[1 + XS_TASK_MAXPARAMS + (%1 * (XS_TASK_MAXPARAMSIZE char))] + + +// incoming task +stock xs__ITaskParam[ 1 + // number of parameters + XS_TASK_MAXPARAMS + // parameter types + (XS_TASK_MAXPARAMSIZE char) * XS_TASK_MAXPARAMS]; // space for len + value +stock xs__ITaskId; + +#define xs__ITaskParamCount xs__ITaskParam[0] +#define xs__ITaskParamType[%1] xs__ITaskParam[1 + %1] + +#define xs__ITaskParamValue[%1] xs__ITaskParam[1 + XS_TASK_MAXPARAMS + (%1 * (XS_TASK_MAXPARAMSIZE char))] + +// tested +stock xs_task_begin(Float:interval, const func[], id = 0, const flags[] = "", repeat = 0) +{ + xs_assert(xs__TaskInterval == 0.0, "New xs_task_begin called before xs_task_end"); + + xs__TaskInterval = interval; + if (xs__TaskInterval < 0.1) + xs__TaskInterval = 0.1; + + copy(xs__TaskFunc, 47, func); + xs__TaskId = id; + copy(xs__TaskFlags, 4, flags); + xs__TaskRepeat = repeat; + + xs__TaskParamCount = 0; +} + +// tested +stock xs_task_pushint(value, bool:__isfl=false /*internal use only*/) +{ + xs_assert(xs__TaskInterval, "xs_task_push* called without xs_task_begin"); + if (xs__TaskParamCount >= XS_TASK_MAXPARAMS) + return 0; + + xs__TaskParamType[xs__TaskParamCount] = __isfl ? xs_float : xs_int; + xs__TaskParamValue[xs__TaskParamCount] = value; + + ++xs__TaskParamCount; + return 1; +} + +// tested +stock xs_task_pushfl(Float:value) +{ + return xs_task_pushint(_:value, true); +} + +// tested +stock xs_task_pushstr(const value[]) +{ + xs_assert(xs__TaskInterval, "xs_task_push* called without xs_task_begin"); + if (xs__TaskParamCount >= XS_TASK_MAXPARAMS) + return 0; + + xs__TaskParamType[xs__TaskParamCount] = xs_string; + strpack(xs__TaskParamValue[xs__TaskParamCount], value); + ++xs__TaskParamCount; + return 1; +} + +// tested +stock xs_task_end() +{ + xs_assert(xs__TaskInterval, "xs_task_end called without xs_task_begin"); + + // find a task id if needed + if (xs__TaskId == -1) + { + xs__TaskId = xs_find_freetaskid(); + if (xs__TaskId == -1) + { + // not found + xs__TaskInterval = 0.0; + return -1; + } + } + + set_task(xs__TaskInterval, xs__TaskFunc, xs__TaskId, xs__TaskParam, + 1 + xs__TaskParamCount * (XS_TASK_MAXPARAMSIZE char), xs__TaskFlags, xs__TaskRepeat); + + xs__TaskInterval = 0.0; + + return xs__TaskId; +} + + +// tested +#define XS_MAKE_TASKFUNC(%1) public %1(const _xs__taskparam[], _xs__taskid) if(xs__task_setup(_xs__taskparam, _xs__taskid)) + +// tested +stock xs__task_setup(const param[], taskid) +{ + xs__ITaskId = taskid; + new len = 1 + param[0] * (XS_TASK_MAXPARAMSIZE char); + for (new i = 0; i < len; ++i) + xs__ITaskParam[i] = param[i]; + return 1; +} + +// tested +stock xs_task_readid() +{ + return xs__ITaskId; +} + +// tested +stock xs_task_paramcount() +{ + return xs__ITaskParamCount; +} + +// tested +stock xs_paramtypes:xs_task_paramtype(paramid) +{ + if (paramid < 0 || paramid >= xs__ITaskParamCount) + return xs_invalid; + + return xs_paramtypes:xs__ITaskParamType[paramid]; +} + +// tested +stock xs_task_paramint(paramid) +{ + if (paramid < 0 || paramid >= xs__ITaskParamCount) + return 0; + if (xs__ITaskParamType[paramid] != _:xs_int) + return 0; + + return xs__ITaskParamValue[paramid]; +} + +// tested +stock Float:xs_task_paramfl(paramid) +{ + if (paramid < 0 || paramid >= xs__ITaskParamCount) + return 0.0; + if (xs__ITaskParamType[paramid] != _:xs_float) + return 0.0; + + return Float:xs__ITaskParamValue[paramid]; +} + +// tested +stock xs_task_paramstr(paramid, out[], maxlen) +{ + #pragma unused maxlen + + if (paramid < 0 || paramid >= xs__ITaskParamCount) + return 0; + if (xs__ITaskParamType[paramid] != _:xs_string) + return 0; + + strunpack(out, xs__ITaskParamValue[paramid]); + return 1; +} diff --git a/amxmodx/scripting/mapchooser.sma b/amxmodx/scripting/mapchooser.sma new file mode 100755 index 0000000..55c988b --- /dev/null +++ b/amxmodx/scripting/mapchooser.sma @@ -0,0 +1,294 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Nextmap Chooser Plugin +// + +#include +#include + +#define SELECTMAPS 5 + +new Array:g_mapName; +new g_mapNums; + +new g_nextName[SELECTMAPS] +new g_voteCount[SELECTMAPS + 2] +new g_mapVoteNum +new g_teamScore[2] +new g_lastMap[32] + +new g_coloredMenus +new bool:g_selected = false + +public plugin_init() +{ + register_plugin("Nextmap Chooser", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("mapchooser.txt") + register_dictionary("common.txt") + + g_mapName=ArrayCreate(32); + + new MenuName[64] + + format(MenuName, charsmax(MenuName), "%L", "en", "CHOOSE_NEXTM") + register_menucmd(register_menuid(MenuName), (-1^(-1<<(SELECTMAPS+2))), "countVote") + register_cvar("amx_extendmap_max", "90") + register_cvar("amx_extendmap_step", "15") + + if (cstrike_running()) + register_event("TeamScore", "team_score", "a") + + get_localinfo("lastMap", g_lastMap, charsmax(g_lastMap)) + set_localinfo("lastMap", "") + + new maps_ini_file[64] + get_configsdir(maps_ini_file, charsmax(maps_ini_file)); + format(maps_ini_file, charsmax(maps_ini_file), "%s/maps.ini", maps_ini_file); + + if (!file_exists(maps_ini_file)) + get_cvar_string("mapcyclefile", maps_ini_file, charsmax(maps_ini_file)) + if (loadSettings(maps_ini_file)) + set_task(15.0, "voteNextmap", 987456, "", 0, "b") + + g_coloredMenus = colored_menus() + +} + +public checkVotes() +{ + new b = 0 + + for (new a = 0; a < g_mapVoteNum; ++a) + if (g_voteCount[b] < g_voteCount[a]) + b = a + + + if (g_voteCount[SELECTMAPS] > g_voteCount[b] + && g_voteCount[SELECTMAPS] > g_voteCount[SELECTMAPS+1]) + { + new mapname[32] + + get_mapname(mapname, charsmax(mapname)) + new Float:steptime = get_cvar_float("amx_extendmap_step") + set_cvar_float("mp_timelimit", get_cvar_float("mp_timelimit") + steptime) + client_print(0, print_chat, "%L", LANG_PLAYER, "CHO_FIN_EXT", steptime) + log_amx("Vote: Voting for the nextmap finished. Map %s will be extended to next %.0f minutes", mapname, steptime) + + return + } + + new smap[32] + if (g_voteCount[b] && g_voteCount[SELECTMAPS + 1] <= g_voteCount[b]) + { + ArrayGetString(g_mapName, g_nextName[b], smap, charsmax(smap)); + set_cvar_string("amx_nextmap", smap); + } + + + get_cvar_string("amx_nextmap", smap, charsmax(smap)) + client_print(0, print_chat, "%L", LANG_PLAYER, "CHO_FIN_NEXT", smap) + log_amx("Vote: Voting for the nextmap finished. The nextmap will be %s", smap) +} + +public countVote(id, key) +{ + if (get_cvar_float("amx_vote_answers")) + { + new name[MAX_NAME_LENGTH] + get_user_name(id, name, charsmax(name)) + + if (key == SELECTMAPS) + client_print(0, print_chat, "%L", LANG_PLAYER, "CHOSE_EXT", name) + else if (key < SELECTMAPS) + { + new map[32]; + ArrayGetString(g_mapName, g_nextName[key], map, charsmax(map)); + client_print(0, print_chat, "%L", LANG_PLAYER, "X_CHOSE_X", name, map); + } + } + ++g_voteCount[key] + + return PLUGIN_HANDLED +} + +bool:isInMenu(id) +{ + for (new a = 0; a < g_mapVoteNum; ++a) + if (id == g_nextName[a]) + return true + return false +} + +public voteNextmap() +{ + new winlimit = get_cvar_num("mp_winlimit") + new maxrounds = get_cvar_num("mp_maxrounds") + + if (winlimit) + { + new c = winlimit - 2 + + if ((c > g_teamScore[0]) && (c > g_teamScore[1])) + { + g_selected = false + return + } + } + else if (maxrounds) + { + if ((maxrounds - 2) > (g_teamScore[0] + g_teamScore[1])) + { + g_selected = false + return + } + } else { + new timeleft = get_timeleft() + + if (timeleft < 1 || timeleft > 129) + { + g_selected = false + return + } + } + + if (g_selected) + return + + g_selected = true + + new menu[512], a, mkeys = (1< SELECTMAPS) ? SELECTMAPS : g_mapNums + + for (g_mapVoteNum = 0; g_mapVoteNum < dmax; ++g_mapVoteNum) + { + a = random_num(0, g_mapNums - 1) + + while (isInMenu(a)) + if (++a >= g_mapNums) a = 0 + + g_nextName[g_mapVoteNum] = a + pos += format(menu[pos], charsmax(menu) - pos, "%d. %a^n", g_mapVoteNum + 1, ArrayGetStringHandle(g_mapName, a)); + mkeys |= (1< +#include + +new Array:g_mapName; +new g_mapNums +new g_menuPosition[MAX_PLAYERS + 1] + +new g_voteCount[5] + +new g_voteSelected[MAX_PLAYERS + 1][4] +new g_voteSelectedNum[MAX_PLAYERS + 1] + +new g_coloredMenus + +new g_choosed + +public plugin_init() +{ + register_plugin("Maps Menu", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("mapsmenu.txt") + register_dictionary("common.txt") + register_clcmd("amx_mapmenu", "cmdMapsMenu", ADMIN_MAP, "- displays changelevel menu") + register_clcmd("amx_votemapmenu", "cmdVoteMapMenu", ADMIN_VOTE, "- displays votemap menu") + + register_menucmd(register_menuid("Changelevel Menu"), 1023, "actionMapsMenu") + register_menucmd(register_menuid("Which map do you want?"), 527, "voteCount") + register_menucmd(register_menuid("Change map to"), 527, "voteCount") + register_menucmd(register_menuid("Votemap Menu"), 1023, "actionVoteMapMenu") + register_menucmd(register_menuid("The winner: "), 3, "actionResult") + + g_mapName=ArrayCreate(32); + + new maps_ini_file[64]; + get_configsdir(maps_ini_file, charsmax(maps_ini_file)); + format(maps_ini_file, charsmax(maps_ini_file), "%s/maps.ini", maps_ini_file); + + if (!file_exists(maps_ini_file)) + get_cvar_string("mapcyclefile", maps_ini_file, charsmax(maps_ini_file)); + + if (!file_exists(maps_ini_file)) + format(maps_ini_file, charsmax(maps_ini_file), "mapcycle.txt") + + load_settings(maps_ini_file) + + g_coloredMenus = colored_menus() +} + +public autoRefuse() +{ + log_amx("Vote: %L", "en", "RESULT_REF") + client_print(0, print_chat, "%L", LANG_PLAYER, "RESULT_REF") +} + +public actionResult(id, key) +{ + remove_task(4545454) + + switch (key) + { + case 0: + { + new _modName[10] + get_modname(_modName, charsmax(_modName)) + + if (!equal(_modName, "zp")) + { + message_begin(MSG_ALL, SVC_INTERMISSION) + message_end() + } + + new tempMap[32]; + ArrayGetString(g_mapName, g_choosed, tempMap, charsmax(tempMap)); + + set_task(2.0, "delayedChange", 0, tempMap, strlen(tempMap) + 1) + log_amx("Vote: %L", "en", "RESULT_ACC") + client_print(0, print_chat, "%L", LANG_PLAYER, "RESULT_ACC") + } + case 1: autoRefuse() + } + + return PLUGIN_HANDLED +} + +public checkVotes(id) +{ + id -= 34567 + new num, ppl[MAX_PLAYERS], a = 0 + + get_players(ppl, num, "c") + if (num == 0) num = 1 + g_choosed = -1 + + for (new i = 0; i < g_voteSelectedNum[id]; ++i) + if (g_voteCount[a] < g_voteCount[i]) + a = i + + new votesNum = g_voteCount[0] + g_voteCount[1] + g_voteCount[2] + g_voteCount[3] + g_voteCount[4] + new iRatio = votesNum ? floatround(get_cvar_float("amx_votemap_ratio") * float(votesNum), floatround_ceil) : 1 + new iResult = g_voteCount[a] + + if (iResult >= iRatio) + { + g_choosed = g_voteSelected[id][a] + new tempMap[32]; + ArrayGetString(g_mapName, g_choosed, tempMap, charsmax(tempMap)); + client_print(0, print_chat, "%L %s", LANG_PLAYER, "VOTE_SUCCESS", tempMap); + log_amx("Vote: %L %s", "en", "VOTE_SUCCESS", tempMap); + } + + if (g_choosed != -1) + { + if (is_user_connected(id)) + { + new menuBody[512] + new tempMap[32]; + ArrayGetString(g_mapName, g_choosed, tempMap, charsmax(tempMap)); + new len = format(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L: \w%s^n^n" : "%L: %s^n^n", id, "THE_WINNER", tempMap) + + len += format(menuBody[len], charsmax(menuBody) - len, g_coloredMenus ? "\y%L^n\w" : "%L^n", id, "WANT_CONT") + format(menuBody[len], charsmax(menuBody) - len, "^n1. %L^n2. %L", id, "YES", id, "NO") + + show_menu(id, 0x03, menuBody, 10, "The winner: ") + set_task(10.0, "autoRefuse", 4545454) + } else { + new _modName[10] + get_modname(_modName, charsmax(_modName)) + + if (!equal(_modName, "zp")) + { + message_begin(MSG_ALL, SVC_INTERMISSION) + message_end() + } + new tempMap[32]; + ArrayGetString(g_mapName, g_choosed, tempMap, charsmax(tempMap)); + set_task(2.0, "delayedChange", 0, tempMap, strlen(tempMap) + 1) + } + } else { + client_print(0, print_chat, "%L", LANG_PLAYER, "VOTE_FAILED") + log_amx("Vote: %L", "en", "VOTE_FAILED") + } + + remove_task(34567 + id) +} + +public voteCount(id, key) +{ + if (key > 3) + { + client_print(0, print_chat, "%L", LANG_PLAYER, "VOT_CANC") + remove_task(34567 + id) + set_cvar_float("amx_last_voting", get_gametime()) + log_amx("Vote: Cancel vote session") + + return PLUGIN_HANDLED + } + + if (get_cvar_float("amx_vote_answers")) + { + new name[MAX_NAME_LENGTH] + + get_user_name(id, name, charsmax(name)) + client_print(0, print_chat, "%L", LANG_PLAYER, "X_VOTED_FOR", name, key + 1) + } + + ++g_voteCount[key] + + return PLUGIN_HANDLED +} + +isMapSelected(id, pos) +{ + for (new a = 0; a < g_voteSelectedNum[id]; ++a) + if (g_voteSelected[id][a] == pos) + return 1 + return 0 +} + +displayVoteMapsMenu(id, pos) +{ + if (pos < 0) + return + + new menuBody[512], b = 0, start = pos * 7 + + if (start >= g_mapNums) + start = pos = g_menuPosition[id] = 0 + + new len = format(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "VOTEMAP_MENU", pos + 1, (g_mapNums / 7 + ((g_mapNums % 7) ? 1 : 0))) + new end = start + 7, keys = MENU_KEY_0 + + if (end > g_mapNums) + end = g_mapNums + + new tempMap[32]; + for (new a = start; a < end; ++a) + { + ArrayGetString(g_mapName, a, tempMap, charsmax(tempMap)); + if (g_voteSelectedNum[id] == 4 || isMapSelected(id, pos * 7 + b)) + { + ++b + if (g_coloredMenus) + len += format(menuBody[len], charsmax(menuBody) - len, "\d%d. %s^n\w", b, tempMap) + else + len += format(menuBody[len], charsmax(menuBody) - len, "#. %s^n", tempMap) + } else { + keys |= (1< get_gametime()) + { + client_print(id, print_chat, "%L", id, "ALREADY_VOT") + return PLUGIN_HANDLED + } + + g_voteSelectedNum[id] = 0 + + if (g_mapNums) + { + displayVoteMapsMenu(id, g_menuPosition[id] = 0) + } else { + console_print(id, "%L", id, "NO_MAPS_MENU") + client_print(id, print_chat, "%L", id, "NO_MAPS_MENU") + } + + return PLUGIN_HANDLED +} + +public cmdMapsMenu(id, level, cid) +{ + if (!cmd_access(id, level, cid, 1)) + return PLUGIN_HANDLED + + if (g_mapNums) + { + displayMapsMenu(id, g_menuPosition[id] = 0) + } else { + console_print(id, "%L", id, "NO_MAPS_MENU") + client_print(id, print_chat, "%L", id, "NO_MAPS_MENU") + } + + return PLUGIN_HANDLED +} + +public delayedChange(mapname[]) +{ + engine_changelevel(mapname) +} + +public actionVoteMapMenu(id, key) +{ + new tempMap[32]; + switch (key) + { + case 7: + { + new Float:voting = get_cvar_float("amx_last_voting") + + if (voting > get_gametime()) + { + client_print(id, print_chat, "%L", id, "ALREADY_VOT") + return PLUGIN_HANDLED + } + + if (voting && voting + get_cvar_float("amx_vote_delay") > get_gametime()) + { + client_print(id, print_chat, "%L", id, "VOT_NOW_ALLOW") + return PLUGIN_HANDLED + } + + g_voteCount = {0, 0, 0, 0, 0} + + new Float:vote_time = get_cvar_float("amx_vote_time") + 2.0 + set_cvar_float("amx_last_voting", get_gametime() + vote_time) + new iVoteTime = floatround(vote_time) + + set_task(vote_time, "checkVotes", 34567 + id) + + new menuBody[512] + new players[MAX_PLAYERS] + new pnum, keys, len + + get_players(players, pnum) + + if (g_voteSelectedNum[id] > 1) + { + len = format(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L^n\w^n" : "%L^n^n", id, "WHICH_MAP") + + for (new c = 0; c < g_voteSelectedNum[id]; ++c) + { + ArrayGetString(g_mapName, g_voteSelected[id][c], tempMap, charsmax(tempMap)); + len += format(menuBody[len], charsmax(menuBody) - len, "%d. %s^n", c + 1, tempMap) + keys |= (1< 0) + { + ArrayGetString(g_mapName, g_voteSelected[id][0], tempMapA, charsmax(tempMapA)); + } + else + { + copy(tempMapA, charsmax(tempMapA), ""); + } + if (g_voteSelectedNum[id] > 1) + { + ArrayGetString(g_mapName, g_voteSelected[id][1], tempMapB, charsmax(tempMapB)); + } + else + { + copy(tempMapB, charsmax(tempMapB), ""); + } + if (g_voteSelectedNum[id] > 2) + { + ArrayGetString(g_mapName, g_voteSelected[id][2], tempMapC, charsmax(tempMapC)); + } + else + { + copy(tempMapC, charsmax(tempMapC), ""); + } + if (g_voteSelectedNum[id] > 3) + { + ArrayGetString(g_mapName, g_voteSelected[id][3], tempMapD, charsmax(tempMapD)); + } + else + { + copy(tempMapD, charsmax(tempMapD), ""); + } + + log_amx("Vote: ^"%s<%d><%s><>^" vote maps (map#1 ^"%s^") (map#2 ^"%s^") (map#3 ^"%s^") (map#4 ^"%s^")", + name, get_user_userid(id), authid, + tempMapA, tempMapB, tempMapC, tempMapD) + } + case 8: displayVoteMapsMenu(id, ++g_menuPosition[id]) + case 9: displayVoteMapsMenu(id, --g_menuPosition[id]) + default: + { + g_voteSelected[id][g_voteSelectedNum[id]++] = g_menuPosition[id] * 7 + key + displayVoteMapsMenu(id, g_menuPosition[id]) + } + } + + return PLUGIN_HANDLED +} + +public actionMapsMenu(id, key) +{ + switch (key) + { + case 8: displayMapsMenu(id, ++g_menuPosition[id]) + case 9: displayMapsMenu(id, --g_menuPosition[id]) + default: + { + new a = g_menuPosition[id] * 8 + key + new _modName[10] + + get_modname(_modName, charsmax(_modName)) + if (!equal(_modName, "zp")) + { + message_begin(MSG_ALL, SVC_INTERMISSION) + message_end() + } + + new authid[32], name[MAX_NAME_LENGTH] + + get_user_authid(id, authid, charsmax(authid)) + get_user_name(id, name, charsmax(name)) + + new tempMap[32]; + ArrayGetString(g_mapName, a, tempMap, charsmax(tempMap)); + + show_activity_key("ADMIN_CHANGEL_1", "ADMIN_CHANGEL_2", name, tempMap); + + log_amx("Cmd: ^"%s<%d><%s><>^" changelevel ^"%s^"", name, get_user_userid(id), authid, tempMap) + set_task(2.0, "delayedChange", 0, tempMap, strlen(tempMap) + 1) + /* displayMapsMenu(id, g_menuPosition[id]) */ + } + } + + return PLUGIN_HANDLED +} + +displayMapsMenu(id, pos) +{ + if (pos < 0) + return + + new menuBody[512] + new tempMap[32] + new start = pos * 8 + new b = 0 + + if (start >= g_mapNums) + start = pos = g_menuPosition[id] = 0 + + new len = format(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "CHANGLE_MENU", pos + 1, (g_mapNums / 8 + ((g_mapNums % 8) ? 1 : 0))) + new end = start + 8 + new keys = MENU_KEY_0 + + if (end > g_mapNums) + end = g_mapNums + + for (new a = start; a < end; ++a) + { + keys |= (1< +#include + +#define MAXMENUS 128 +#define STRINGSIZE 32 +#define STRINGLENGTH STRINGSIZE - 1 +#define MENUITEMSPERPAGE 8 +//#define MENUS_NUMBER 16 + +new g_coloredMenus +new g_menuPosition[MAX_PLAYERS + 1] + +new g_menusNumber = 0 +new g_menuBody[MAXMENUS][STRINGSIZE] +new g_menuCmd[MAXMENUS][STRINGSIZE] +new g_menuAccess[MAXMENUS] +new g_menuPlugin[MAXMENUS][STRINGSIZE] + +new g_clientMenusNumber = 0 +new g_clientMenuBody[MAXMENUS][STRINGSIZE] +new g_clientMenuCmd[MAXMENUS][STRINGSIZE] +new g_clientMenuAccess[MAXMENUS] +new g_clientMenuPlugin[MAXMENUS][STRINGSIZE] + +public plugin_init() +{ + register_plugin("Menus Front-End", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("menufront.txt") + register_dictionary("common.txt") + + register_menucmd(register_menuid("AMX Mod X Menu"), 1023, "actionMenu") + register_menucmd(register_menuid("AMX Mod X Client Menu"), 1023, "clientActionMenu") + register_clcmd("amxmodmenu", "cmdMenu", ADMIN_MENU, "- displays menus") + register_clcmd("amx_menu", "clientCmdMenu", 0, "- displays menus available to client") + + register_srvcmd("amx_addmenuitem", "addmenuitem_cmd", 0, " - Add a menu item to Menus Front-End") + register_srvcmd("amx_addclientmenuitem", "addclientmenuitem_cmd", 0, " - Add a menu item to Client Menus Front-End") + + g_coloredMenus = colored_menus() +} + +public plugin_cfg() +{ + AddDefaultMenus() + + new configs[128] + get_configsdir(configs, charsmax(configs)) + server_cmd("exec %s/custommenuitems.cfg", configs) +} + +// menuBody: Text that will be shown for this item in menu +// menuCmd: Command that should be executed to start menu +// menuAccess: Access required for menu +// menuPlugin: The exact case-insensitive name of plugin holding the menu command +public AddMenu(const menuBody[], const menuCmd[], const menuAccess, const menuPlugin[]) +{ + if (g_menusNumber + 1 == MAXMENUS) + { + log_amx("Error: Plugin ^"%s^" tried to add a menu item to Menu Front-End plugin with maximum menu items reached!", menuPlugin) + return + } + + copy(g_menuBody[g_menusNumber], STRINGLENGTH, menuBody) + copy(g_menuCmd[g_menusNumber], STRINGLENGTH, menuCmd) + g_menuAccess[g_menusNumber] = menuAccess + + copy(g_menuPlugin[g_menusNumber], STRINGLENGTH, menuPlugin) + + g_menusNumber++ + // server_print("Menu item %d added to Menus Front-End: ^"%s^" from plugin ^"%s^"", g_menusNumber, menuBody, menuPlugin) +} + +public AddClientMenu(const menuBody[], const menuCmd[], const menuAccess, const menuPlugin[]) +{ + if (g_clientMenusNumber + 1 == MAXMENUS) + { + log_amx("Error: Plugin ^"%s^" tried to add a menu item to Menu Front-End plugin with maximum menu items reached!", menuPlugin) + return + } + + copy(g_clientMenuBody[g_clientMenusNumber], STRINGLENGTH, menuBody) + copy(g_clientMenuCmd[g_clientMenusNumber], STRINGLENGTH, menuCmd) + g_clientMenuAccess[g_clientMenusNumber] = menuAccess + + copy(g_clientMenuPlugin[g_clientMenusNumber], STRINGLENGTH, menuPlugin) + + g_clientMenusNumber++ + server_print("Client menu item %d added to Client Menus Front-End: ^"%s^" from plugin ^"%s^"", g_clientMenusNumber, menuBody, menuPlugin) +} + +AddDefaultMenus() +{ + new flags; + AddMenu("KICK_PLAYER", "amx_kickmenu", get_clcmd_flags("amx_kickmenu", flags) ? flags : ADMIN_KICK , "Players Menu") + AddMenu("BAN_PLAYER", "amx_banmenu", get_clcmd_flags("amx_banmenu", flags) ? flags : ADMIN_BAN, "Players Menu") + AddMenu("SLAP_SLAY", "amx_slapmenu", get_clcmd_flags("amx_slapmenu", flags) ? flags : ADMIN_SLAY, "Players Menu") + AddMenu("TEAM_PLAYER", "amx_teammenu", get_clcmd_flags("amx_teammenu", flags) ? flags : ADMIN_LEVEL_A, "Players Menu") + AddMenu("CHANGEL", "amx_mapmenu", get_clcmd_flags("amx_mapmenu", flags) ? flags : ADMIN_MAP, "Maps Menu") + AddMenu("VOTE_MAPS", "amx_votemapmenu", get_clcmd_flags("amx_votemapmenu", flags) ? flags : ADMIN_VOTE, "Maps Menu") + AddMenu("SPECH_STUFF", "amx_speechmenu", get_clcmd_flags("amx_speechmenu", flags) ? flags : ADMIN_MENU, "Commands Menu") + AddMenu("CLIENT_COM", "amx_clcmdmenu", get_clcmd_flags("amx_clcmdmenu", flags) ? flags : ADMIN_LEVEL_A, "Players Menu") + AddMenu("SERVER_COM", "amx_cmdmenu", get_clcmd_flags("amx_cmdmenu", flags) ? flags : ADMIN_MENU, "Commands Menu") + AddMenu("CVARS_SET", "amx_cvarmenu", get_clcmd_flags("amx_cvarmenu", flags) ? flags : ADMIN_CVAR, "Commands Menu") + AddMenu("CONFIG", "amx_cfgmenu", get_clcmd_flags("amx_cfgmenu", flags) ? flags : ADMIN_MENU, "Commands Menu") + AddMenu("LANG_SET", "amx_langmenu", get_clcmd_flags("amx_langmenu", flags) ? flags : ADMIN_CFG, "Multi-Lingual System") + AddMenu("STATS_SET", "amx_statscfgmenu", get_clcmd_flags("amx_statscfgmenu", flags) ? flags : ADMIN_CFG, "Stats Configuration") + AddMenu("PAUSE_PLUG", "amx_pausecfgmenu", get_clcmd_flags("amx_pausecfgmenu", flags) ? flags : ADMIN_CFG, "Pause Plugins") + AddMenu("RES_WEAP", "amx_restmenu", get_clcmd_flags("amx_restmenu", flags) ? flags : ADMIN_CFG, "Restrict Weapons") + AddMenu("TELE_PLAYER", "amx_teleportmenu", get_clcmd_flags("amx_teleportmenu", flags) ? flags : ADMIN_CFG, "Teleport Menu") +} + +stock bool:get_clcmd_flags(const search_command[], &flags) +{ + new count = get_clcmdsnum(-1); + static cmd[128]; + static info[1]; + new _flags; + + for (new i = 0; i < count; i++) + { + get_clcmd(i, cmd, charsmax(cmd), _flags, info, charsmax(info), -1); + + if (strcmp(cmd, search_command) == 0) + { + flags = _flags; + return true; + } + } + + return false; +} + +public actionMenu(id, key) +{ + switch (key) + { + case 8: displayMenu(id, ++g_menuPosition[id]) + case 9: displayMenu(id, --g_menuPosition[id]) + default: client_cmd(id, "%s", g_menuCmd[g_menuPosition[id] * 8 + key]) + } + return PLUGIN_HANDLED +} + +public clientActionMenu(id, key) +{ + switch (key) + { + case 8: clientDisplayMenu(id, ++g_menuPosition[id]) + case 9: clientDisplayMenu(id, --g_menuPosition[id]) + default: client_cmd(id, "%s", g_clientMenuCmd[g_menuPosition[id] * 8 + key]) + } + return PLUGIN_HANDLED +} + +displayMenu(id, pos) +{ + if (pos < 0) + return + + new menuBody[512] + new b = 0 + new start = pos * MENUITEMSPERPAGE + + if (start >= g_menusNumber) // MENUS_NUMBER + start = pos = g_menuPosition[id] = 0 + + new len = format(menuBody, charsmax(menuBody), + + g_coloredMenus ? "\yAMX Mod X Menu\R%d/%d^n\w^n" : "AMX Mod X Menu %d/%d^n^n" , pos + 1, (g_menusNumber / MENUITEMSPERPAGE) + (((g_menusNumber % MENUITEMSPERPAGE) > 0) ? 1 : 0)) + + new end = min(start + MENUITEMSPERPAGE, g_menusNumber); + new keys = MENU_KEY_0 + + new iUserFlags = get_user_flags(id); + for (new a = start; a < end; ++a) + { + if ( (g_menuAccess[a] == 0 || iUserFlags & g_menuAccess[a]) && + ((is_plugin_loaded(g_menuPlugin[a]) != -1) || // search plugins for registered name + (is_plugin_loaded(g_menuPlugin[a], true) != -1))) // search plugins for filename + { + keys |= (1<= g_clientMenusNumber) // MENUS_NUMBER + start = pos = g_menuPosition[id] = 0 + + new len = format(menuBody, charsmax(menuBody), g_coloredMenus ? "\yAMX Mod X Client Menu\R%d/%d^n\w^n" : "AMX Mod X Client Menu %d/%d^n^n" , pos + 1, (g_clientMenusNumber / MENUITEMSPERPAGE) + (((g_clientMenusNumber % MENUITEMSPERPAGE) > 0) ? 1 : 0)) + + new end = min(start + MENUITEMSPERPAGE, g_clientMenusNumber); + new keys = MENU_KEY_0 + + new iUserFlags = get_user_flags(id); + for (new a = start; a < end; ++a) + { + if ( (g_clientMenuAccess[a] == 0 || iUserFlags & g_clientMenuAccess[a]) && + ((is_plugin_loaded(g_clientMenuPlugin[a]) != -1) || // search plugins for registered name + (is_plugin_loaded(g_clientMenuPlugin[a], true) != -1))) // search plugins for file name + { + keys |= (1< +#include +#include +#include + +public MultiKill +public MultiKillSound +public BombPlanting +public BombDefusing +public BombPlanted +public BombDefused +public BombFailed +public BombPickUp +public BombDrop +public BombCountVoice +public BombCountDef +public BombReached +public ItalyBonusKill +public EnemyRemaining +public LastMan +public LastManHealth +public KnifeKill +public KnifeKillSound +public GrenadeKill +public GrenadeSuicide +public HeadShotKill +public HeadShotKillSound +public RoundCounterSound +public RoundCounter +public KillingStreak +public KillingStreakSound +public DoubleKill +public DoubleKillSound +public PlayerName +public FirstBloodSound + +public BombPlantedSound +public BombDefusedSound +public BombFailedSound +public BombCountHUD +public LastManSound +public GrenadeKillSound +public GrenadeSuicideSound + +const SOUNDFILE_PATH_MAXLEN = 64 +const SOUND_SHORTPATH_MAXLEN = SOUNDFILE_PATH_MAXLEN - 10 // 64 (sound/ [ 54 ] .wav) critical value for fast dl + +new g_streakKills[MAX_PLAYERS + 1][2] +new g_multiKills[MAX_PLAYERS + 1][2] +new g_C4Timer +new g_Defusing +new g_Planter +new Float:g_LastOmg +new g_LastAnnounce +new g_roundCount +new Float:g_doubleKill +new g_doubleKillId +new g_friend[MAX_PLAYERS + 1] +new g_firstBlood +new g_center1_sync +new g_announce_sync +new g_status_sync +new g_left_sync +new g_bottom_sync +new g_he_sync + +new g_pcvar_mp_c4timer, g_c4timer_value + +const TASK_BOMB_TIMER = 8038 +const TASK_DELAYED_NEW_ROUND = 98038 + +new g_connected[MAX_PLAYERS + 1] +new g_msounds[MAX_PLAYERS + 1] +new const _msound[] = "_msound" + +new g_MultiKillMsg[7][] = +{ + "Multi-Kill! %s^n%L %d %L (%d %L)", + "Ultra-Kill!!! %s^n%L %d %L (%d %L)", + "%s IS ON A KILLING SPREE!!!^n%L %d %L (%d %L)", + "RAMPAGE!!! %s^n%L %d %L (%d %L)", + "%s IS UNSTOPPABLE!!!^n%L %d %L (%d %L)", + "%s IS A MONSTER!^n%L %d %L (%d %L)", + "%s IS GODLIKE!!!!^n%L %d %L (%d %L)" +} + +new g_Sounds[7][SOUND_SHORTPATH_MAXLEN] = +{ + "misc/multikill", + "misc/ultrakill", + "misc/killingspree", + "misc/rampage", + "misc/unstoppable", + "misc/monsterkill", + "misc/godlike" +} + +new g_firstbloodsound[SOUND_SHORTPATH_MAXLEN] = "misc/firstblood" +new g_lastmansound_1vsothers[SOUND_SHORTPATH_MAXLEN] = "misc/oneandonly" +new g_lastmansound_duel[SOUND_SHORTPATH_MAXLEN] = "misc/maytheforce" +new g_hssound_killer[SOUND_SHORTPATH_MAXLEN] = "misc/headshot" +new g_hssound_victim[SOUND_SHORTPATH_MAXLEN] = "misc/headshot" +new g_knifekillsound[SOUND_SHORTPATH_MAXLEN] = "misc/humiliation" +new g_doublekillsound[SOUND_SHORTPATH_MAXLEN] = "misc/doublekill" +new g_roundcountersound[SOUND_SHORTPATH_MAXLEN] = "misc/prepare" +new g_grenadekillsound[SOUND_SHORTPATH_MAXLEN] = "djeyl/grenade" +new g_grenadesuicidesound[SOUND_SHORTPATH_MAXLEN] = "djeyl/witch" +new g_bombplantedsound[SOUND_SHORTPATH_MAXLEN] = "djeyl/c4powa" +new g_bombdefusedsound[SOUND_SHORTPATH_MAXLEN] = "djeyl/laugh" +new g_bombfailedsound[SOUND_SHORTPATH_MAXLEN] = "djeyl/witch" + +new g_KillingMsg[7][] = +{ + "%s: Multi-Kill!", + "%s: Ultra-Kill!!!", + "%s IS ON A KILLING SPREE!!!", + "%s: RAMPAGE!!!", + "%s IS UNSTOPPABLE!!!", + "%s IS A MONSTER!", + "%s IS GODLIKE!!!" +} + +new g_KinfeMsg[4][] = +{ + "KNIFE_MSG_1", + "KNIFE_MSG_2", + "KNIFE_MSG_3", + "KNIFE_MSG_4" +} + +new g_LastMessages[4][] = +{ + "LAST_MSG_1", + "LAST_MSG_2", + "LAST_MSG_3", + "LAST_MSG_4" +} + +new g_HeMessages[4][] = +{ + "HE_MSG_1", + "HE_MSG_2", + "HE_MSG_3", + "HE_MSG_4" +} + +new g_SHeMessages[4][] = +{ + "SHE_MSG_1", + "SHE_MSG_2", + "SHE_MSG_3", + "SHE_MSG_4" +} + +new g_HeadShots[7][] = +{ + "HS_MSG_1", + "HS_MSG_2", + "HS_MSG_3", + "HS_MSG_4", + "HS_MSG_5", + "HS_MSG_6", + "HS_MSG_7" +} + +new const g_teamsNames[CsTeams][] = { "", "TERRORIST" , "CT", "" }; + +public plugin_init() +{ + register_plugin("CS Misc. Stats", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("miscstats.txt") + register_dictionary("statsx.txt") + register_event("TextMsg", "eRestart", "a", "2&#Game_C", "2&#Game_w") + register_event("SendAudio", "eEndRound", "a", "2&%!MRAD_terwin", "2&%!MRAD_ctwin", "2&%!MRAD_rounddraw") + + register_event("HLTV", "Event_HLTV_New_Round", "a", "1=0", "2=0") // cache c4 timer value + register_logevent("LogEvent_Round_Start", 2, "1=Round_Start") // replaces ugly register_event("RoundTime", "eNewRound", "bc") + register_event("StatusValue", "setTeam", "bef", "1=1") + register_event("StatusValue", "showStatus", "bef", "1=2", "2!0") + register_event("StatusValue", "hideStatus", "bef", "1=1", "2=0") + + new mapname[32], n = get_mapname(mapname, charsmax(mapname)) + if ((get_map_objectives() & MapObjective_Bomb) || (equali(mapname, "de_", 3) || equali(mapname, "csde_", 5))) + { + register_event("StatusIcon", "eGotBomb", "be", "1=1", "1=2", "2=c4") + register_event("TextMsg", "eBombPickUp", "bc", "2&#Got_bomb") + register_event("TextMsg", "eBombDrop", "bc", "2&#Game_bomb_d") + register_event("BarTime", "eStopDefuse", "b", "1=0") + } + else if (equali(mapname, "cs_italy") || equali(mapname, "cs_italy_cz")) + { + register_event("23", "chickenKill", "a", "1=108", "15=4") + register_event("23", "radioKill", "a", "1=108", n == 8 ? "15=2" : "15=8") // cz radio is wood + + } + + g_center1_sync = CreateHudSyncObj() + g_announce_sync = CreateHudSyncObj() + g_status_sync = CreateHudSyncObj() + g_left_sync = CreateHudSyncObj() + g_bottom_sync = CreateHudSyncObj() + g_he_sync = CreateHudSyncObj() + + g_pcvar_mp_c4timer = get_cvar_pointer("mp_c4timer") + g_c4timer_value = get_pcvar_num( g_pcvar_mp_c4timer ) + + register_clcmd("say /msounds", "cmdSwitchSounds", _, " - switches sounds on and off") + register_clcmd("say_team /msounds", "cmdSwitchSounds", _, " - switches sounds on and off") +} + +public plugin_precache() +{ + // parse sounds and precache them + new szConfigsDir[64], szCfgFile[64] + get_configsdir(szConfigsDir, charsmax(szConfigsDir)) + formatex(szCfgFile, charsmax(szCfgFile), "%s/stats.ini", szConfigsDir) + + new buffer[256] + + // initialize xvars so we can know later if sounds have to be precached or not. + // xvars gonna be initialized again in statscfg.amxx plugin_init, this is ok. + new fp = fopen(szCfgFile, "rt") + if( fp ) + { + new xvarname[32], xvarid + while( !feof(fp) ) + { + fgets(fp, buffer, charsmax(buffer)) + trim(buffer) + if( buffer[0] != ';' ) + { + parse(buffer, xvarname, charsmax(xvarname)) + if ((xvarid = get_xvar_id(xvarname)) != -1) + { + set_xvar_num(xvarid, 1) + } + } + } + fclose(fp) + } + + formatex(szCfgFile, charsmax(szCfgFile), "%s/miscstats.ini", szConfigsDir) + fp = fopen(szCfgFile, "rt") + if( fp ) + { + new szSoundKey[32], szSoundFile[SOUNDFILE_PATH_MAXLEN] + while( !feof(fp) ) + { + fgets(fp, buffer, charsmax(buffer)) + trim(buffer) + if( buffer[0] != ';' && parse(buffer, szSoundKey, charsmax(szSoundKey), szSoundFile, charsmax(szSoundFile)) == 2 ) + { + if( equal(szSoundKey, "FirstBloodSound") ) + { + copy_sound(g_firstbloodsound, charsmax(g_firstbloodsound), szSoundFile) + if( FirstBloodSound ) precache_sound_custom(g_firstbloodsound) + } + else if( equal(szSoundKey, "LastManVsOthersSound") ) + { + copy_sound(g_lastmansound_1vsothers, charsmax(g_lastmansound_1vsothers), szSoundFile) + if( LastManSound ) precache_sound_custom(g_lastmansound_1vsothers) + } + else if( equal(szSoundKey, "LastManDuelSound") ) + { + copy_sound(g_lastmansound_duel, charsmax(g_lastmansound_duel), szSoundFile) + if( LastManSound ) precache_sound_custom(g_lastmansound_duel) + } + else if( equal(szSoundKey, "HeadShotKillSoundKiller") ) + { + copy_sound(g_hssound_killer, charsmax(g_hssound_killer), szSoundFile) + if( HeadShotKillSound ) precache_sound_custom(g_hssound_killer) + } + else if( equal(szSoundKey, "HeadShotKillSoundVictim") ) + { + copy_sound(g_hssound_victim, charsmax(g_hssound_victim), szSoundFile) + if( HeadShotKillSound ) precache_sound_custom(g_hssound_victim) + } + else if( equal(szSoundKey, "KnifeKillSound") ) + { + copy_sound(g_knifekillsound, charsmax(g_knifekillsound), szSoundFile) + if( KnifeKillSound ) precache_sound_custom(g_knifekillsound) + } + else if( equal(szSoundKey, "DoubleKillSound") ) + { + copy_sound(g_doublekillsound, charsmax(g_doublekillsound), szSoundFile) + if( DoubleKillSound ) precache_sound_custom(g_doublekillsound) + } + else if( equal(szSoundKey, "RoundCounterSound") ) + { + copy_sound(g_roundcountersound, charsmax(g_roundcountersound), szSoundFile) + if( RoundCounterSound ) precache_sound_custom(g_roundcountersound) + } + else if( equal(szSoundKey, "GrenadeKillSound") ) + { + copy_sound(g_grenadekillsound, charsmax(g_grenadekillsound), szSoundFile) + if( GrenadeKillSound ) precache_sound_custom(g_grenadekillsound) + } + else if( equal(szSoundKey, "GrenadeSuicideSound") ) + { + copy_sound(g_grenadesuicidesound, charsmax(g_grenadesuicidesound), szSoundFile) + if( GrenadeSuicideSound ) precache_sound_custom(g_grenadesuicidesound) + } + else if( equal(szSoundKey, "BombPlantedSound") ) + { + copy_sound(g_bombplantedsound, charsmax(g_bombplantedsound), szSoundFile) + if( BombPlantedSound ) precache_sound_custom(g_bombplantedsound) + } + else if( equal(szSoundKey, "BombDefusedSound") ) + { + copy_sound(g_bombdefusedsound, charsmax(g_bombdefusedsound), szSoundFile) + if( BombDefusedSound ) precache_sound_custom(g_bombdefusedsound) + } + else if( equal(szSoundKey, "BombFailedSound") ) + { + copy_sound(g_bombfailedsound, charsmax(g_bombfailedsound), szSoundFile) + if( BombFailedSound ) precache_sound_custom(g_bombfailedsound) + } + else + { + // KillingStreakSound and MultiKillSound + if( equal(szSoundKey, "MultiKillSound") ) + { + copy_sound(g_Sounds[0], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[0]) + } + else if( equal(szSoundKey, "UltraKillSound") ) + { + copy_sound(g_Sounds[1], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[1]) + } + else if( equal(szSoundKey, "KillingSpreeSound") ) + { + copy_sound(g_Sounds[2], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[2]) + } + else if( equal(szSoundKey, "RampageSound") ) + { + copy_sound(g_Sounds[3], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[3]) + } + else if( equal(szSoundKey, "UnstopableSound") ) + { + copy_sound(g_Sounds[4], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[4]) + } + else if( equal(szSoundKey, "MonsterKillSound") ) + { + copy_sound(g_Sounds[5], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[5]) + } + else if( equal(szSoundKey, "GodLike") ) + { + copy_sound(g_Sounds[6], charsmax(g_Sounds[]), szSoundFile) + if( KillingStreakSound || MultiKillSound ) precache_sound_custom(g_Sounds[6]) + } + } + } + } + fclose(fp) + } +} + +precache_sound_custom( const sound[] ) +{ + new fullpathsound[SOUNDFILE_PATH_MAXLEN] + formatex(fullpathsound, charsmax(fullpathsound), "sound/%s.wav", sound) + if( file_exists(fullpathsound) ) + { + precache_sound(fullpathsound[6]) + } + else + { + log_amx("Could not locate <%s> file", fullpathsound) + } +} + +copy_sound(dest[], len, src[]) +{ + new n = copy(dest, len, src[ 6 * equali(src, "sound/", 6) ]) + if( n > 4 && equal(dest[n-4], ".wav") ) + { + dest[n-4] = EOS + } +} + +public plugin_cfg() +{ + new g_addStast[] = "amx_statscfg add ^"%s^" %s" + + server_cmd(g_addStast, "ST_MULTI_KILL", "MultiKill") + server_cmd(g_addStast, "ST_MULTI_KILL_SOUND", "MultiKillSound") + server_cmd(g_addStast, "ST_BOMB_PLANTING", "BombPlanting") + server_cmd(g_addStast, "ST_BOMB_DEFUSING", "BombDefusing") + server_cmd(g_addStast, "ST_BOMB_PLANTED", "BombPlanted") + server_cmd(g_addStast, "ST_BOMB_PLANTED_SOUND", "BombPlantedSound") + server_cmd(g_addStast, "ST_BOMB_DEF_SUCC", "BombDefused") + server_cmd(g_addStast, "ST_BOMB_DEF_SUCC_SOUND", "BombDefusedSound") + server_cmd(g_addStast, "ST_BOMB_DEF_FAIL", "BombFailed") + server_cmd(g_addStast, "ST_BOMB_DEF_FAIL_SOUND", "BombFailedSound") + server_cmd(g_addStast, "ST_BOMB_PICKUP", "BombPickUp") + server_cmd(g_addStast, "ST_BOMB_DROP", "BombDrop") + server_cmd(g_addStast, "ST_BOMB_CD_HUD", "BombCountHUD") + server_cmd(g_addStast, "ST_BOMB_CD_VOICE", "BombCountVoice") + server_cmd(g_addStast, "ST_BOMB_CD_DEF", "BombCountDef") + server_cmd(g_addStast, "ST_BOMB_SITE", "BombReached") + server_cmd(g_addStast, "ST_ITALY_BONUS", "ItalyBonusKill") + server_cmd(g_addStast, "ST_LAST_MAN", "LastMan") + server_cmd(g_addStast, "ST_LAST_MAN_HEALTH", "LastManHealth") + server_cmd(g_addStast, "ST_LAST_MAN_SOUND", "LastManSound") + server_cmd(g_addStast, "ST_KNIFE_KILL", "KnifeKill") + server_cmd(g_addStast, "ST_KNIFE_KILL_SOUND", "KnifeKillSound") + server_cmd(g_addStast, "ST_HE_KILL", "GrenadeKill") + server_cmd(g_addStast, "ST_HE_KILL_SOUND", "GrenadeKillSound") + server_cmd(g_addStast, "ST_HE_SUICIDE", "GrenadeSuicide") + server_cmd(g_addStast, "ST_HE_SUICIDE_SOUND", "GrenadeSuicideSound") + server_cmd(g_addStast, "ST_HS_KILL", "HeadShotKill") + server_cmd(g_addStast, "ST_HS_KILL_SOUND", "HeadShotKillSound") + server_cmd(g_addStast, "ST_ROUND_CNT", "RoundCounter") + server_cmd(g_addStast, "ST_ROUND_CNT_SOUND", "RoundCounterSound") + server_cmd(g_addStast, "ST_KILL_STR", "KillingStreak") + server_cmd(g_addStast, "ST_KILL_STR_SOUND", "KillingStreakSound") + server_cmd(g_addStast, "ST_ENEMY_REM", "EnemyRemaining") + server_cmd(g_addStast, "ST_DOUBLE_KILL", "DoubleKill") + server_cmd(g_addStast, "ST_DOUBLE_KILL_SOUND", "DoubleKillSound") + server_cmd(g_addStast, "ST_PLAYER_NAME", "PlayerName") + server_cmd(g_addStast, "ST_FIRST_BLOOD_SOUND", "FirstBloodSound") +} + +public client_connect(id) +{ + if( is_user_bot(id) ) + { + g_msounds[id] = 0 + return; + } + new info[2] + if( !get_user_info(id, _msound, info, charsmax(info)) || info[0] != '0' ) + { + g_msounds[id] = 1 + } + else + { + g_msounds[id] = 0 + } +} + +public client_putinserver(id) +{ + g_multiKills[id] = {0, 0} + g_streakKills[id] = {0, 0} + g_connected[id] = true +} + +public client_disconnected(id) +{ + g_connected[id] = false +} + +public client_death(killer, victim, wpnindex, hitplace, TK) +{ + if (wpnindex == CSW_C4) + return + + new headshot = (hitplace == HIT_HEAD) ? 1 : 0 + new selfkill = (killer == victim) ? 1 : 0 + + new victim_alive = is_user_alive(victim) // happens on ClientKill + + if (g_firstBlood) + { + g_firstBlood = 0 + if (FirstBloodSound) + play_sound(0, g_firstbloodsound) + } + + if ((KillingStreak || KillingStreakSound) && !TK) + { + g_streakKills[victim][1]++ + g_streakKills[victim][0] = 0 + + if (!selfkill) + { + g_streakKills[killer][0]++ + g_streakKills[killer][1] = 0 + + new a = g_streakKills[killer][0] - 3 + + if ((a > -1) && !(a % 2)) + { + new name[MAX_NAME_LENGTH] + get_user_name(killer, name, charsmax(name)) + + if ((a >>= 1) > 6) + a = 6 + + if (KillingStreak) + { + set_hudmessage(0, 100, 255, 0.05, 0.50, 2, 0.02, 6.0, 0.01, 0.1, -1) + ShowSyncHudMsg(0, g_left_sync, g_KillingMsg[a], name) + } + + if (KillingStreakSound) + { + play_sound(0, g_Sounds[a]) + } + } + } + } + + if (MultiKill || MultiKillSound) + { + if (!selfkill && !TK && killer) + { + g_multiKills[killer][0]++ + g_multiKills[killer][1] += headshot + + new param[2] + + param[0] = killer + param[1] = g_multiKills[killer][0] + set_task(4.0 + float(param[1]), "checkKills", killer, param, sizeof(param)) + } + } + + new const CsTeams:team = cs_get_user_team(victim); + + if (EnemyRemaining && CS_TEAM_T <= team <= CS_TEAM_CT && is_user_connected(victim)) + { + new const victimTeammatesCount = get_playersnum_ex(GetPlayers_ExcludeDead | GetPlayers_MatchTeam, g_teamsNames[team]); + + if (victimTeammatesCount) + { + new killerTeammatesList[MAX_PLAYERS], killerTeammatesCount; + get_players_ex(killerTeammatesList, killerTeammatesCount, GetPlayers_ExcludeDead | GetPlayers_MatchTeam, g_teamsNames[CsTeams:(any:team % 2 + 1)]); + + if (killerTeammatesCount) + { + set_hudmessage(255, 255, 255, 0.02, 0.85, 2, 0.05, 0.1, 0.02, 3.0, -1); + + for (new teammate; teammate < killerTeammatesCount; ++teammate) + { + victimTeammatesCount > 1 ? + ShowSyncHudMsg(killerTeammatesList[teammate], g_bottom_sync, "%l", "REMAINING_ENEMIES", victimTeammatesCount) : + ShowSyncHudMsg(killerTeammatesList[teammate], g_bottom_sync, "%l","REMAINING_ENEMY"); + } + } + } + } + + if (LastMan || LastManSound) + { + new cts[MAX_PLAYERS], ts[MAX_PLAYERS], ctsnum, tsnum, b + get_players(cts, ctsnum, "ae", "CT") + get_players(ts, tsnum, "ae", "TERRORIST") + + if( victim_alive ) + { + switch( team ) + { + case CS_TEAM_T: + { + for(b=0; b 1) + { + g_LastAnnounce = cts[0] + oposite = tsnum + _team = CS_TEAM_T + } + else if (tsnum == 1 && ctsnum > 1) + { + g_LastAnnounce = ts[0] + oposite = ctsnum + _team = CS_TEAM_CT + } + + if (g_LastAnnounce) + { + if( LastMan ) + { + new name[MAX_NAME_LENGTH] + + get_user_name(g_LastAnnounce, name, charsmax(name)) + + set_hudmessage(0, 255, 255, -1.0, 0.38, 0, 6.0, 6.0, 0.5, 0.15, -1) + + if( LastManHealth ) + { + ShowSyncHudMsg(0, g_center1_sync, "%s (%d HP) vs. %d %s%s: %L", name, get_user_health(g_LastAnnounce), oposite, g_teamsNames[_team], (oposite == 1) ? "" : "S", LANG_PLAYER, g_LastMessages[random_num(0, 3)]) + } + else + { + ShowSyncHudMsg(0, g_center1_sync, "%s vs. %d %s%s: %L", name, oposite, g_teamsNames[_team], (oposite == 1) ? "" : "S", LANG_PLAYER, g_LastMessages[random_num(0, 3)]) + } + } + + if ( LastManSound && g_connected[g_LastAnnounce] ) + { + play_sound(g_LastAnnounce, g_lastmansound_1vsothers) + } + } + } + } + + if (wpnindex == CSW_KNIFE && (KnifeKill || KnifeKillSound)) + { + if (KnifeKill) + { + new killer_name[MAX_NAME_LENGTH], victim_name[MAX_NAME_LENGTH] + + get_user_name(killer, killer_name, charsmax(killer_name)) + get_user_name(victim, victim_name, charsmax(victim_name)) + + set_hudmessage(255, 100, 100, -1.0, 0.25, 1, 6.0, 6.0, 0.5, 0.15, -1) + ShowSyncHudMsg(0, g_he_sync, "%L", LANG_PLAYER, g_KinfeMsg[random_num(0, 3)], killer_name, victim_name) + } + + if (KnifeKillSound) + play_sound(0, g_knifekillsound) + } + + if (wpnindex == CSW_HEGRENADE) + { + new killer_name[MAX_NAME_LENGTH], victim_name[MAX_NAME_LENGTH] + if( GrenadeKill || GrenadeSuicide ) + { + get_user_name(killer, killer_name, charsmax(killer_name)) + get_user_name(victim, victim_name, charsmax(victim_name)) + + set_hudmessage(255, 100, 100, -1.0, 0.25, 1, 6.0, 6.0, 0.5, 0.15, -1) + } + + if (!selfkill) + { + if (GrenadeKill) + ShowSyncHudMsg(0, g_he_sync, "%L", LANG_PLAYER, g_HeMessages[random_num(0, 3)], killer_name, victim_name) + if (GrenadeKillSound) + play_sound(0, g_grenadekillsound) + } + else + { + if (GrenadeSuicide) + ShowSyncHudMsg(0, g_he_sync, "%L", LANG_PLAYER, g_SHeMessages[random_num(0, 3)], victim_name) + if (GrenadeSuicideSound) + play_sound(0, g_grenadesuicidesound) + } + } + + if (headshot && (HeadShotKill || HeadShotKillSound)) + { + if (HeadShotKill && wpnindex) + { + new killer_name[MAX_NAME_LENGTH], victim_name[MAX_NAME_LENGTH], weapon_name[32], message[256], players[MAX_PLAYERS], pnum, plr + + xmod_get_wpnname(wpnindex, weapon_name, charsmax(weapon_name)) + get_user_name(killer, killer_name, charsmax(killer_name)) + get_user_name(victim, victim_name, charsmax(victim_name)) + get_players(players, pnum, "ch") + + for (new i = 0; i < pnum; i++) + { + plr = players[i] + formatex(message, charsmax(message), "%L", plr, g_HeadShots[random_num(0, 6)]) + + replace(message, charsmax(message), "$vn", victim_name) + replace(message, charsmax(message), "$wn", weapon_name) + replace(message, charsmax(message), "$kn", killer_name) + + set_hudmessage(100, 100, 255, -1.0, 0.30, 0, 6.0, 6.0, 0.5, 0.15, -1) + ShowSyncHudMsg(plr, g_announce_sync, "%s", message) + } + } + + if (HeadShotKillSound) + { + play_sound(victim, g_hssound_victim) + if( victim != killer ) + play_sound(killer, g_hssound_killer) + } + } + + if ((DoubleKill || DoubleKillSound) && !selfkill) + { + new Float:nowtime = get_gametime() + + if (g_doubleKill == nowtime && g_doubleKillId == killer) + { + if (DoubleKill) + { + new name[MAX_NAME_LENGTH] + + get_user_name(killer, name, charsmax(name)) + + set_hudmessage(255, 0, 255, -1.0, 0.35, 0, 6.0, 6.0, 0.5, 0.15, -1) + ShowSyncHudMsg(0, g_center1_sync, "%L", LANG_PLAYER, "DOUBLE_KILL", name) + } + + if (DoubleKillSound) + play_sound(0, g_doublekillsound) + } + + g_doubleKill = nowtime + g_doubleKillId = killer + } +} + +public hideStatus(id) +{ + if (PlayerName) + { + ClearSyncHud(id, g_status_sync) + } +} + +public setTeam(id) + g_friend[id] = read_data(2) + +public showStatus(id) +{ + if( PlayerName) + { + new name[MAX_NAME_LENGTH], pid = read_data(2) + + get_user_name(pid, name, charsmax(name)) + new color1 = 0, color2 = 0 + + if (cs_get_user_team(pid) == CS_TEAM_T) + color1 = 255 + else + color2 = 255 + + if (g_friend[id] == 1) // friend + { + new wpnid = get_user_weapon(pid) + new wpnname[32] + + if (wpnid) + xmod_get_wpnname(wpnid, wpnname, charsmax(wpnname)) + + set_hudmessage(color1, 50, color2, -1.0, 0.60, 1, 0.01, 3.0, 0.01, 0.01, -1) + ShowSyncHudMsg(id, g_status_sync, "%s -- %d HP / %d AP / %s", name, get_user_health(pid), get_user_armor(pid), wpnname) + } else { + set_hudmessage(color1, 50, color2, -1.0, 0.60, 1, 0.01, 3.0, 0.01, 0.01, -1) + ShowSyncHudMsg(id, g_status_sync, "%s", name) + } + } +} + +public Event_HLTV_New_Round() +{ + g_c4timer_value = get_pcvar_num( g_pcvar_mp_c4timer ) + ++g_roundCount + g_firstBlood = 1 + g_C4Timer = 0 + + if (RoundCounterSound) + play_sound(0, g_roundcountersound) + + if (RoundCounter) + { + set_task(0.2, "Delayed_New_Round", TASK_DELAYED_NEW_ROUND) + } +} + +public Delayed_New_Round() +{ + set_hudmessage(200, 0, 0, -1.0, 0.30, 0, 6.0, 6.0, 0.5, 0.15, -1) + ShowSyncHudMsg(0, g_announce_sync, "%L", LANG_PLAYER, "PREPARE_FIGHT", g_roundCount) +} + +public LogEvent_Round_Start() +{ + if (KillingStreak) + { + new appl[MAX_PLAYERS], ppl, i + get_players(appl, ppl, "ac") + + for (new a = 0; a < ppl; ++a) + { + i = appl[a] + + if (g_streakKills[i][0] >= 2) + client_print(i, print_chat, "* %L", i, "KILLED_ROW", g_streakKills[i][0]) + else if (g_streakKills[i][1] >= 2) + client_print(i, print_chat, "* %L", i, "DIED_ROUNDS", g_streakKills[i][1]) + } + } +} + +public eRestart() +{ + eEndRound() + g_roundCount = 0 + g_firstBlood = 1 +} + +public eEndRound() +{ + g_C4Timer = -2 + g_LastOmg = 0.0 + remove_task(TASK_BOMB_TIMER) + g_LastAnnounce = 0 +} + +public checkKills(param[]) +{ + new id = param[0] + new a = param[1] + + if (a == g_multiKills[id][0]) + { + a -= 3 + + if (a > -1) + { + if (a > 6) + { + a = 6 + } + + if (MultiKill) + { + new name[MAX_NAME_LENGTH] + + get_user_name(id, name, charsmax(name)) + set_hudmessage(255, 0, 100, 0.05, 0.50, 2, 0.02, 6.0, 0.01, 0.1, -1) + + ShowSyncHudMsg(0, g_left_sync, g_MultiKillMsg[a], name, LANG_PLAYER, "WITH", g_multiKills[id][0], LANG_PLAYER, "KILLS", g_multiKills[id][1], LANG_PLAYER, "HS") + } + + if (MultiKillSound) + { + play_sound(0, g_Sounds[a]) + } + } + g_multiKills[id] = {0, 0} + } +} + +public chickenKill() +{ + if (ItalyBonusKill) + announceEvent(0, "KILLED_CHICKEN") +} + +public radioKill() +{ + if (ItalyBonusKill) + announceEvent(0, "BLEW_RADIO") +} + +announceEvent(id, message[]) +{ + new name[MAX_NAME_LENGTH] + + get_user_name(id, name, charsmax(name)) + set_hudmessage(255, 100, 50, -1.0, 0.30, 0, 6.0, 6.0, 0.5, 0.15, -1) + ShowSyncHudMsg(0, g_announce_sync, "%L", LANG_PLAYER, message, name) +} + +public eBombPickUp(id) +{ + if (BombPickUp) + announceEvent(id, "PICKED_BOMB") +} + +public eBombDrop() +{ + if (BombDrop) + announceEvent(g_Planter, "DROPPED_BOMB") +} + +public eGotBomb(id) +{ + g_Planter = id + + if (BombReached && read_data(1) == 2 && g_LastOmg < get_gametime()) + { + g_LastOmg = get_gametime() + 15.0 + announceEvent(g_Planter, "REACHED_TARGET") + } +} + +public bombTimer() +{ + if (--g_C4Timer > 0) + { + if( BombCountHUD ) + { + new r, g + if( g_C4Timer < 10 ) + { + r = 255, g = 0 + } + else + { + r = (((max(g_c4timer_value - g_C4Timer - 10,0)) * 255000) / (g_c4timer_value - 10)) / 1000 + g = 255 - r + } + + set_hudmessage(r, g, 0, -1.0, 0.75, g_C4Timer <= 10 ? 1 : 0, 0.01, 1.1, 0.001, 0.001, .channel = -1) + show_hudmessage(0, "C4: %ds", g_C4Timer) + } + if (BombCountVoice) + { + if (g_C4Timer == 30 || g_C4Timer == 20) + { + new temp[64] + + num_to_word(g_C4Timer, temp, charsmax(temp)) + format(temp, charsmax(temp), "^"vox/%s seconds until explosion^"", temp) + play_sound(0, temp) + } + else if (g_C4Timer < 11) + { + new temp[64] + + num_to_word(g_C4Timer, temp, charsmax(temp)) + format(temp, charsmax(temp), "^"vox/%s^"", temp) + play_sound(0, temp) + } + } + if (BombCountDef && g_Defusing && is_user_alive(g_Defusing)) + client_print(g_Defusing, print_center, "%d", g_C4Timer) + } + else + remove_task(TASK_BOMB_TIMER) +} + +public eStopDefuse(id) +{ + if( id == g_Defusing ) + { + g_Defusing = 0 + } +} + +public bomb_planted(planter) +{ + g_Defusing = 0 + + if (BombPlanted) + announceEvent(planter, "SET_UP_BOMB") + + if (BombPlantedSound) + play_sound(0, g_bombplantedsound) + + g_C4Timer = g_c4timer_value + 1 + bombTimer() + set_task(1.0, "bombTimer", TASK_BOMB_TIMER, "", 0, "b") +} + +public bomb_planting(planter) +{ + if (BombPlanting) + announceEvent(planter, "PLANT_BOMB") +} + +public bomb_defusing(defuser) +{ + if (BombDefusing) + announceEvent(defuser, "DEFUSING_BOMB") + + g_Defusing = defuser +} + +public bomb_defused(defuser) +{ + if (BombDefused) + announceEvent(defuser, "DEFUSED_BOMB") + if (BombDefusedSound) + play_sound(0, g_bombdefusedsound) +} + +public bomb_explode(planter, defuser) +{ + if( defuser ) + { + if (BombFailed) + announceEvent(defuser, "FAILED_DEFU") + if (BombFailedSound) + play_sound(0, g_bombfailedsound) + } +} + +play_sound(id, sound[]) +{ + if( id ) + { + if( g_msounds[id] ) + { + client_cmd(id, "spk %s", sound) + } + } + else + { + new players[MAX_PLAYERS], pnum, id + get_players(players, pnum, "ch") + + for(--pnum; pnum>=0; pnum--) + { + id = players[pnum] + if ( g_connected[id] && g_msounds[id] ) + client_cmd(id, "spk %s", sound) + } + } +} + +public cmdSwitchSounds( id ) +{ + g_msounds[id] = !g_msounds[id] + client_print(id, print_chat, "MSounds %L", id, g_msounds[id] ? "ENABLED" : "DISABLED") + set_user_info(id, _msound, g_msounds[id] ? "1" : "0") // will this save setting for next map is player has cl_filterstuffcmd 0 ??? + client_cmd(id, "setinfo %s %s", _msound, g_msounds[id] ? "1" : "0") +} diff --git a/amxmodx/scripting/mpbhop.sma b/amxmodx/scripting/mpbhop.sma new file mode 100644 index 0000000..3377b30 --- /dev/null +++ b/amxmodx/scripting/mpbhop.sma @@ -0,0 +1,896 @@ +/* Copyright � 2008, ConnorMcLeod + + func_door is free software; + you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with func_door; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#define CHATCOLOR +#define MAKE_DOORS_SILENT + +#include +#include +#include +#include +#include +#include + +new const VERSION[] = "1.1.2"; + +#pragma semicolon 1 + +#define SetIdBits(%1,%2) %1 |= 1<<(%2 & 31) +#define ClearIdBits(%1,%2) %1 &= ~( 1<<(%2 & 31) ) +#define GetIdBits(%1,%2) %1 & 1<<(%2 & 31) + +#define SetEntBits(%1,%2) %1[%2>>5] |= 1<<(%2 & 31) +#define ClearEntBits(%1,%2) %1[%2>>5] &= ~( 1 << (%2 & 31) ) +#define GetEntBits(%1,%2) %1[%2>>5] & 1<<(%2 & 31) + +enum _:BlocksClasses { + FUNC_DOOR, + FUNC_WALL_TOGGLE, + FUNC_BUTTON, + TRIGGER_MULTIPLE +} + +new const Float:VEC_DUCK_HULL_MIN[3] = {-16.0, -16.0, -18.0 }; +new const Float:VEC_DUCK_HULL_MAX[3] = { 16.0, 16.0, 32.0 }; +new const Float:VEC_DUCK_VIEW[3] = { 0.0, 0.0, 12.0 }; + +new const Float:VEC_NULL[3] = { 0.0, 0.0, 0.0 }; + +const PLAYERS_ARRAY_SIZE = 33; +const MAX_ENTSARRAYS_SIZE = 64; // x * 32 // 2048 (should be 1800 on default servers settings) + +new g_bitPresentClass; + +const KEYS = ((1<<0)|(1<<1)|(1<<9)); + +new g_iBlock[ PLAYERS_ARRAY_SIZE ]; +new Float:g_flFirstTouch[ PLAYERS_ARRAY_SIZE ]; + +new Float:g_flJumpOrigin[ PLAYERS_ARRAY_SIZE ][3]; +new Float:g_flJumpAngles[ PLAYERS_ARRAY_SIZE ][3]; +new Float:g_flJumpGravity[ PLAYERS_ARRAY_SIZE ]; + +new g_bBlocks[MAX_ENTSARRAYS_SIZE], g_bBlocksByPlugin[MAX_ENTSARRAYS_SIZE]; +new g_bOnGround, g_bTeleported, g_bAdmin; + +new bool:g_bBlockEntityTouch; +new bool:g_bActive; +new bool:g_bSafeInform = true; + +new g_iFhAddToFullPack; +new g_iAdminDoor[PLAYERS_ARRAY_SIZE]; +new szConfigFile[64]; + +new Trie:g_iBlocksClass; + +new g_iMaxPlayers, g_iMaxEnts; +#define IsPlayer(%1) ( 1 <= %1 <= g_iMaxPlayers ) + +public plugin_init() { + register_plugin("MultiPlayer Bhop", VERSION, "ConnorMcLeod"); + new pCvar = register_cvar("mp_bhop_version", VERSION, FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_SPONLY); + set_pcvar_string(pCvar, VERSION); + + new const szPossibleBlockClass[][] = {"func_door", "func_wall_toggle", "func_button", "trigger_multiple"}; + g_iBlocksClass = TrieCreate(); + for(new i; i set blocks so they can't move when players touch them"); + register_concmd("kz_mpbhop_entitytouch", "ConCmd_EntityTouch", ADMIN_CFG, "<0/1> set blocks so they can't move when other entities than players touch them"); + register_concmd("kz_safe_inform", "ClCmd_SafeInform", ADMIN_CFG, "<0/1> Inform recorders that their demo will be safe or not safe according to plugin state"); + + register_clcmd("kz_mpbhopmenu", "ClCmd_BhopMenu", ADMIN_CFG); + register_clcmd("kz_showblocks", "ClCmd_ShowBlocks", ADMIN_CFG); + + register_clcmd("fullupdate", "ClCmd_FullUpdate"); + + register_menucmd(register_menuid("MpBhop Menu"), KEYS ,"MpBhopMenuAction"); + + g_iMaxPlayers = get_maxplayers(); + g_iMaxEnts = global_get(glb_maxEntities); + + new iCount; + + iCount += Set_Doors(); + iCount += Set_Wall_Toggle(); + iCount += Set_Buttons(); + + iCount += SetBlocksByFile(); + + server_print("[MPBHOP] %d bhop blocks detected", iCount); + + SetTriggerMultiple(); +} + +public plugin_cfg() { + new szConfigPath[96]; + get_localinfo("amxx_configsdir", szConfigPath, charsmax(szConfigPath)); + format(szConfigPath, charsmax(szConfigPath), "%s/mpbhop.cfg", szConfigPath); + + if(file_exists(szConfigPath)) { + new buffer[2], n; + read_file(szConfigPath, 0, buffer, charsmax(buffer), n); + if(buffer[0] == ';') + goto ForceWrite; + server_cmd("exec %s", szConfigPath); + server_exec(); + } + else { +ForceWrite: + new fp = fopen(szConfigPath, "wt"); + if(!fp) + return; + new szPluginFileName[96], szPluginName[64], szAuthor[32], szVersion[32], szStatus[2]; + new iPlugin = get_plugin(-1, + szPluginFileName, charsmax(szPluginFileName), + szPluginName, charsmax(szPluginName), + szVersion, charsmax(szVersion), + szAuthor, charsmax(szAuthor), + szStatus, charsmax(szStatus) ); + + // server_print("Plugin id is %d", iPlugin); + fprintf(fp, "// ^"%s^" configuration file^n", szPluginName); + fprintf(fp, "// Author : ^"%s^"^n", szAuthor); + fprintf(fp, "// Version : ^"%s^"^n", szVersion); + fprintf(fp, "// File : ^"%s^"^n", szPluginFileName); + + new iMax, i, szCommand[64], iCommandAccess, szCmdInfo[128], szFlags[32]; + iMax = get_concmdsnum(-1, -1); + fprintf(fp, "^n// Console Commands :^n"); + for(i=0; i 0.25 ) // 0.3 == exploit on cg_cbblebhop oO + { + if( flTime - g_flFirstTouch[id] > 0.7 ) + { + g_flFirstTouch[id] = flTime; + return HAM_SUPERCEDE; + } + + Util_TeleportPlayerBack( id ); + } + return HAM_SUPERCEDE; +} + +Util_TeleportPlayerBack(id) +{ + SetIdBits(g_bTeleported, id); // apply null velocity on next PreThink() + + new flags = pev(id, pev_flags); + if( flags & FL_BASEVELOCITY ) + { + flags &= ~FL_BASEVELOCITY; + set_pev(id, pev_basevelocity, VEC_NULL); + } + set_pev(id, pev_velocity, VEC_NULL); + + set_pev(id, pev_flags, flags | FL_DUCKING); + + engfunc(EngFunc_SetSize, id, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX); + engfunc(EngFunc_SetOrigin, id, g_flJumpOrigin[id]); + set_pev(id, pev_view_ofs, VEC_DUCK_VIEW); + + set_pev(id, pev_v_angle, VEC_NULL); + set_pev(id, pev_angles, g_flJumpAngles[id]); + set_pev(id, pev_punchangle, VEC_NULL); + set_pev(id, pev_fixangle, 1); + + set_pev(id, pev_gravity, g_flJumpGravity[id]); + + set_pev(id, pev_fuser2, 0.0); +} + +public ConCmd_MpBhop(id, lvl, cid) +{ + if( cmd_access(id, lvl, cid, 2) ) + { + new szStatus[2]; + read_argv(1, szStatus, charsmax(szStatus)); + static HamHook:iHhPlayerPreThink; + switch( szStatus[0] ) + { + case '0': + { + if( !g_bActive ) + { + return PLUGIN_HANDLED; + } + if( iHhPlayerPreThink ) + { + DisableHamForward( iHhPlayerPreThink ); + } + SetTouch( false ); + g_bActive = false; + + if( g_bSafeInform ) + { + client_print(0, print_console, "MpBhop has been De-Activated, recording is now SAFE"); +#if defined CHATCOLOR + client_print_color(0, print_chat, "^1 * ^4[MpBhop] ^1MpBhop has been ^3De-Activated^1, recording is now ^4SAFE"); +#else + client_print(id, print_chat, " * [MpBhop] MpBhop has been De-Activated, recording is now SAFE"); +#endif + } + } + case '1': + { + if( g_bActive ) + { + return PLUGIN_HANDLED; + } + if( !iHhPlayerPreThink ) + { + RegisterHam(Ham_Player_PreThink, "player", "CBasePlayer_PreThink"); + } + else + { + EnableHamForward( iHhPlayerPreThink ); + } + SetTouch( true ); + g_bActive = true; + if( g_bSafeInform ) + { + client_print(0, print_console, "MpBhop has been Activated, recording is now NOT SAFE"); +#if defined CHATCOLOR + client_print_color(0, print_chat, "^1 * ^4[MpBhop] ^1MpBhop has been ^4Activated^1, recording is now ^3NOT SAFE"); +#else + client_print(id, print_chat, " * MpBhop has been Activated, recording is now NOT SAFE"); +#endif + } + } + default: + { + client_print(id, print_console, "Usage: kz_mpbhop <0/1>"); + } + } + } + return PLUGIN_HANDLED; +} + +public ConCmd_EntityTouch(id, lvl, cid) +{ + if( cmd_access(id, lvl, cid, 2) ) + { + new szStatus[2]; + read_argv(1, szStatus, charsmax(szStatus)); + g_bBlockEntityTouch = !!str_to_num(szStatus); + } + return PLUGIN_HANDLED; +} + +Set_Doors() +{ + new iDoor = FM_NULLENT, i; + new Float:flMovedir[3], szNoise[32], Float:flSize[3], Float:flDmg, Float:flSpeed; + new const szNull[] = "common/null.wav"; + while( (iDoor = find_ent_by_class( iDoor, "func_door")) ) + { + // definitly not a bhop block + pev(iDoor, pev_dmg, flDmg); + if( flDmg ) + { +#if defined MAKE_DOORS_SILENT + set_pev(iDoor, pev_noise1, szNull); // while here, set healing doors silent xD + set_pev(iDoor, pev_noise2, szNull); + set_pev(iDoor, pev_noise3, szNull); +#endif + continue; + } + + // this func_door goes UP, not a bhop block ? + // or bhop block but let them move up (kz_megabhop for example) + pev(iDoor, pev_movedir, flMovedir); + if( flMovedir[2] > 0.0 ) + { + continue; + } + + // too small : real door ? could this one be skipped ? + pev(iDoor, pev_size, flSize); + if( ( flSize[0] < 24.0 && flSize[1] > 50.0 ) + ||( flSize[1] < 24.0 && flSize[0] > 50.0 ) ) + { + continue; + } + + // real door ? not all doors make sound though... + pev(iDoor, pev_noise1, szNoise, charsmax(szNoise)); + if( szNoise[0] && !equal(szNoise, szNull) ) + { + continue; + } + pev(iDoor, pev_noise2, szNoise, charsmax(szNoise)); + if( szNoise[0] && !equal(szNoise, szNull) ) + { + continue; + } + + // not a bhop block ? too slow // this at least detects the big ent on kzsca_sewerbhop + pev(iDoor, pev_speed, flSpeed); + if( flSpeed < 80.0 ) + { + continue; + } + + // Pray for this to be a bhop block + SetEntBits(g_bBlocksByPlugin, iDoor); + SetEntBits(g_bBlocks, iDoor); + g_bitPresentClass |= 1< +#include + +new g_menuLang[MAX_PLAYERS + 1] +new g_langNum +new g_coloredMenus + +new g_cvarDisplayClientMessage; +new g_cvarClientLanguages; +new g_cvarServerLanguage; + +public plugin_init() +{ + register_plugin("Multi-Lingual System", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("multilingual.txt") + register_dictionary("common.txt") + register_dictionary("languages.txt") + + g_cvarDisplayClientMessage = register_cvar("amx_language_display_msg", "1") + g_cvarClientLanguages = get_cvar_pointer("amx_client_languages") + g_cvarServerLanguage = get_cvar_pointer("amx_language"); + + register_clcmd("amx_langmenu", "cmdLangMenu", ADMIN_ALL) + register_menu("Language Menu", 1023, "actionMenu") + + g_langNum = get_langsnum() + g_coloredMenus = colored_menus() +} + +public client_putinserver(id) +{ + if (get_pcvar_num(g_cvarDisplayClientMessage) && get_pcvar_num(g_cvarClientLanguages) && !is_user_bot(id)) + { + set_task(10.0, "dispInfo", id) + } +} + +public client_disconnected(id) +{ + remove_task(id) +} + +public dispInfo(id) +{ + client_print(id, print_chat, "%L", id, "TYPE_LANGMENU") +} + +public cmdLangMenu(id, level, cid) +{ + if (!get_pcvar_num(g_cvarClientLanguages)) + { + client_print(id, print_console, "[AMXX] %L", LANG_SERVER, "LANG_MENU_DISABLED") + return PLUGIN_HANDLED + } + + new buffer[3] + get_user_info(id, "lang", buffer, charsmax(buffer)) + + if (buffer[0] == EOS) // if "lang" is not defined, by default it will use server language. + { + get_pcvar_string(g_cvarServerLanguage, buffer, charsmax(buffer)); + } + + g_menuLang[id] = get_lang_id(buffer) + + showMenu(id) + + return PLUGIN_HANDLED +} + +showMenu(id) +{ + if (!get_pcvar_num(g_cvarClientLanguages)) + { + return + } + + new menuBody[512], pLang[3] + + get_lang(g_menuLang[id], pLang) + + new len = formatex(menuBody, charsmax(menuBody), (g_coloredMenus ? "\y%L\w^n^n" : "%L^n^n"), id, "LANG_MENU") + + len += formatex(menuBody[len], charsmax(menuBody) - len, (g_coloredMenus ? "1. %L\R\r%L\w^n" : "1. %L %L^n"), id, "PERSO_LANG", pLang, "LANG_NAME") + len += formatex(menuBody[len], charsmax(menuBody) - len, "^n2. %L", id, "SAVE_LANG") + formatex(menuBody[len], charsmax(menuBody) - len, "^n^n0. %L", id, "EXIT") + + show_menu(id, MENU_KEY_0|MENU_KEY_1|MENU_KEY_2, menuBody, -1, "Language Menu") +} + +public actionMenu(id, key) +{ + if (!get_pcvar_num(g_cvarClientLanguages)) + { + return 0 + } + + if (key == 0) + { + if (g_menuLang[id] < (g_langNum - 1)) + { + g_menuLang[id]++ + } + else + { + g_menuLang[id] = 0 + } + + showMenu(id) + } + else if(key == 1) + { + new pLang[3], pLang_old[3] + + get_lang(g_menuLang[id], pLang) + get_user_info(id, "lang", pLang_old, charsmax(pLang_old)) + + if (!equali(pLang, pLang_old)) + { + client_cmd(id, "setinfo ^"lang^" ^"%s^"", pLang) + set_user_info(id, "lang", pLang); // In case setinfo breaks (slowhacking and all), this will at least be a fallback while the user is connect + + new lName[64] + formatex(lName, charsmax(lName), "%L", pLang, "LANG_NAME") + client_print(id, print_chat, "%L", pLang, "SET_LANG_USER", lName) + } + } + + return 0 +} + +get_lang_id(lang[]) +{ + new tLang[3] + + for (new i = 0; i < g_langNum; i++) + { + get_lang(i, tLang) + + if (equali(tLang, lang)) + { + return i + } + } + + return 0 +} diff --git a/amxmodx/scripting/nextmap.sma b/amxmodx/scripting/nextmap.sma new file mode 100755 index 0000000..bdb318e --- /dev/null +++ b/amxmodx/scripting/nextmap.sma @@ -0,0 +1,231 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// NextMap Plugin +// + +#include + +// WARNING: If you comment this line make sure +// that in your mapcycle file maps don't repeat. +// However the same map in a row is still valid. +#define OBEY_MAPCYCLE + +new g_nextMap[32] +new g_mapCycle[32] +new g_pos +new g_currentMap[32] + +// pcvars +new g_mp_friendlyfire, g_mp_chattime +new g_amx_nextmap + +public plugin_init() +{ + register_plugin("NextMap", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("nextmap.txt") + register_event("30", "changeMap", "a") + register_clcmd("say nextmap", "sayNextMap", 0, "- displays nextmap") + register_clcmd("say currentmap", "sayCurrentMap", 0, "- display current map") + + g_amx_nextmap = register_cvar("amx_nextmap", "", FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_SPONLY) + g_mp_chattime = get_cvar_pointer("mp_chattime") + g_mp_friendlyfire = get_cvar_pointer("mp_friendlyfire") + if( g_mp_friendlyfire ) + { + register_clcmd("say ff", "sayFFStatus", 0, "- display friendly fire status") + } + + get_mapname(g_currentMap, charsmax(g_currentMap)) + + new szString[40], szString2[32], szString3[8] + + get_localinfo("lastmapcycle", szString, charsmax(szString)) + parse(szString, szString2, charsmax(szString2), szString3, charsmax(szString3)) + + get_cvar_string("mapcyclefile", g_mapCycle, charsmax(g_mapCycle)) + + if (!equal(g_mapCycle, szString2)) + g_pos = 0 // mapcyclefile has been changed - go from first + else + g_pos = str_to_num(szString3) + + readMapCycle(g_mapCycle, g_nextMap, charsmax(g_nextMap)) + set_pcvar_string(g_amx_nextmap, g_nextMap) + formatex(szString, charsmax(szString), "%s %d", g_mapCycle, g_pos) // save lastmapcycle settings + set_localinfo("lastmapcycle", szString) +} + +getNextMapName(szArg[], iMax) +{ + new len = get_pcvar_string(g_amx_nextmap, szArg, iMax) + + if (ValidMap(szArg)) return len + len = copy(szArg, iMax, g_nextMap) + set_pcvar_string(g_amx_nextmap, g_nextMap) + + return len +} + +public sayNextMap() +{ + new name[32] + + getNextMapName(name, charsmax(name)) + client_print(0, print_chat, "%L %s", LANG_PLAYER, "NEXT_MAP", name) +} + +public sayCurrentMap() +{ + client_print(0, print_chat, "%L: %s", LANG_PLAYER, "PLAYED_MAP", g_currentMap) +} + +public sayFFStatus() +{ + client_print(0, print_chat, "%L: %L", LANG_PLAYER, "FRIEND_FIRE", LANG_PLAYER, get_pcvar_num(g_mp_friendlyfire) ? "ON" : "OFF") +} + +public delayedChange(param[]) +{ + if (g_mp_chattime) { + set_pcvar_float(g_mp_chattime, get_pcvar_float(g_mp_chattime) - 2.0) + } + engine_changelevel(param) +} + +public changeMap() +{ + new string[32] + new Float:chattime = g_mp_chattime ? get_pcvar_float(g_mp_chattime) : 10.0; // mp_chattime defaults to 10 in other mods + + if (g_mp_chattime) { + set_pcvar_float(g_mp_chattime, chattime + 2.0) // make sure mp_chattime is long + } + new len = getNextMapName(string, charsmax(string)) + 1 + set_task(chattime, "delayedChange", 0, string, len) // change with 1.5 sec. delay +} + +new g_warning[] = "WARNING: Couldn't find a valid map or the file doesn't exist (file ^"%s^")" + +stock bool:ValidMap(mapname[]) +{ + if ( is_map_valid(mapname) ) + { + return true; + } + // If the is_map_valid check failed, check the end of the string + new len = strlen(mapname) - 4; + + // The mapname was too short to possibly house the .bsp extension + if (len < 0) + { + return false; + } + if ( equali(mapname[len], ".bsp") ) + { + // If the ending was .bsp, then cut it off. + // the string is byref'ed, so this copies back to the loaded text. + mapname[len] = '^0'; + + // recheck + if ( is_map_valid(mapname) ) + { + return true; + } + } + + return false; +} + +#if defined OBEY_MAPCYCLE +readMapCycle(szFileName[], szNext[], iNext) +{ + new b, i = 0, iMaps = 0 + new szBuffer[32], szFirst[32] + + if (file_exists(szFileName)) + { + while (read_file(szFileName, i++, szBuffer, charsmax(szBuffer), b)) + { + if (!isalnum(szBuffer[0]) || !ValidMap(szBuffer)) continue + + if (!iMaps) + copy(szFirst, charsmax(szFirst), szBuffer) + + if (++iMaps > g_pos) + { + copy(szNext, iNext, szBuffer) + g_pos = iMaps + return + } + } + } + + if (!iMaps) + { + log_amx(g_warning, szFileName) + copy(szNext, iNext, g_currentMap) + } + else + copy(szNext, iNext, szFirst) + g_pos = 1 +} + +#else + +readMapCycle(szFileName[], szNext[], iNext) +{ + new b, i = 0, iMaps = 0 + new szBuffer[32], szFirst[32] + + new a = g_pos + + if (file_exists(szFileName)) + { + while (read_file(szFileName, i++, szBuffer, charsmax(szBuffer), b)) + { + if (!isalnum(szBuffer[0]) || !ValidMap(szBuffer)) continue + + if (!iMaps) + { + iMaps = 1 + copy(szFirst, charsmax(szFirst), szBuffer) + } + + if (iMaps == 1) + { + if (equali(g_currentMap, szBuffer)) + { + if (a-- == 0) + iMaps = 2 + } + } else { + if (equali(g_currentMap, szBuffer)) + ++g_pos + else + g_pos = 0 + + copy(szNext, iNext, szBuffer) + return + } + } + } + + if (!iMaps) + { + log_amx(g_warning, szFileName) + copy(szNext, iNext, g_currentMap) + } + else + copy(szNext, iNext, szFirst) + + g_pos = 0 +} +#endif diff --git a/amxmodx/scripting/pausecfg.sma b/amxmodx/scripting/pausecfg.sma new file mode 100755 index 0000000..db4d016 --- /dev/null +++ b/amxmodx/scripting/pausecfg.sma @@ -0,0 +1,530 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Pause Plugins Plugin +// + +#include +#include + +// Uncomment if you want to have two new commands +// amx_off - pause plugins not marked as unpauseable +// amx_on - enable plugins not marked as unpauseable +#define DIRECT_ONOFF + +#define MAX_SYSTEM 32 + +new g_menuPos[MAX_PLAYERS + 1] +new g_fileToSave[64] +new g_coloredMenus +new g_Modified +new g_addCmd[] = "amx_pausecfg add ^"%s^"" +new g_system[MAX_SYSTEM] +new g_systemNum + +public plugin_init() +{ + register_plugin("Pause Plugins", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("pausecfg.txt") + register_dictionary("common.txt") + register_dictionary("admincmd.txt") + + register_concmd("amx_pausecfg", "cmdPlugin", ADMIN_CFG, "- list commands for pause/unpause management") + register_clcmd("amx_pausecfgmenu", "cmdMenu", ADMIN_CFG, "- pause/unpause plugins with menu") +#if defined DIRECT_ONOFF + register_concmd("amx_off", "cmdOFF", ADMIN_CFG, "- pauses some plugins") + register_concmd("amx_on", "cmdON", ADMIN_CFG, "- unpauses some plugins") +#endif + register_menucmd(register_menuid("Pause/Unpause Plugins"), 1023, "actionMenu") + + g_coloredMenus = colored_menus() + get_configsdir(g_fileToSave, charsmax(g_fileToSave)); + format(g_fileToSave, charsmax(g_fileToSave), "%s/pausecfg.ini", g_fileToSave); + + return PLUGIN_CONTINUE +} + +#if defined DIRECT_ONOFF +public cmdOFF(id, level, cid) +{ + if (cmd_access(id, level, cid, 1)) + pausePlugins(id) + + return PLUGIN_HANDLED +} + +public cmdON(id, level, cid) +{ + if (cmd_access(id, level, cid, 1)) + unpausePlugins(id) + + return PLUGIN_HANDLED +} +#endif + +public plugin_cfg() +{ + loadSettings(g_fileToSave) + + // Put here titles of plugins which you don't want to pause + server_cmd(g_addCmd, "Admin Base") + server_cmd(g_addCmd, "Admin Base (SQL)") + server_cmd(g_addCmd, "Pause Plugins") + server_cmd(g_addCmd, "TimeLeft") + server_cmd(g_addCmd, "NextMap") + server_cmd(g_addCmd, "Slots Reservation") +} + +public actionMenu(id, key) +{ + switch (key) + { + case 6: + { + if (file_exists(g_fileToSave)) + { + delete_file(g_fileToSave) + client_print(id, print_chat, "* %L", id, "PAUSE_CONF_CLEARED") + } + else + client_print(id, print_chat, "* %L", id, "PAUSE_ALR_CLEARED") + + displayMenu(id, g_menuPos[id]) + } + case 7: + { + if (saveSettings(g_fileToSave)) + { + g_Modified = 0 + client_print(id, print_chat, "* %L", id, "PAUSE_CONF_SAVED") + } + else + client_print(id, print_chat, "* %L", id, "PAUSE_SAVE_FAILED") + + displayMenu(id, g_menuPos[id]) + } + case 8: displayMenu(id, ++g_menuPos[id]) + case 9: displayMenu(id, --g_menuPos[id]) + default: + { + new option = g_menuPos[id] * 6 + key + new file[32], status[2] + + get_plugin(option, file, charsmax(file), status, 0, status, 0, status, 0, status, 1) + + switch (status[0]) + { + // "running" + case 'r': pause("ac", file) + + // "debug" + case 'd': pause("ac", file) + + // "paused" + case 'p': + { + g_Modified = 1 + unpause("ac", file) + } + + // "stopped" + case 's': + { + client_print(id, print_chat, "%L", id, "CANT_UNPAUSE_PLUGIN", file); + } + } + + displayMenu(id, g_menuPos[id]) + } + } + + return PLUGIN_HANDLED +} + +getStatus(id, code, &statusCode, lStatus[], lLen) +{ + switch (code) + { + // "running" + case 'r': + { + statusCode = 'O' + format(lStatus, lLen, "%L", id, "ON") + } + + // "debug" + case 'd': + { + statusCode = 'O' + format(lStatus, lLen, "%L", id, "ON") + } + + // "stopped" + case 's': + { + statusCode = 'S' + format(lStatus, lLen, "%L", id, "STOPPED") + } + + // "paused" + case 'p': + { + statusCode = 'O' + format(lStatus, lLen, "%L", id, "OFF") + } + + // "bad load" + case 'b': + { + statusCode = 'E' + format(lStatus, lLen, "%L", id, "ERROR") + } + default: + { + statusCode = 'L' + format(lStatus, lLen, "%L", id, "LOCKED") + } + } +} + +isSystem(id) +{ + for (new a = 0; a < g_systemNum; ++a) + if (g_system[a] == id) + return 1 + return 0 +} + +displayMenu(id, pos) +{ + if (pos < 0) return + + new filename[32], title[32], status[8], statusCode + new datanum = get_pluginsnum() + new menu_body[512], start = pos * 6, k = 0 + + if (start >= datanum) + start = pos = g_menuPos[id] = 0 + + new len = format(menu_body, charsmax(menu_body), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "PAUSE_UNPAUSE", pos + 1, ((datanum / 6) + ((datanum % 6) ? 1 : 0))) + new end = start + 6, keys = MENU_KEY_0|MENU_KEY_8|MENU_KEY_7 + + if (end > datanum) + end = datanum + + for (new a = start; a < end; ++a) + { + get_plugin(a, filename, charsmax(filename), title, charsmax(title), status, 0, status, 0, status, charsmax(status)) + getStatus(id, status[0], statusCode, status, charsmax(status)) + + if (isSystem(a) || (statusCode != 'O' && statusCode != 'S')) + { + if (g_coloredMenus) + { + len += format(menu_body[len], charsmax(menu_body) - len, "\d%d. %s\R%s^n\w", ++k, title, status) + } else { + ++k + len += format(menu_body[len], charsmax(menu_body) - len, "#. %s %s^n", title, status) + } + } else { + keys |= (1< 2) + { + read_argv(2, cmds, charsmax(cmds)) + new file[2] + + if ((g_system[g_systemNum] = findPluginByTitle(cmds, file, 0)) != -1) + { + if (g_systemNum < MAX_SYSTEM) + g_systemNum++ + else + console_print(id, "%L", id, "CANT_MARK_MORE") + } + } + else if (equal(cmds, "off")) + { + pausePlugins(id) + } + else if (equal(cmds, "on")) + { + unpausePlugins(id) + } + else if (equal(cmds, "save")) + { + if (saveSettings(g_fileToSave)) + { + g_Modified = 0 + console_print(id, "%L", id, "PAUSE_CONF_SAVED") + } + else + console_print(id, "%L", id, "PAUSE_SAVE_FAILED") + } + else if (equal(cmds, "clear")) + { + if (file_exists(g_fileToSave)) + { + delete_file(g_fileToSave) + console_print(id, "%L", id, "PAUSE_CONF_CLEARED") + } + else + console_print(id, "%L", id, "PAUSE_ALR_CLEARED") + } + else if (equal(cmds, "pause")) + { + new arg[32], a, len = read_argv(2, arg, charsmax(arg)) + + if (len && ((a = findPluginByFile(arg, len)) != -1) && !isSystem(a) && pause("ac", arg)) + console_print(id, "%L %L", id, "PAUSE_PLUGIN_MATCH", arg, id, "PAUSED") + else + console_print(id, "%L", id, "PAUSE_COULDNT_FIND", arg) + } + else if (equal(cmds, "enable")) + { + new arg[32], a, len = read_argv(2, arg, charsmax(arg)) + + if (len && (a = findPluginByFile(arg, len)) != -1 && !isSystem(a)) + { + if (unpause("ac", arg)) + { + console_print(id, "%L %L", id, "PAUSE_PLUGIN_MATCH", arg, id, "UNPAUSED") + } + else + { + console_print(id, "%L", id, "CANT_UNPAUSE_PLUGIN", arg) + } + } + else + { + console_print(id, "%L", id, "PAUSE_COULDNT_FIND", arg) + } + } + else if (equal(cmds, "stop")) + { + new arg[32], a, len = read_argv(2, arg, charsmax(arg)) + + if (len && (a = findPluginByFile(arg, len)) != -1 && !isSystem(a) && pause("dc", arg)) + { + g_Modified = 1 + console_print(id, "%L %L", id, "PAUSE_PLUGIN_MATCH", arg, id, "STOPPED") + } + else + console_print(id, "%L", id, "PAUSE_COULDNT_FIND", arg) + } + else if (equal(cmds, "list")) + { + new lName[32], lVersion[32], lAuthor[32], lFile[32], lStatus[32] + + format(lName, charsmax(lName), "%L", id, "NAME") + format(lVersion, charsmax(lVersion), "%L", id, "VERSION") + format(lAuthor, charsmax(lAuthor), "%L", id, "AUTHOR") + format(lFile, charsmax(lFile), "%L", id, "FILE") + format(lStatus, charsmax(lStatus), "%L", id, "STATUS") + + new arg1[8], running = 0 + new start = read_argv(2, arg1, charsmax(arg1)) ? str_to_num(arg1) : 1 + + if (--start < 0) + start = 0 + + new plgnum = get_pluginsnum() + + if (start >= plgnum) + start = plgnum - 1 + + console_print(id, "^n----- %L -----", id, "PAUSE_LOADED") + console_print(id, " %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s", lName, lVersion, lAuthor, lFile, lStatus) + + new plugin[32], title[32], version[16], author[32], status[16] + new end = start + 10 + + if (end > plgnum) end = plgnum + + for (new a = start; a < end; ++a) + { + get_plugin(a, plugin, charsmax(plugin), title, charsmax(title), version, charsmax(version), author, charsmax(author), status, charsmax(status)) + if (status[0] == 'r') ++running + console_print(id, " [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s", a + 1, title, version, author, plugin, status) + } + + console_print(id, "----- %L -----", id, "PAUSE_ENTRIES", start + 1, end, plgnum, running) + + if (end < plgnum) + console_print(id, "----- %L -----", id, "PAUSE_USE_MORE", end + 1) + else + console_print(id, "----- %L -----", id, "PAUSE_USE_BEGIN") + } else { + console_print(id, "%L", id, "PAUSE_USAGE") + console_print(id, "%L:", id, "PAUSE_COMMANDS") + console_print(id, "%L", id, "COM_PAUSE_OFF") + console_print(id, "%L", id, "COM_PAUSE_ON") + console_print(id, "%L", id, "COM_PAUSE_STOP") + console_print(id, "%L", id, "COM_PAUSE_PAUSE") + console_print(id, "%L", id, "COM_PAUSE_ENABLE") + console_print(id, "%L", id, "COM_PAUSE_SAVE_PAUSED") + console_print(id, "%L", id, "COM_PAUSE_CLEAR_PAUSED") + console_print(id, "%L", id, "COM_PAUSE_LIST") + console_print(id, "%L", id, "COM_PAUSE_ADD") + } + + return PLUGIN_HANDLED +} + +saveSettings(filename[]) +{ + if (file_exists(filename)) + delete_file(filename) + + new text[256], file[32], title[32], status[2] + new inum = get_pluginsnum() + + if (!write_file(filename, ";Generated by Pause Plugins Plugin. Do not modify!^n;Title Filename")) + return 0 + + for (new a = 0; a < inum; ++a) + { + get_plugin(a, file, charsmax(file), title, charsmax(title), status, 0, status, 0, status, charsmax(status)) + + // "paused" + if (status[0] == 'p') + { + format(text, charsmax(text), "^"%s^" ;%s", title, file) + write_file(filename, text) + } + } + + return 1 +} + +loadSettings(filename[]) +{ + if (!file_exists(filename)) + return 0 + + new name[256], file[32], i, pos = 0 + + while (read_file(filename, pos++, name, charsmax(name), i)) + { + if (name[0] != ';' && parse(name, name, charsmax(name)) && (i = findPluginByTitle(name, file, charsmax(file)) != -1)) + pause("ac", file) + } + + return 1 +} diff --git a/amxmodx/scripting/plmenu.sma b/amxmodx/scripting/plmenu.sma new file mode 100755 index 0000000..bf96d87 --- /dev/null +++ b/amxmodx/scripting/plmenu.sma @@ -0,0 +1,1246 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Players Menu Plugin +// + +#include +#include + +/** skip autoloading since it's optional */ +#define AMXMODX_NOAUTOLOAD +#include +#include + +new g_menuPosition[MAX_PLAYERS + 1]; +new g_menuPlayers[MAX_PLAYERS + 1][MAX_PLAYERS]; +new g_menuPlayersNum[MAX_PLAYERS + 1]; +new g_menuOption[MAX_PLAYERS + 1]; +new g_menuSettings[MAX_PLAYERS + 1]; + +new g_menuSelect[MAX_PLAYERS + 1][64]; +new g_menuSelectNum[MAX_PLAYERS + 1]; + +#define MAX_CLCMDS 24 + +new g_clcmdName[MAX_CLCMDS][32]; +new g_clcmdCmd[MAX_CLCMDS][64]; +new g_clcmdMisc[MAX_CLCMDS][2]; +new g_clcmdNum; + +new g_coloredMenus; +new bool:g_cstrike = false; +new bool:g_fakemeta = false; + +new Array:g_bantimes; +new Array:g_slapsettings; + +new const g_CSTeamNames[3][] = { + "TERRORIST", + "CT", + "SPECTATOR" +}; +new const g_CSTeamNumbers[3][] = { + "1", + "2", + "6" +}; +new const g_CSTeamiNumbers[3] = { + 1, + 2, + 3 +}; + +new g_CSPlayerCanSwitchFromSpec[MAX_PLAYERS + 1]; +new g_transferingAdmin; + +new allow_spectators, mp_limitteams; + +new p_amx_tempban_maxtime; +new Trie:g_tempBans; + +new g_silent[MAX_PLAYERS + 1]; + +public plugin_natives() +{ + set_module_filter("module_filter"); + set_native_filter("native_filter"); +} + +public plugin_init() +{ + register_plugin("Players Menu", AMXX_VERSION_STR, "AMXX Dev Team"); + register_dictionary("common.txt"); + register_dictionary("admincmd.txt"); + register_dictionary("plmenu.txt"); + + register_clcmd("amx_kickmenu", "cmdKickMenu", ADMIN_KICK, "- displays kick menu"); + register_clcmd("amx_banmenu", "cmdBanMenu", ADMIN_BAN|ADMIN_BAN_TEMP, "- displays ban menu"); + register_clcmd("amx_slapmenu", "cmdSlapMenu", ADMIN_SLAY, "- displays slap/slay menu"); + register_clcmd("amx_teammenu", "cmdTeamMenu", ADMIN_LEVEL_A, "- displays team menu"); + register_clcmd("amx_clcmdmenu", "cmdClcmdMenu", ADMIN_LEVEL_A, "- displays client cmds menu"); + + register_menucmd(register_menuid("Ban Menu"), 1023, "actionBanMenu"); + register_menucmd(register_menuid("Kick Menu"), 1023, "actionKickMenu"); + register_menucmd(register_menuid("Slap/Slay Menu"), 1023, "actionSlapMenu"); + register_menucmd(register_menuid("Team Menu"), 1023, "actionTeamMenu"); + register_menucmd(register_menuid("Client Cmds Menu"), 1023, "actionClcmdMenu"); + + g_bantimes = ArrayCreate(); + // Load up the old default values + ArrayPushCell(g_bantimes, 0); + ArrayPushCell(g_bantimes, 5); + ArrayPushCell(g_bantimes, 10); + ArrayPushCell(g_bantimes, 15); + ArrayPushCell(g_bantimes, 30); + ArrayPushCell(g_bantimes, 45); + ArrayPushCell(g_bantimes, 60); + + g_slapsettings = ArrayCreate(); + // Old default values + ArrayPushCell(g_slapsettings, 0); // slap 0 damage + ArrayPushCell(g_slapsettings, 1); + ArrayPushCell(g_slapsettings, 5); + ArrayPushCell(g_slapsettings, 0); // Last option is ignored - it is slay + + register_srvcmd("amx_plmenu_bantimes", "plmenu_setbantimes"); + register_srvcmd("amx_plmenu_slapdmg", "plmenu_setslapdmg"); + + g_coloredMenus = colored_menus(); + + new clcmds_ini_file[64]; + get_configsdir(clcmds_ini_file, charsmax(clcmds_ini_file)); + format(clcmds_ini_file, charsmax(clcmds_ini_file), "%s/clcmds.ini", clcmds_ini_file); + load_settings(clcmds_ini_file); + + if (LibraryExists("cstrike", LibType_Library)) + { + g_cstrike = true; + } + if (LibraryExists("fakemeta", LibType_Library)) + { + g_fakemeta = true; + } + + new modname[9]; + get_modname(modname, charsmax(modname)); + if (equal(modname, "cstrike") || equal(modname, "czero")) + { + register_event("TeamInfo", "Event_TeamInfo", "a", "2=TERRORIST", "2=CT"); + register_event("TextMsg", "Event_TextMsg", "b", "1=4", "2=#Only_1_Team_Change"); + } + + allow_spectators = get_cvar_pointer("allow_spectators"); + mp_limitteams = get_cvar_pointer("mp_limitteams"); +} + +public plugin_cfg() +{ + new x = get_xvar_id("g_tempBans"); + if (x) + { + g_tempBans = Trie:get_xvar_num(x); + } + new amx_tempban_maxtime[] = "amx_tempban_maxtime"; + p_amx_tempban_maxtime = get_cvar_pointer(amx_tempban_maxtime); + if (!p_amx_tempban_maxtime) + { + p_amx_tempban_maxtime = register_cvar(amx_tempban_maxtime, "4320", FCVAR_PROTECTED); + server_cmd("amx_cvar add %s", amx_tempban_maxtime); + } +} + +public plmenu_setbantimes() +{ + new buff[32]; + new args = read_argc(); + + if (args <= 1) + { + server_print("usage: amx_plmenu_bantimes [time2] [time3] ..."); + server_print(" use time of 0 for permanent."); + + return; + } + + ArrayClear(g_bantimes); + + for (new i = 1; i < args; i++) + { + read_argv(i, buff, charsmax(buff)); + + ArrayPushCell(g_bantimes, str_to_num(buff)); + } +} + +public plmenu_setslapdmg() +{ + new buff[32]; + new args = read_argc(); + + if (args <= 1) + { + server_print("usage: amx_plmenu_slapdmg [dmg2] [dmg3] ..."); + server_print(" slay is automatically set for the last value."); + + return; + } + + ArrayClear(g_slapsettings); + + for (new i = 1; i < args; i++) + { + read_argv(i, buff, charsmax(buff)); + + ArrayPushCell(g_slapsettings, str_to_num(buff)); + } + ArrayPushCell(g_slapsettings, 0); // compensate for slay +} + +public module_filter(const module[]) +{ + if (equali(module, "cstrike") || equali(module, "fakemeta")) + { + return PLUGIN_HANDLED; + } + + return PLUGIN_CONTINUE; +} + +public native_filter(const name[], index, trap) +{ + if (!trap) + { + return PLUGIN_HANDLED; + } + + return PLUGIN_CONTINUE; +} + +/* Ban menu */ + +public actionBanMenu(id, key) +{ + switch (key) + { + case 7: + { + /* BEGIN OF CHANGES BY MISTAGEE ADDED A FEW MORE OPTIONS */ + + ++g_menuOption[id]; + g_menuOption[id] %= ArraySize(g_bantimes); + + g_menuSettings[id] = ArrayGetCell(g_bantimes, g_menuOption[id]); + + displayBanMenu(id, g_menuPosition[id]); + } + case 8: + { + displayBanMenu(id, ++g_menuPosition[id]); + } + case 9: + { + displayBanMenu(id, --g_menuPosition[id]); + } + default: + { + new banTime = g_menuSettings[id]; + if (~get_user_flags(id) & (ADMIN_BAN | ADMIN_RCON) && (banTime <= 0 || banTime > get_pcvar_num(p_amx_tempban_maxtime))) + { + console_print(id, "%L", id, "NO_ACC_COM"); + displayBanMenu(id, g_menuPosition[id]); + return PLUGIN_HANDLED; + } + new player = g_menuPlayers[id][g_menuPosition[id] * 7 + key]; + new name[MAX_NAME_LENGTH], name2[MAX_NAME_LENGTH], authid[32], authid2[32]; + + get_user_name(player, name2, charsmax(name2)); + get_user_authid(id, authid, charsmax(authid)); + get_user_authid(player, authid2, charsmax(authid2)); + get_user_name(id, name, charsmax(name)); + + new userid2 = get_user_userid(player); + + log_amx("Ban: ^"%s<%d><%s><>^" ban and kick ^"%s<%d><%s><>^" (minutes ^"%d^")", name, get_user_userid(id), authid, name2, userid2, authid2, banTime); + + if (!banTime) // permanent + { + for (new i = 1; i <= MaxClients; i++) + { + show_activity_id(i, id, name, "%L %s %L", i, "BAN", name2, i, "PERM"); + } + } + else + { + new tempTime[32]; + num_to_str(banTime, tempTime, charsmax(tempTime)); + for (new i = 1; i <= MaxClients; i++) + { + show_activity_id(i, id, name, "%L %s %L", i, "BAN", name2, i, "FOR_MIN", tempTime); + } + } + /* ---------- check for Steam ID added by MistaGee -------------------- + IF AUTHID == 4294967295 OR VALVE_ID_LAN OR HLTV, BAN PER IP TO NOT BAN EVERYONE */ + + if (equal("4294967295", authid2) + || equal("HLTV", authid2) + || equal("STEAM_ID_LAN", authid2) + || equali("VALVE_ID_LAN", authid2)) + { + /* END OF MODIFICATIONS BY MISTAGEE */ + new ipa[32]; + get_user_ip(player, ipa, charsmax(ipa), 1); + + server_cmd("addip %d %s;writeip", banTime, ipa); + if (g_tempBans) + { + TrieSetString(g_tempBans, ipa, authid); + } + } + else + { + server_cmd("banid %d #%d kick;writeid", banTime, userid2); + if (g_tempBans) + { + TrieSetString(g_tempBans, authid2, authid); + } + } + + server_exec(); + + displayBanMenu(id, g_menuPosition[id]); + } + } + + return PLUGIN_HANDLED; +} + +displayBanMenu(id, pos) +{ + if (pos < 0) + { + return; + } + + get_players(g_menuPlayers[id], g_menuPlayersNum[id]); + + new menuBody[512]; + new b = 0; + new i; + new name[MAX_NAME_LENGTH]; + new start = pos * 7; + + if (start >= g_menuPlayersNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "BAN_MENU", pos + 1, (g_menuPlayersNum[id] / 7 + ((g_menuPlayersNum[id] % 7) ? 1 : 0))); + new end = start + 7; + new keys = MENU_KEY_0|MENU_KEY_8; + + if (end > g_menuPlayersNum[id]) + { + end = g_menuPlayersNum[id]; + } + + for (new a = start; a < end; ++a) + { + i = g_menuPlayers[id][a]; + get_user_name(i, name, charsmax(name)); + + if (is_user_bot(i) || (access(i, ADMIN_IMMUNITY) && i != id)) + { + ++b; + + if (g_coloredMenus) + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "\d%d. %s^n\w", b, name); + } + else + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "#. %s^n", name); + } + } + else + { + keys |= (1< 0) + { + g_menuSettings[id] = ArrayGetCell(g_bantimes, g_menuOption[id]); + } + else + { + // should never happen, but failsafe + g_menuSettings[id] = 0; + } + displayBanMenu(id, g_menuPosition[id] = 0); + + return PLUGIN_HANDLED; +} + +/* Slap/Slay */ + +public actionSlapMenu(id, key) +{ + switch (key) + { + case 7: + { + ++g_menuOption[id]; + + g_menuOption[id] %= ArraySize(g_slapsettings); + + g_menuSettings[id] = ArrayGetCell(g_slapsettings, g_menuOption[id]); + + displaySlapMenu(id, g_menuPosition[id]); + } + case 8: + { + displaySlapMenu(id, ++g_menuPosition[id]); + } + case 9: + { + displaySlapMenu(id, --g_menuPosition[id]); + } + default: + { + new player = g_menuPlayers[id][g_menuPosition[id] * 7 + key]; + new name2[MAX_NAME_LENGTH]; + + get_user_name(player, name2, charsmax(name2)); + + if (!is_user_alive(player)) + { + client_print(id, print_chat, "%L", id, "CANT_PERF_DEAD", name2); + displaySlapMenu(id, g_menuPosition[id]); + return PLUGIN_HANDLED; + } + + new authid[32], authid2[32], name[MAX_NAME_LENGTH]; + + get_user_authid(id, authid, charsmax(authid)); + get_user_authid(player, authid2, charsmax(authid2)); + get_user_name(id, name, charsmax(name)); + + new aSize = ArraySize(g_slapsettings); + if (aSize > 1 && g_menuOption[id] < aSize -1) + { + log_amx("Cmd: ^"%s<%d><%s><>^" slap with %d damage ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, g_menuSettings[id], name2, get_user_userid(player), authid2); + + show_activity_key("ADMIN_SLAP_1", "ADMIN_SLAP_2", name, name2, g_menuSettings[id]); + + user_slap(player, (get_user_health(player) > g_menuSettings[id]) ? g_menuSettings[id] : 0); + } + else // aSize == 1 or g_menuOption[id] == aSize - 1 // last option + { + log_amx("Cmd: ^"%s<%d><%s><>^" slay ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, name2, get_user_userid(player), authid2); + + show_activity_key("ADMIN_SLAY_1", "ADMIN_SLAY_2", name, name2); + + user_kill(player); + } + + displaySlapMenu(id, g_menuPosition[id]); + } + } + + return PLUGIN_HANDLED; +} + +displaySlapMenu(id, pos) +{ + if (pos < 0) + { + return; + } + + get_players(g_menuPlayers[id], g_menuPlayersNum[id]); + + new menuBody[512]; + new b = 0; + new i; + new name[MAX_NAME_LENGTH], team[4]; + new start = pos * 7; + + if (start >= g_menuPlayersNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "SLAP_SLAY_MENU", pos + 1, (g_menuPlayersNum[id] / 7 + ((g_menuPlayersNum[id] % 7) ? 1 : 0))); + new end = start + 7; + new keys = MENU_KEY_0|MENU_KEY_8; + + if (end > g_menuPlayersNum[id]) + { + end = g_menuPlayersNum[id]; + } + + for (new a = start; a < end; ++a) + { + i = g_menuPlayers[id][a]; + get_user_name(i, name, charsmax(name)); + + if (g_cstrike) + { + if (cs_get_user_team(i) == CS_TEAM_T) + { + copy(team, charsmax(team), "TE"); + } + else if (cs_get_user_team(i) == CS_TEAM_CT) + { + copy(team, charsmax(team), "CT"); + } + else + { + get_user_team(i, team, charsmax(team)); + } + } + else + { + get_user_team(i, team, charsmax(team)); + } + + if (!is_user_alive(i) || (access(i, ADMIN_IMMUNITY) && i != id)) + { + ++b; + + if (g_coloredMenus) + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "\d%d. %s\R%s^n\w", b, name, team); + } + else + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "#. %s %s^n", name, team); + } + } + else + { + keys |= (1< 0) + { + g_menuSettings[id] = ArrayGetCell(g_slapsettings, g_menuOption[id]); + } + else + { + // should never happen, but failsafe + g_menuSettings[id] = 0; + } + + displaySlapMenu(id, g_menuPosition[id] = 0); + + return PLUGIN_HANDLED; +} + +/* Kick */ + +public actionKickMenu(id, key) +{ + switch (key) + { + case 8: + { + displayKickMenu(id, ++g_menuPosition[id]); + } + case 9: + { + displayKickMenu(id, --g_menuPosition[id]); + } + default: + { + new player = g_menuPlayers[id][g_menuPosition[id] * 8 + key]; + new authid[32], authid2[32], name[MAX_NAME_LENGTH], name2[MAX_NAME_LENGTH]; + + get_user_authid(id, authid, charsmax(authid)); + get_user_authid(player, authid2, charsmax(authid2)); + get_user_name(id, name, charsmax(name)); + get_user_name(player, name2, charsmax(name2)); + + new userid2 = get_user_userid(player); + + log_amx("Kick: ^"%s<%d><%s><>^" kick ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, name2, userid2, authid2); + + show_activity_key("ADMIN_KICK_1", "ADMIN_KICK_2", name, name2); + + server_cmd("kick #%d", userid2); + server_exec(); + + displayKickMenu(id, g_menuPosition[id]); + } + } + + return PLUGIN_HANDLED; +} + +displayKickMenu(id, pos) +{ + if (pos < 0) + { + return; + } + + get_players(g_menuPlayers[id], g_menuPlayersNum[id]); + + new menuBody[512]; + new b = 0; + new i; + new name[MAX_NAME_LENGTH]; + new start = pos * 8; + + if (start >= g_menuPlayersNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "KICK_MENU", pos + 1, (g_menuPlayersNum[id] / 8 + ((g_menuPlayersNum[id] % 8) ? 1 : 0))); + new end = start + 8; + new keys = MENU_KEY_0; + + if (end > g_menuPlayersNum[id]) + { + end = g_menuPlayersNum[id]; + } + + for (new a = start; a < end; ++a) + { + i = g_menuPlayers[id][a]; + get_user_name(i, name, charsmax(name)); + + if (access(i, ADMIN_IMMUNITY) && i != id) + { + ++b; + + if (g_coloredMenus) + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "\d%d. %s^n\w", b, name); + } + else + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "#. %s^n", name); + } + } + else + { + keys |= (1<<%s><>^" transfer ^"%s<%d><%s><>^" (team ^"%s^")", name, get_user_userid(id), authid, name2, get_user_userid(player), authid2, g_CSTeamNames[destTeamSlot]); + + show_activity_key("ADMIN_TRANSF_1", "ADMIN_TRANSF_2", name, name2, g_CSTeamNames[destTeamSlot]); + + if (destTeamSlot == 2) + { + if (g_fakemeta) + { + if (get_ent_data(player, "CBasePlayer", "m_iMenu") == CS_Menu_ChooseAppearance) + { + // works for both vgui and old style menus, and send menuselect could close other menus (and since get_user_menu fails to return VGUI and old style classes menus...) + engclient_cmd(player, "joinclass", "6"); + } + } + else // force + { + engclient_cmd(player, "joinclass", "6"); + } + } + + if (g_CSPlayerCanSwitchFromSpec[player] && g_cstrike && (CS_TEAM_T <= cs_get_user_team(player) <= CS_TEAM_CT)) + { + if (is_user_alive(player) && (!g_silent[id] || destTeamSlot == 2)) + { + new deaths = cs_get_user_deaths(player); + user_kill(player, 1); + cs_set_user_deaths(player, deaths); + } + + cs_set_user_team(player, destTeamSlot + 1); + + } + else + { + if (is_user_alive(player) && (!g_silent[id] || destTeamSlot == 2)) + { + user_kill(player, 1); + } + if (g_fakemeta) + { + set_ent_data(player, "CBasePlayer", "m_bTeamChanged", true); + } + new limit_setting; + if (mp_limitteams) + { + limit_setting = get_pcvar_num(mp_limitteams); + + set_pcvar_num(mp_limitteams, 0); + } + + if (destTeamSlot == 2) + { + new Float:allow_spectators_setting; + if (allow_spectators) + { + allow_spectators_setting = get_pcvar_float(allow_spectators); + if (allow_spectators_setting != 1.0) + { + set_pcvar_float(allow_spectators, 1.0); + } + } + engclient_cmd(player, "jointeam", g_CSTeamNumbers[destTeamSlot]); + if (allow_spectators && allow_spectators_setting != 1.0) + { + set_pcvar_float(allow_spectators, allow_spectators_setting); + } + } + else + { + engclient_cmd(player, "jointeam", g_CSTeamNumbers[destTeamSlot]); + engclient_cmd(player, "joinclass", "1"); + } + if (mp_limitteams && limit_setting != 0) + { + set_pcvar_num(mp_limitteams, limit_setting); + } + } + if (g_cstrike) + { + cs_reset_user_model(player); + } + if (g_fakemeta) + { + set_ent_data(player, "CBasePlayer", "m_bTeamChanged", true); + } + + g_transferingAdmin = 0; + displayTeamMenu(id, g_menuPosition[id]); + } + } + + return PLUGIN_HANDLED; +} + +displayTeamMenu(id, pos) +{ + if (pos < 0) + { + return; + } + + get_players(g_menuPlayers[id], g_menuPlayersNum[id]); + + new menuBody[512]; + new b = 0; + new i, iteam; + new name[MAX_NAME_LENGTH], team[4]; + new start = pos * 6; + + if (start >= g_menuPlayersNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "TEAM_MENU", pos + 1, (g_menuPlayersNum[id] / 6 + ((g_menuPlayersNum[id] % 6) ? 1 : 0))); + new end = start + 6; + new keys = MENU_KEY_0|MENU_KEY_7|MENU_KEY_8; + + if (end > g_menuPlayersNum[id]) + { + end = g_menuPlayersNum[id]; + } + + for (new a = start; a < end; ++a) + { + i = g_menuPlayers[id][a]; + get_user_name(i, name, charsmax(name)); + + if (g_cstrike) + { + iteam = _:cs_get_user_team(i); + + if (iteam == 1) + { + copy(team, charsmax(team), "TE"); + } + else if (iteam == 2) + { + copy(team, charsmax(team), "CT"); + } + else if (iteam == 3) + { + copy(team, charsmax(team), "SPE"); + // iteam = 6; // oO WTF is this ?? fixed g_CSTeamiNumbers. + } + else + { + iteam = get_user_team(i, team, charsmax(team)); + } + } + else + { + iteam = get_user_team(i, team, charsmax(team)); + } + if (!iteam) + { + iteam = 3; // fix get_user_team returning 0 on spectators + } + + if ((iteam == g_CSTeamiNumbers[g_menuOption[id] % 3]) || (access(i, ADMIN_IMMUNITY) && i != id)) + { + ++b; + + if (g_coloredMenus) + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "\d%d. %s\R%s^n\w", b, name, team); + } + else + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "#. %s %s^n", name, team); + } + } + else + { + keys |= (1<= g_menuPlayersNum[id]) + { + start = pos = g_menuPosition[id] = 0; + } + + new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "CL_CMD_MENU", pos + 1, (g_menuPlayersNum[id] / 7 + ((g_menuPlayersNum[id] % 7) ? 1 : 0))); + new end = start + 7; + new keys = MENU_KEY_0|MENU_KEY_8; + + if (end > g_menuPlayersNum[id]) + { + end = g_menuPlayersNum[id]; + } + + for (new a = start; a < end; ++a) + { + i = g_menuPlayers[id][a]; + get_user_name(i, name, charsmax(name)); + + if (!g_menuSelectNum[id] || (access(i, ADMIN_IMMUNITY) && i != id)) + { + ++b; + + if (g_coloredMenus) + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "\d%d. %s^n\w", b, name); + } + else + { + len += formatex(menuBody[len], charsmax(menuBody) - len, "#. %s^n", name); + } + } + else + { + keys |= (1< 3) + { + while (replace(g_clcmdCmd[g_clcmdNum], charsmax(g_clcmdCmd[]), "\'", "^"")) + { + // do nothing + } + + g_clcmdMisc[g_clcmdNum][1] = read_flags(szFlags); + g_clcmdMisc[g_clcmdNum][0] = read_flags(szAccess); + g_clcmdNum++; + } + } + + return 1; +} + +public plugin_end() +{ + ArrayDestroy(g_bantimes); + ArrayDestroy(g_slapsettings); +} diff --git a/amxmodx/scripting/pluginmenu.sma b/amxmodx/scripting/pluginmenu.sma new file mode 100644 index 0000000..2d7e2ae --- /dev/null +++ b/amxmodx/scripting/pluginmenu.sma @@ -0,0 +1,937 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Plugin Cvar and Command Menu +// + +#include +#include + + + +new DisabledCallback; +new EnabledCallback; + +// pcvar that the client is currently modifying +new CurrentCvar[MAX_PLAYERS + 1]; + +// Name of the cvar being modified +new CurrentCvarName[MAX_PLAYERS + 1][32]; + +// Plugin ID that the client is modifying +new CurrentPlid[MAX_PLAYERS + 1]; + +// Page that the client is currently on +new CurrentPage[MAX_PLAYERS + 1]; + +// Menu function ID that the client is in +new CurrentMenuFunction[MAX_PLAYERS + 1] = { -1,... }; + +new CurrentCommand[MAX_PLAYERS + 1][32]; +new cvarmenu_cmdid; +new cmdmenu_cmdid; + +new ExplicitPlugin[MAX_PLAYERS + 1]; + +public plugin_init() +{ + register_plugin("Plugin Menu",AMXX_VERSION_STR,"AMXX Dev Team"); + + register_dictionary("common.txt"); + register_dictionary("pausecfg.txt"); // Needed for PAUSE_COULDNT_FIND + + cvarmenu_cmdid=register_clcmd("amx_plugincvarmenu", "CvarMenuCommand", ADMIN_CVAR, " - displays the plugin cvar menu"); + cmdmenu_cmdid=register_clcmd("amx_plugincmdmenu", "CommandMenuCommand", ADMIN_MENU, " - displays the plugin command menu"); + + register_clcmd("amx_changecvar","CommandChangeCvar"); + register_clcmd("amx_executecmd","CommandExecuteCommand"); + + // Register global menu callbacks. + DisabledCallback=menu_makecallback("AlwaysDisableCallback"); + EnabledCallback=menu_makecallback("AlwaysEnableCallback"); +} + +// Add these menus to the amxmodmenu +public plugin_cfg() +{ + set_task(0.1, "addToMenuFront"); +} +public addToMenuFront() +{ + new PluginFileName[64]; + + get_plugin(-1, PluginFileName, charsmax(PluginFileName)); + new cvarflags; + new cmdflags; + new garbage[1]; + new cmd[32]; + + get_concmd(cmdmenu_cmdid, cmd, charsmax(cmd), cmdflags, garbage, charsmax(garbage), -1); + + if (strcmp(cmd, "amx_plugincmdmenu") != 0) + { + // this should never happen, but just incase! + cmdflags = ADMIN_MENU; + } + get_concmd(cvarmenu_cmdid, cmd, charsmax(cmd), cvarflags, garbage, charsmax(garbage), -1); + + if (strcmp(cmd, "amx_plugincvarmenu") != 0) + { + // this should never happen, but just incase! + cvarflags = ADMIN_CVAR; + } + + AddMenuItem("Plugin Cvars", "amx_plugincvarmenu", cvarflags, PluginFileName); + AddMenuItem("Plugin Commands", "amx_plugincmdmenu", cmdflags, PluginFileName); +} + +// Reset all fields for each client as they connect. +public client_connect(id) +{ + CurrentCvar[id]=0; + CurrentPlid[id]=0; + CurrentMenuFunction[id]=-1; + CurrentCvarName[id][0]=0; + CurrentCommand[id][0]=0; + ExplicitPlugin[id]=-1; + +} + +/** + * Creates a plugin list menu. + * + * @param MenuText The text to display as the title. + * @param Handler The function to call when an item is selected. + * @param Command The function to pass to the handler. It will be passed as "PLID Command". + * @param Callback Function to call for each plugin to be listed. Displays a number next to it (how many cvars, etc.) + */ +stock DisplayPluginMenu(id,const MenuText[], const Handler[], const Command[], const Callback[]) +{ + new Menu=menu_create(MenuText,Handler); + + + new PluginState[32]; + new PluginName[64]; + new func=get_func_id(Callback); + new tally; + new PluginCmd[64]; + new MenuText[64]; + for (new i=0, max=get_pluginsnum(); + i0) + { + get_plugin(i,"",0,PluginName,charsmax(PluginName),"",0,"",0,PluginState,charsmax(PluginState)); + + // Command syntax is: "# Function", # being plugin ID, function being public function to call. + formatex(PluginCmd,charsmax(PluginCmd),"%d %s",i,Command); + formatex(MenuText,charsmax(MenuText),"%s - %d",PluginName,tally); + // If the plugin is running, add this as an activated menu item. + if (strcmp(PluginState,"running",true)==0 || + strcmp(PluginState,"debug", true)==0) + { + menu_additem(Menu,MenuText,PluginCmd,EnabledCallback); + } + else + { + menu_additem(Menu,MenuText,"",_,DisabledCallback); + } + } + } + } + + menu_setprop(Menu,MPROP_BACKNAME,fmt("%L", id, "BACK")); + menu_setprop(Menu,MPROP_NEXTNAME,fmt("%L", id, "MORE")); + menu_setprop(Menu,MPROP_EXITNAME,fmt("%L", id, "EXIT")); + menu_setprop(Menu,MPROP_NUMBER_COLOR,"\y"); + menu_setprop(Menu,MPROP_EXIT,MEXIT_ALL); + menu_display(id,Menu,0); + +} + +/** + * Byrefs the plugin id of a target plugin (passed by argv(1)), but only if it's valid. + * + * @param id id of the display messages to upon failure. + * @param plid Variable to byref the plugin id. + * @return True on successful lookup, false on failure. + */ +stock bool:GetPlidForValidPlugins(id, &plid) +{ + // If arguments have been passed, then we were given + // a specific plugin to examine. + if (read_argc()>1) + { + // Yes, we were provided a plugin. + new TargetPlugin[64]; + read_argv(1,TargetPlugin,charsmax(TargetPlugin)); + + new BufferName[64]; + new BufferFile[64]; + new BufferState[64]; + // Scan for the plugin ID. + for (new i=0, max=get_pluginsnum(); + i<%s><>^" set cvar (name ^"%s^") (value ^"%s^")", Name, get_user_userid(id), AuthID, CurrentCvarName[id], Args); + + + new cvar_val[64]; + for (new i = 1; i <= MaxClients; i++) + { + if (is_user_connected(i) && !is_user_bot(i)) + { + if (get_pcvar_flags(pointer) & FCVAR_PROTECTED || equali(Args, "rcon_password")) + { + formatex(cvar_val, charsmax(cvar_val), "*** %L ***", i, "PROTECTED"); + } + else + { + copy(cvar_val, charsmax(cvar_val), Args); + } + show_activity_id(i, id, Name, "%L", i, "SET_CVAR_TO", "", CurrentCvarName[id], cvar_val); + } + } + console_print(id, "[AMXX] %L", id, "CVAR_CHANGED", CurrentCvarName[id], Args); + + } + + // Now redraw the menu for the client + if (CurrentMenuFunction[id]!=-1 && callfunc_begin_i(CurrentMenuFunction[id])==1) + { + callfunc_push_int(id); + callfunc_push_int(CurrentPlid[id]); + callfunc_push_int(CurrentPage[id]); + callfunc_end(); + } + + return PLUGIN_HANDLED; +} + +/** + * Process a selection from the cvar menu. + * + * @param id The client who chose an item. + * @param menu The menu handle. + * @param item The item that has been selected. + */ +public CvarMenuSelection(id, menu, item) +{ + + if (item==MENU_EXIT) + { + menu_destroy(menu); + + if (ExplicitPlugin[id]==-1) + { + DisplayPluginMenu(id,"Plugin Cvar Menu:", "PluginMenuSelection","DisplayCvarMenu","GetNumberOfCvarsForPlid"); + } + } + else if (item==MENU_BACK) + { + --CurrentPage[id]; + client_print(id,print_chat,"MENU_BACK"); + } + else if (item==MENU_MORE) + { + ++CurrentPage[id]; + client_print(id,print_chat,"MENU_MORE"); + } + else + { + new CvarName[64]; + new Command[32]; + new Dummy[1]; + // pcvar pointer is stored in command, extract the name of the cvar from the name field. + menu_item_getinfo(menu, item, Dummy[0], Command, charsmax(Command),CvarName,charsmax(CvarName),Dummy[0]); + + CurrentCvar[id]=str_to_num(Command); + + if (CurrentCvar[id]==0) // This should never happen, but just incase.. + { + client_print(id,print_chat,"[AMXX] There was an error extracting the cvar pointer. (Name=^"%s^")",CvarName); + return PLUGIN_HANDLED; + } + // TODO: ML this + + // Scan up "CvarName" and stop at the first space + for (new i=0;i) should be filtered out already. + * + * @param Command The command that is being checked. + */ +stock bool:IsDisplayableCmd(const Command[]) +{ + // Block "say" and "say_team" + if (equal(Command,"say",3)) + { + return false; + } + + return true; +} +/** + * Displays a command list for the specified plugin. + * + * @param id Id of the client that's being displayed to. + * @param plid Plugin ID of the plugin that is to be displayed. + * @param page The page to start at. + */ +public DisplayCmdMenu(id, plid, page) +{ + new PluginName[32]; + new MenuTitle[64]; + get_plugin(plid,"",0,PluginName,charsmax(PluginName),"",0,"",0,"",0); + + formatex(MenuTitle,charsmax(MenuTitle),"%s Commands:",PluginName); + + new Menu=menu_create(MenuTitle,"CommandMenuSelection"); + + new Command[64]; + new CidString[32]; + new CommandAccess; + new userflags=get_user_flags(id); + new bool:isadmin=bool:is_user_admin(id); + + + for (new i=0, max=get_concmdsnum(-1,-1); + i +#include +#include + +new const PluginName[] = "Restrict Weapons"; + +const MaxAliasNameLength = 16; +const MaxItemNameLength = 32; +const MaxMenuTitleLength = 48; +const MaxCommandAliasLength = 12; +const MaxConfigFileLength = 48; +const MaxConsoleLength = 128; +const MaxMapLength = 32; + +new bool:BlockedItems[CSI_MAX_COUNT]; +new bool:ModifiedItem; +new bool:ConfigsExecuted; + +new MenuPosition[MAX_PLAYERS + 1]; +new MenuHandle [MAX_PLAYERS + 1] = { -1, ... }; +new ConfigFilePath[PLATFORM_MAX_PATH]; + +new RestrictedBotWeapons[] = "00000000000000000000000000"; +new RestrictedBotEquipAmmos[] = "000000000"; + +new CvarPointerAllowMapSettings; +new CvarPointerRestrictedWeapons; +new CvarPointerRestrictedEquipAmmos; + +enum MenuTitle +{ + m_Title[MaxMenuTitleLength], + m_Alias[MaxCommandAliasLength], +}; + +#define TITLE(%0) "MENU_TITLE_" + #%0 + +new const MenuInfos[][MenuTitle] = +{ + { TITLE(HANDGUNS) , "pistol" }, + { TITLE(SHOTGUNS) , "shotgun" }, + { TITLE(SUBMACHINES) , "sub" }, + { TITLE(RIFLES) , "rifle" }, + { TITLE(SNIPERS) , "sniper" }, + { TITLE(MACHINE) , "machine" }, + { TITLE(EQUIPMENT) , "equip" }, + { TITLE(AMMUNITION) , "ammo" }, +} + +enum MenuItem +{ + m_Index, + m_Name[MaxItemNameLength], +}; + +#define ITEM(%0) { CSI_%0, "MENU_ITEM_" + #%0 } +#define ITEM_NONE { CSI_NONE, "" } + +new const ItemsInfos[][][MenuItem] = +{ + { ITEM(USP) , ITEM(GLOCK18) , ITEM(DEAGLE) , ITEM(P228) , ITEM(ELITE) , ITEM(FIVESEVEN), ITEM_NONE , ITEM_NONE }, + { ITEM(M3) , ITEM(XM1014) , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE }, + { ITEM(MP5NAVY), ITEM(TMP) , ITEM(P90) , ITEM(MAC10) , ITEM(UMP45) , ITEM_NONE , ITEM_NONE , ITEM_NONE }, + { ITEM(AK47) , ITEM(SG552) , ITEM(M4A1) , ITEM(GALIL) , ITEM(FAMAS) , ITEM(AUG) , ITEM_NONE , ITEM_NONE }, + { ITEM(SCOUT) , ITEM(AWP) , ITEM(G3SG1) , ITEM(SG550) , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE }, + { ITEM(M249) , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE }, + { ITEM(VEST) , ITEM(VESTHELM), ITEM(FLASHBANG), ITEM(HEGRENADE), ITEM(SMOKEGRENADE), ITEM(DEFUSER) , ITEM(NVGS), ITEM(SHIELD) }, + { ITEM(PRIAMMO), ITEM(SECAMMO) , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE , ITEM_NONE }, +}; + + +public plugin_init() +{ + register_plugin(PluginName, AMXX_VERSION_STR, "AMXX Dev Team"); + + register_dictionary("restmenu.txt"); + register_dictionary("common.txt"); + + register_clcmd( "amx_restmenu", "@ClientCommand_MainMenu" , ADMIN_CFG, .info = "REG_CMD_MENU", .info_ml = true); + register_concmd("amx_restrict", "@ConsoleCommand_Restrict", ADMIN_CFG, .info = "REG_CMD_REST", .info_ml = true); + + CvarPointerAllowMapSettings = register_cvar("amx_restrmapsettings", "0"); + CvarPointerRestrictedWeapons = register_cvar("amx_restrweapons" , RestrictedBotWeapons); + CvarPointerRestrictedEquipAmmos = register_cvar("amx_restrequipammo" , RestrictedBotEquipAmmos); +} + +public OnConfigsExecuted() +{ + new const configFile[] = "weaprest"; + new const configFileExt[] = "ini"; + + new configsDir[PLATFORM_MAX_PATH]; + get_configsdir(configsDir, charsmax(configsDir)); + + if (get_pcvar_bool(CvarPointerAllowMapSettings)) + { + new mapName[MaxMapLength]; + get_mapname(mapName, charsmax(mapName)); + + formatex(ConfigFilePath, charsmax(ConfigFilePath), "%s/%s_%s.%s", configsDir, configFile, mapName, configFileExt); + } + else + { + formatex(ConfigFilePath, charsmax(ConfigFilePath), "%s/%s.%s", configsDir, configFile, configFileExt); + } + + loadSettings(ConfigFilePath); + + ConfigsExecuted = true; +} + +public CS_OnBuyAttempt(player, itemid) +{ + if (BlockedItems[itemid]) + { + return blockcommand(player); + } + + return PLUGIN_CONTINUE; +} + +public blockcommand(const id) // Might be used by others plugins, so keep this for backward compatibility. +{ + client_print(id, print_center, "%l", "RESTRICTED_ITEM"); + return PLUGIN_HANDLED; +} + +@ClientCommand_MainMenu(const id, const level, const cid) +{ + if (cmd_access(id, level, cid, 1)) + { + displayMenu(id, MenuPosition[id] = -1); + } + + return PLUGIN_HANDLED; +} + +@ConsoleCommand_Restrict(const id, const level, const cid) +{ + if (!cmd_access(id, level, cid, 1)) + { + return PLUGIN_HANDLED; + } + + new const argumentsCount = read_argc(); + + if (argumentsCount <= 1) // Main command only, no arguments. + { + goto usage; + } + + new action[8]; + new argumentIndex; + new const actionLength = read_argv(++argumentIndex, action, charsmax(action)) - trim(action); + + if (!actionLength || !isalpha(action[0])) // Empty argument or first character is not a letter. + { + goto usage; + } + + new const ch1 = char_to_lower(action[0]); + new const ch2 = char_to_lower(action[1]); + + if (ch1 == 'o' && (ch2 == 'n' || ch2 == 'f')) // [on]/[of]f + { + new const bool:restricted = (ch2 == 'n'); + new bool:valid; + + if (argumentsCount <= argumentIndex + 1) // No arguments, all items are concerned. + { + arrayset(BlockedItems, restricted, sizeof BlockedItems); + console_print(id, "%l", restricted ? "EQ_WE_RES" : "EQ_WE_UNRES"); + + ModifiedItem = valid = true; + refreshMenus(level); + } + else // Either item type or specific alias + { + new commands[MaxConsoleLength]; + new itemName[MaxItemNameLength]; + new argument[MaxAliasNameLength]; + new position, class; + new itemid, slot; + new commandLength; + + while (argumentIndex < argumentsCount) + { + // Ignore if the argument is empty or the first character is not a letter. + if ((commandLength = read_argv(++argumentIndex, commands, charsmax(commands)) - trim(commands)) <= 0 || !isalpha(commands[0])) + { + continue; + } + + strtolower(commands); + position = 0; + + // In case argument contains several input between quotes. + while (position != commandLength && (position = argparse(commands, position, argument, charsmax(argument))) != -1) + { + if ((class = findMenuAliasId(argument)) != -1) + { + for (slot = 0; slot < sizeof ItemsInfos[] && (itemid = ItemsInfos[class][slot][m_Index]) != CSI_NONE; ++slot) + { + BlockedItems[itemid] = restricted; + } + + console_print(id, "%l %l %l", MenuInfos[class], (class < 6) ? "HAVE_BEEN" : "HAS_BEEN", restricted ? "RESTRICTED" : "UNRESTRICTED"); + ModifiedItem = valid = true; + } + else if ((itemid = cs_get_item_id(argument)) != CSI_NONE) + { + BlockedItems[itemid] = restricted; + findItemFullName(itemid, itemName, charsmax(itemName)); + + console_print(id, "%l %l %l", itemName, "HAS_BEEN", restricted ? "RESTRICTED" : "UNRESTRICTED"); + ModifiedItem = valid = true; + } + } + } + + if (!valid) + { + console_print(id, "%l", "NO_EQ_WE"); + } + else + { + refreshMenus(level); + } + } + + if (ConfigsExecuted && valid) + { + show_activity_key("ADMIN_UPD_RES_1", "ADMIN_UPD_RES_2", fmt("%n", id)); + log_amx("%L", LANG_SERVER, "ADMIN_CMD_UPDATEDCFG", id); + } + } + else if (ch1 == 'l' && ch2 == 'i') // [li]st + { + // Items list. + if (argumentsCount > argumentIndex + 1) // Available arguments. + { + new const selection = read_argv_int(++argumentIndex) - 1; // Index starts from 0. + + if (0 <= selection <= charsmax(ItemsInfos)) + { + console_print(id, "^n----- %l: %l -----^n", "WEAP_RES", MenuInfos[selection][m_Title]); + + SetGlobalTransTarget(id); + + new alias[MaxAliasNameLength]; + new itemid; + + console_print(id, " %-32.31s %-10.9s %-9.8s", fmt("%l", "NAME"), fmt("%l", "VALUE"), fmt("%l", "STATUS")); + console_print(id, ""); + + for (new slot = 0; slot < sizeof ItemsInfos[] && (itemid = ItemsInfos[selection][slot][m_Index]) != CSI_NONE; ++slot) + { + cs_get_item_alias(itemid, alias, charsmax(alias)); + + console_print(id, " %-32.31s %-10.9s %-9.8s", fmt("%l", ItemsInfos[selection][slot][m_Name]), alias + , fmt("%l", BlockedItems[itemid] ? "ON" : "OFF")); + } + + console_print(id, ""); + return PLUGIN_HANDLED; + } + } + + console_print(id, "^n----- %l -----^n", "WEAP_RES"); + + // Item types list. + for (new class = 0; class < sizeof MenuInfos; ++class) + { + console_print(id, "%3d: %l", class + 1, MenuInfos[class][m_Title]); + } + + console_print(id, "^n----- %l -----^n", "REST_USE_HOW"); + } + else if (ch1 == 's') // [s]ave + { + // If 'save' is used in a per-map config file, the plugin config file is not yet known as it depends on + // amx_restrmapsettings cvar value read after per-map configs are processed. Postponing the saving a little. + if (!ConfigsExecuted) + { + const taskId = 424242; + + if (!task_exists(taskId)) + { + set_task(0.1, "@Task_SaveConfig", taskId); + } + + return PLUGIN_HANDLED; + } + + new bool:saved = saveSettings(ConfigFilePath); + + if (saved) + { + ModifiedItem = false; + refreshMenus(level, .displaySaveMessage = true); + + if (ConfigsExecuted) + { + log_amx("%L", LANG_SERVER, "ADMIN_CMD_SAVEDCFG", id, ConfigFilePath); + } + } + + console_print(id, "%l^n", saved ? "REST_CONF_SAVED" : "REST_COULDNT_SAVE", ConfigFilePath); + } + else if (ch1 == 'l' && ch2 == 'o') // [lo]ad + { + if (argumentsCount <= argumentIndex + 1) // No argument + { + goto usage; + } + + new argument[MaxConfigFileLength]; + read_argv(++argumentIndex, argument, charsmax(argument)) - trim(argument); + + new filepath[PLATFORM_MAX_PATH]; + new length = get_configsdir(filepath, charsmax(filepath)); + formatex(filepath[length], charsmax(filepath) - length, "/%s", argument); + + new bool:loaded = loadSettings(filepath); + + if (loaded) + { + arrayset(BlockedItems, false, sizeof BlockedItems); + + ModifiedItem = true; + refreshMenus(level); + + if (ConfigsExecuted) + { + show_activity_key("ADMIN_UPD_RES_1", "ADMIN_UPD_RES_2", fmt("%n", id)); + log_amx("%L", LANG_SERVER, "ADMIN_CMD_LOADEDCFG", id, ConfigFilePath); + } + } + + console_print(id, "%l^n", loaded ? "REST_CONF_LOADED" : "REST_COULDNT_LOAD", filepath); + } + else + { + usage: + console_print(id, "%l", "COM_REST_USAGE"); + console_print(id, "^n%l", "COM_REST_COMMANDS"); + console_print(id, "%l", "COM_REST_ON"); + console_print(id, "%l", "COM_REST_OFF"); + console_print(id, "%l", "COM_REST_ONV"); + console_print(id, "%l", "COM_REST_OFFV"); + console_print(id, "%l", "COM_REST_LIST"); + console_print(id, "%l", "COM_REST_SAVE"); + console_print(id, "%l^n", "COM_REST_LOAD"); + console_print(id, "%l^n", "COM_REST_VALUES"); + console_print(id, "%l^n", "COM_REST_TYPE"); + } + + return PLUGIN_HANDLED; +} + +@Task_SaveConfig() +{ + server_cmd("amx_restrict save"); +} + +displayMenu(const id, const position) +{ + SetGlobalTransTarget(id); + + new menuTitle[MaxMenuTitleLength * 2]; + formatex(menuTitle, charsmax(menuTitle), " \y%l", "REST_WEAP"); + + new const menu = MenuHandle[id] = menu_create(menuTitle, "@OnMenuAction"); + + if (position < 0) // Main menu + { + for (new class = 0; class < sizeof MenuInfos; ++class) + { + menu_additem(menu, fmt("%l", MenuInfos[class][m_Title])); + } + } + else // Sub-menus + { + menu_setprop(menu, MPROP_TITLE, fmt("%s > \d%l", menuTitle, MenuInfos[position][m_Title])); + + for (new slot = 0, data[MenuItem], index; slot < sizeof ItemsInfos[]; ++slot) + { + data = ItemsInfos[position][slot]; + + if ((index = data[m_Index])) + { + menu_additem(menu, fmt("%l\R%s%l", data[m_Name], BlockedItems[index] ? "\y" : "\r", BlockedItems[index] ? "ON" : "OFF")); + continue; + } + + menu_addblank2(menu); + } + } + + menu_addblank(menu, .slot = false); + menu_additem(menu, fmt("%s%l \y\R%s", ModifiedItem ? "\y" : "\d", "SAVE_SET", ModifiedItem ? "*" : "")); + + if (position >= 0) // Inside a sub-menu + { + menu_addblank(menu, .slot = false); + menu_additem(menu, fmt("%l", "BACK")); + } + else // Main menu + { + menu_setprop(menu, MPROP_EXITNAME, fmt("%l", "EXIT")); + menu_setprop(menu, MPROP_EXIT, MEXIT_FORCE); // Force an EXIT item since pagination is disabled. + } + + menu_setprop(menu, MPROP_PERPAGE, 0); // Disable pagination. + menu_setprop(menu, MPROP_NUMBER_COLOR, " \r"); // Small QoL change to avoid menu overlapping with left icons. + + menu_display(id, menu); + + return menu; +} + +@OnMenuAction(const id, const menu, const key) +{ + new position = MenuPosition[id]; + + if (key >= 0) + { + switch (key + 1) + { + case 1 .. sizeof ItemsInfos[]: + { + if (position < 0) // We are right now in the main menu, go to sub-menu. + { + position = key; + } + else // We are in a sub-menu. + { + ModifiedItem = true; + + new const itemid = ItemsInfos[any:position][key][m_Index]; + BlockedItems[itemid] = !BlockedItems[itemid]; + + restrictPodbotItem(itemid, .toggle = true); + updatePodbotCvars(); + } + } + case sizeof ItemsInfos[] + 1: // Save option. + { + if (saveSettings(ConfigFilePath)) + { + show_activity_key("ADMIN_UPD_RES_1", "ADMIN_UPD_RES_2", fmt("%n", id)); + log_amx("%L", LANG_SERVER, "ADMIN_MENU_SAVEDCFG", id ,ConfigFilePath); + + ModifiedItem = false; + } + + client_print(id, print_chat, "* %l", ModifiedItem ? "CONF_SAV_FAIL" : "CONF_SAV_SUC"); + } + default: + { + position = -1; // Back to main menu. + } + } + } + + MenuHandle[id] = -1; + + menu_destroy(menu); + + if (position != MenuPosition[id] || key >= 0) + { + displayMenu(id, MenuPosition[id] = position); + } + + return PLUGIN_HANDLED; +} + +findAdminsWithMenu(playersList[MAX_PLAYERS], &playersCount, const commandLevel = -1) +{ + new player, adminsCount; + new menu, newmenu; + + get_players(playersList, playersCount, "ch"); + + for (new i = 0; i < playersCount, (player = playersList[i]); ++i) + { + if (player_menu_info(player, menu, newmenu) && newmenu != -1 && newmenu == MenuHandle[player]) + { + if (commandLevel == -1 || access(player, commandLevel)) // extra safety + { + playersList[adminsCount++] = player; + } + } + } + + playersCount = adminsCount; +} + +refreshMenus(const commandLevel = 0, const bool:displaySaveMessage = false) +{ + new playersList[MAX_PLAYERS], playersCount; + findAdminsWithMenu(playersList, playersCount, commandLevel); + + if (!playersCount) + { + return; + } + + for (new i = 0, player; i < playersCount, (player = playersList[i]); ++i) + { + MenuHandle[player] = displayMenu(player, MenuPosition[player]); + + if (displaySaveMessage) + { + client_print(playersList[i], print_chat, "* %l (amx_restrict)", "CONF_SAV_SUC"); + } + } +} + +bool:saveSettings(const filename[]) +{ + new const fp = fopen(filename, "wt"); + + if (!fp) + { + return false; + } + + fprintf(fp, "%L", LANG_SERVER, "CONFIG_FILE_HEADER", PluginName); + + new alias[MaxAliasNameLength]; + new itemid; + new bool:showCategory; + + for (new class = 0, slot; class < sizeof ItemsInfos; ++class) + { + showCategory = true; + + for (slot = 0; slot < sizeof ItemsInfos[]; ++slot) + { + if ((itemid = ItemsInfos[class][slot][m_Index]) == CSI_NONE) + { + break; + } + + if (BlockedItems[itemid]) + { + if (showCategory) + { + showCategory = false; + fprintf(fp, "^n; %l^n; -^n", MenuInfos[class][m_Title]); + } + + cs_get_item_alias(itemid, alias, charsmax(alias)); + fprintf(fp, "%-16.15s ; %L^n", alias, LANG_SERVER, ItemsInfos[class][slot][m_Name]); + } + } + } + + fclose(fp); + + return true; +} + +bool:loadSettings(const filename[]) +{ + new const fp = fopen(filename, "rt"); + + if (!fp) + { + return false; + } + + new lineRead[MaxAliasNameLength], alias[MaxAliasNameLength]; + new itemid, ch; + + arrayset(RestrictedBotEquipAmmos, '0', charsmax(RestrictedBotEquipAmmos)); + arrayset(RestrictedBotWeapons, '0', charsmax(RestrictedBotWeapons)); + + while (!feof(fp)) + { + if (fgets(fp, lineRead, charsmax(lineRead)) - trim(lineRead) <= 0) + { + continue; + } + + if ((ch = lineRead[0]) == ';' || ch == '/' || ch == '#') + { + continue; + } + + if (parse(lineRead, alias, charsmax(alias)) == 1 && (itemid = cs_get_item_id(alias)) != CSI_NONE) + { + BlockedItems[itemid] = true; + restrictPodbotItem(itemid); + } + } + + fclose (fp); + + updatePodbotCvars(); + + return true; +} + +findMenuAliasId(const name[]) +{ + for (new i = 0; i < sizeof MenuInfos; ++i) + { + if (equal(name, MenuInfos[i][m_Alias])) + { + return i; + } + } + + return -1; +} + +findItemFullName(const itemid, name[], const maxlen) +{ + for (new class = 0, slot; class < sizeof ItemsInfos; ++class) + { + for (slot = 0; slot < sizeof ItemsInfos[]; ++slot) + { + if (ItemsInfos[class][slot][m_Index] == itemid) + { + copy(name, maxlen, ItemsInfos[class][slot][m_Name]); + return; + } + } + } +} + +restrictPodbotItem(const itemid, const bool:toggle = false) +{ + new const translatedItems[CSI_MAX_COUNT] = + { + // CSI ids -> string indexes of pb_restrweapons and pb_restrequipammo cvars. See podbot.cfg. + -1, 4, -1, 20, 3, 8, -1, 12, 19, 4, 5, 6, 13, 23, 17, 18, 1, 2, 21, 9, 24, 7, 16, 10, 22, 2, 3, 15, 14, 0, 11, 0, 1, 5, 6, 25, 7, 8 + }; + + new const index = translatedItems[itemid]; + + if (index >= 0) + { + if ((itemid <= CSI_LAST_WEAPON && !(1 << itemid & CSI_ALL_GRENADES)) || itemid == CSI_SHIELD) + { + RestrictedBotWeapons[index] = toggle && RestrictedBotWeapons[index] == '1' ? '0' : '1'; + } + else + { + RestrictedBotEquipAmmos[index] = toggle && RestrictedBotEquipAmmos[index] == '1' ? '0' : '1'; + } + } +} + +updatePodbotCvars() +{ + set_pcvar_string(CvarPointerRestrictedWeapons, RestrictedBotWeapons); + set_pcvar_string(CvarPointerRestrictedEquipAmmos, RestrictedBotEquipAmmos); +} + diff --git a/amxmodx/scripting/rtv.sma b/amxmodx/scripting/rtv.sma new file mode 100644 index 0000000..abf0e56 --- /dev/null +++ b/amxmodx/scripting/rtv.sma @@ -0,0 +1,417 @@ +/* Todo: + * countdown + */ +#include +#include + +#define MAX_NOMINATIONS 4 +#define MAX_MAPS_IN_VOTE 6 +#define ID_EXTEND MAX_MAPS_IN_VOTE + +#define TASK_VOTE 0 + +new Array:g_mapName; +new g_mapCount; + +new g_voting; +new Float:g_lastVoteTime; + +new g_mapChoices[MAX_MAPS_IN_VOTE + 1]; +new g_mapVoteCount[MAX_MAPS_IN_VOTE + 1]; +new g_numChoices; + +new g_countDown; +new g_numPlayersVoted; +new g_maxClients; + +new const g_prefix[] = "^1[^4f0.gg^1]"; + +new g_nextmap[32]; + +new g_nomination[33] = {-1, ...}; +new bool:g_voted[33]; +new bool:g_rocked[33]; + +new CvarExtendMax, CvarExtendStep; +new CvarRtvWait, CvarRtvRatio; +new CvarTimeLimit; + +public plugin_init() { + register_plugin("rtv", "0.1", "Flummi"); + register_menucmd(register_menuid("MapVoteMenu"), 1023, "CountMapVote"); + register_clcmd("say", "CmdSay"); + CvarExtendStep = register_cvar("mapvote_extend_step", "15"); + CvarExtendMax = register_cvar("mapvote_extend_max", "90"); + CvarRtvWait = register_cvar("mapvote_rtv_wait", "15"); + CvarRtvRatio = register_cvar("mapvote_rtv_ratio", "0.7"); + CvarTimeLimit = get_cvar_pointer("mp_timelimit"); + g_maxClients = get_maxplayers() - 1; + g_mapName = ArrayCreate(32); + g_lastVoteTime = get_gametime() - 1000; + loadConfigs(); + set_task(10.0, "CheckEndOfMap", 1337, _, _, "b"); + pause("ac", "mapchooser.amxx"); +} + +public client_disconnected(id) { + g_rocked[id] = false; + g_voted[id] = false; + g_nomination[id] = -1; +} + +public CmdSay(id) { + new arg[72]; + read_args(arg, charsmax(arg)); + remove_quotes(arg); + + new arg1[32], arg2[32]; + parse(arg, arg1, charsmax(arg1), arg2, charsmax(arg2)); + + new mapId = arrayFindString(g_mapName, arg1); + if(mapId != -1) { + nominateMap(id, mapId); + return PLUGIN_HANDLED; + } + else if(equal(arg1, "/nom") || equal(arg1, "/nominate")) { + ShowNominationMenu(id, arg2); + return PLUGIN_HANDLED; + } + else if(equal(arg1, "rtv") || equal(arg1, "rockthevote")) { + rockTheVote(id); + return PLUGIN_HANDLED; + } + return PLUGIN_CONTINUE; +} + +public ShowNominationMenu(id, const match[]) { + new buffer[64]; + formatex(buffer, charsmax(buffer), "Nomination \w(search: %s)\y", match); + new menu = menu_create(buffer, "HandleMenuNomination"); + for(new mapId = 0; mapId < g_mapCount; mapId++) { + static mapName[32]; + ArrayGetString(g_mapName, mapId, mapName, charsmax(mapName)); + if(contain(mapName, match) > -1 || !match[0]) { + static info[2]; + formatex(buffer, charsmax(buffer), mapName); + if(isMapNominated(mapId)) + add(buffer, charsmax(buffer), "\r (nominated)"); + info[0] = mapId; + menu_additem(menu, buffer, info); + } + } + menu_setprop(menu, MPROP_NUMBER_COLOR, "\y"); + menu_display(id, menu); +} + +public HandleMenuNomination(id, menu, item) { + if(item == MENU_EXIT) { + menu_destroy(menu); + return; + } + new dummy, info[2], tmpname[32]; + menu_item_getinfo(menu, item, dummy, info, charsmax(info), tmpname, charsmax(tmpname), dummy); + new mapId = info[0] + if(!nominateMap(id, mapId)) + client_print_color(id, print_chat, "%s Map ^"^4%s^1^" has already been nominated.", g_prefix, tmpname); + menu_destroy(menu); +} + +public CheckEndOfMap() { + if(g_voting) + return; + if(get_timeleft() < 130) + MakeMapVote(); +} + +public MakeMapVote() { + g_voting = 1; + g_lastVoteTime = get_gametime(); + g_numChoices = 0; + new nomination[32], numNominations = 0; + for(new i = 1; i <= g_maxClients; i++) + if(g_nomination[i] != -1) + nomination[numNominations++] = g_nomination[i]; + new maxChoices = min(g_mapCount, MAX_MAPS_IN_VOTE); + new maxNomination = min(numNominations, MAX_NOMINATIONS); + while(g_numChoices < maxChoices) { + static map; + if(g_numChoices < maxNomination) { + new i = random(numNominations); + while(isMapInMenu((map = nomination[i]))) + if(++i >= numNominations) + i = 0; + } + else { // Add random maps + map = random(g_mapCount); + while(isMapInMenu(map)) + if(++map >= g_mapCount) + map = 0; + } + g_mapChoices[g_numChoices++] = map; + } + + g_mapChoices[ID_EXTEND] = (get_pcvar_float(CvarTimeLimit) < get_pcvar_float(CvarExtendMax)); + + arrayset(g_mapVoteCount, 0, sizeof g_mapVoteCount); + arrayset(g_voted, false, sizeof g_voted); + remove_task(TASK_VOTE); + set_task(1.0, "ShowMapVote", TASK_VOTE, _, _, "a", 7); + set_task(6.0, "CheckMapVotes", TASK_VOTE); + g_countDown = 5; + g_numPlayersVoted = 0; +} + +public ShowMapVote() { + new numPlayers = countRealPlayers(); + static menu[512], len, keys; + for(new player = 1; player <= g_maxClients; player++) { + if(!is_user_connected(player) || is_user_bot(player)) + continue; + if(g_voting == 1) + len = formatex(menu, charsmax(menu), "\yvoting will start soon...^n^n"); + else if(g_voting == 2) + len = formatex(menu, charsmax(menu), "\yvote for the next map^n^n"); + else + len = formatex(menu, charsmax(menu), "\yvoting results^n^n"); + + keys = 0; + len += formatex(menu[len], 511-len, "\r1. \wCheckpoint^n"); + keys |= (1 << 0); + len += formatex(menu[len], 511-len, "\r2. \wGocheck^n^n"); + keys |= (1 << 1); + + for(new i = 2; i < (g_numChoices + 2); i++) { + new map = g_mapChoices[i-2]; + if(g_voting != 2) + len += formatex(menu[len], 511-len, "\y%d. \w%a", i+1, ArrayGetStringHandle(g_mapName, map)); + else + len += formatex(menu[len], 511-len, "\r%d. \w%a", i+1, ArrayGetStringHandle(g_mapName, map)); + if(g_voting == 3 || (g_voted[player] && g_mapVoteCount[i - 2])) + len += formatex(menu[len], 511-len, " \y(%d%%)", (g_mapVoteCount[i - 2] * 100 / (numPlayers | 1))); + menu[len++] = '^n'; + keys |= (1 << i); + } + + new i = ID_EXTEND; + if(g_voting != 1 && g_mapChoices[i]) { + static mapName[32]; + get_mapname(mapName, charsmax(mapName)); + len += formatex(menu[len], 511-len, "^n%s9. \wextend %s", g_voting == 2 ? "\r" : "\y", mapName); + if(g_voting == 3 || (g_voted[player] && g_mapVoteCount[i])) + len += formatex(menu[len], 511-len, " \y(%d%%)", (g_mapVoteCount[i] * 100 / (numPlayers | 1))); + keys |= MENU_KEY_9; + } + if(g_voting != 3 && g_countDown <= 10) + len += formatex(menu[len], 511-len, "^n^n\wremaining time: %d", max(0, g_countDown)); + show_menu(player, keys, menu, 5, "MapVoteMenu"); + } + g_countDown--; +} + +public CountMapVote(id, key) { + if(key == 0) { + client_cmd(id, "say /cp"); + ShowMapVote(); + return; + } + else if(key == 1) { + client_cmd(id, "say /gc"); + ShowMapVote(); + return; + } + + if(g_voting == 2 && !g_voted[id]) { + new username[32]; + get_user_name(id, username, charsmax(username)); + new tmpmap[32]; + ArrayGetString(g_mapName, g_mapChoices[key - 2], tmpmap, charsmax(tmpmap)); + + if((key + 1) == 9) { + g_mapVoteCount[ID_EXTEND]++; + g_numPlayersVoted++; + g_voted[id] = true; + client_print_color(0, print_chat, "%s %s chose map extending", g_prefix, username); + } + else { + g_mapVoteCount[key - 2]++; + g_numPlayersVoted++; + g_voted[id] = true; + client_print_color(0, print_chat, "%s %s chose %s", g_prefix, username, tmpmap); + } + } + ShowMapVote(); +} + +public CheckMapVotes() { + if(g_voting == 1) { + g_voting = 2; + client_cmd(0, "spk Gman/Gman_Choose%d", random_num(1, 2)); + remove_task(TASK_VOTE); + set_task(1.0, "ShowMapVote", TASK_VOTE, _, _, "a", 15); + set_task(16.0, "CheckMapVotes", TASK_VOTE); + g_countDown = 15; + return; + } + + new numPlayers = countRealPlayers(); + g_voting = 3; + ShowMapVote(); + + new best; + for(new i = 0; i <= MAX_MAPS_IN_VOTE; i++) + if(g_mapVoteCount[i] > g_mapVoteCount[best]) + best = i; + + new sameVotes[MAX_MAPS_IN_VOTE + 1], num = 0; + for(new i = 0; i <= MAX_MAPS_IN_VOTE; i++) + if(g_mapVoteCount[i] > 0 && g_mapVoteCount[i] == g_mapVoteCount[best]) + sameVotes[num++] = i; + + if(num > 1) { + best = sameVotes[random(num)]; + client_print_color(0, print_chat, "%s since there are %d results that are the same, one of them is randomly selected.", g_prefix, num); + } + + new mapName[32]; + + if(best == ID_EXTEND || (g_numPlayersVoted == 0 && numPlayers != 0)) { // extend map + g_voting = 0; + get_mapname(mapName, charsmax(mapName)); + + if(get_timeleft() < 130) + set_cvar_float("mp_timelimit", get_cvar_float("mp_timelimit") + get_pcvar_float(CvarExtendStep)); + + client_print_color(0, print_chat, "%s voting is over. %s will be extended by %d minutes.", g_prefix, mapName, get_pcvar_num(CvarExtendStep)); + } + else { + ArrayGetString(g_mapName, g_mapChoices[best], g_nextmap, charsmax(g_nextmap)); + server_print("(after vote) g_nextmap: %s", g_nextmap); + set_cvar_string("amx_nextmap", g_nextmap); + set_task(10.0, "changeLevel", TASK_VOTE); + message_begin(MSG_ALL, SVC_INTERMISSION); + message_end(); + client_print_color(0, print_chat, "%s voting is over. the next map will be %s.", g_prefix, g_nextmap); + } +} + +public changeLevel() { + server_print("(changeLevel) g_nextmap: %s", g_nextmap); + client_print_color(0, print_chat, "%s changing map to %s...", g_prefix, g_nextmap); + server_cmd("changelevel ^"%s^"", g_nextmap); +} + +loadConfigs() { + new currentMap[32]; + get_mapname(currentMap, charsmax(currentMap)); + + new filePath[100]; + get_configsdir(filePath, charsmax(filePath)); + add(filePath, charsmax(filePath), "/maps.ini"); + + new file = fopen(filePath, "r"); + if(file) { + while(!feof(file)) { + static data[64]; + fgets(file, data, charsmax(data)); + + static mapName[32]; + parse(data, mapName, charsmax(mapName)); + + if(is_map_valid(mapName) && !equal(currentMap, mapName) && !isMapExists(mapName)) { + ArrayPushString(g_mapName, mapName); + g_mapCount++; + } + } + + fclose(file); + } + + if(!g_mapCount) + set_fail_state("Could not load any map."); +} + +rockTheVote(id) { + if(g_voting) { + client_print_color(id, print_chat, "%s voting is in progress", g_prefix); + return; + } + + new Float:timeWait = g_lastVoteTime + get_pcvar_float(CvarRtvWait) - get_gametime(); + if(timeWait > 0.0) { + client_print_color(id, print_chat, "%s next vote in (%.f seconds)", g_prefix, timeWait); + return; + } + + if(g_rocked[id]) { + g_rocked[id] = false; + client_print_color(id, print_chat, "%s you canceled the vote to change the map.", g_prefix); + return; + } + + g_rocked[id] = true; + + new maxVotes = floatround(get_pcvar_float(CvarRtvRatio) * countRealPlayers()); + new numVotes = countRocked(); + + if(numVotes >= maxVotes) { + arrayset(g_rocked, false, sizeof g_rocked); + MakeMapVote(); + + client_print_color(0, print_chat, "%s %n voted to change the map.", g_prefix, id); + } + else + client_print_color(0, print_chat, "%s %n rocked the vote (%d players are needed).", g_prefix, id, maxVotes - numVotes); +} + +bool:nominateMap(id, map) { + if(isMapNominated(map)) + return false; + g_nomination[id] = map; + client_print_color(0, print_chat, "%s %n nominated the map %a.", g_prefix, id, ArrayGetStringHandle(g_mapName, map)); + return true; +} + +stock bool:isMapInMenu(map) { + for(new i = 0; i < g_numChoices; i++) + if(g_mapChoices[i] == map) + return true + return false; +} + +stock bool:isMapExists(const map[]) { + return (arrayFindString(g_mapName, map) != -1); +} + +stock arrayFindString(Array:which, const string[]) { + new size = ArraySize(which); + for(new i = 0; i < size; i++) { + static buffer[128]; + ArrayGetString(g_mapName, i, buffer, charsmax(buffer)); + if(equal(string, buffer)) + return i; + } + return -1; +} + +stock bool:isMapNominated(map) { + for(new i = 1; i <= g_maxClients; i++) + if(g_nomination[i] == map) + return true; + return false; +} + +stock countRocked() { + new count = 0; + for(new i = 1; i <= g_maxClients; i++) + if(g_rocked[i]) + count++; + return count; +} + +stock countRealPlayers() { + new count = 0; + for(new i = 1; i <= g_maxClients; i++) + if(is_user_connected(i) && !is_user_bot(i)) + count++; + return count; +} diff --git a/amxmodx/scripting/scrollmsg.sma b/amxmodx/scripting/scrollmsg.sma new file mode 100755 index 0000000..316c823 --- /dev/null +++ b/amxmodx/scripting/scrollmsg.sma @@ -0,0 +1,107 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Scrolling Message Plugin +// + +#include +#include + +#define SPEED 0.3 +#define SCROLLMSG_SIZE 512 + +new g_startPos +new g_endPos +new g_scrollMsg[SCROLLMSG_SIZE] +new g_displayMsg[SCROLLMSG_SIZE] +new Float:g_xPos +new g_Length +new g_Frequency + +public plugin_init() +{ + register_plugin("Scrolling Message", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("scrollmsg.txt") + register_dictionary("common.txt") + register_srvcmd("amx_scrollmsg", "setMessage") +} + +public showMsg() +{ + new a = g_startPos, i = 0 + + while (a < g_endPos) + g_displayMsg[i++] = g_scrollMsg[a++] + + g_displayMsg[i] = 0 + + if (g_endPos < g_Length) + g_endPos++ + + if (g_xPos > 0.35) + g_xPos -= 0.0063 + else + { + g_startPos++ + g_xPos = 0.35 + } + + set_hudmessage(200, 100, 0, g_xPos, 0.90, 0, SPEED, SPEED, 0.05, 0.05, 2) + show_hudmessage(0, "%s", g_displayMsg) +} + +public msgInit() +{ + g_endPos = 1 + g_startPos = 0 + g_xPos = 0.65 + + new hostname[64] + + get_cvar_string("hostname", hostname, charsmax(hostname)) + replace(g_scrollMsg, charsmax(g_scrollMsg), "%hostname%", hostname) + + g_Length = strlen(g_scrollMsg) + + set_task(SPEED, "showMsg", 123, "", 0, "a", g_Length + 48) + client_print(0, print_console, "%s", g_scrollMsg) +} + +public setMessage() +{ + remove_task(123) /* remove current messaging */ + read_argv(1, g_scrollMsg, charsmax(g_scrollMsg)) + + g_Length = strlen(g_scrollMsg) + + new mytime[32] + + read_argv(2, mytime, charsmax(mytime)) + + g_Frequency = str_to_num(mytime) + + if (g_Frequency > 0) + { + new minimal = floatround((g_Length + 48) * (SPEED + 0.1)) + + if (g_Frequency < minimal) + { + server_print("%L", LANG_SERVER, "MIN_FREQ", minimal) + g_Frequency = minimal + } + + server_print("%L", LANG_SERVER, "MSG_FREQ", g_Frequency / 60, g_Frequency % 60) + set_task(float(g_Frequency), "msgInit", 123, "", 0, "b") + } + else + server_print("%L", LANG_SERVER, "MSG_DISABLED") + + return PLUGIN_HANDLED +} diff --git a/amxmodx/scripting/stats_logging.sma b/amxmodx/scripting/stats_logging.sma new file mode 100755 index 0000000..4424151 --- /dev/null +++ b/amxmodx/scripting/stats_logging.sma @@ -0,0 +1,91 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Stats Logging Plugin +// + +#include +#include + +new g_pingSum[MAX_PLAYERS + 1] +new g_pingCount[MAX_PLAYERS + 1] +new g_inGame[MAX_PLAYERS + 1] + +public plugin_init() +{ + register_plugin("CS Stats Logging", AMXX_VERSION_STR, "AMXX Dev Team") +} + +public client_disconnected(id) +{ + if (!g_inGame[id]) + return + + g_inGame[id] = 0 + + if (is_user_bot(id)) + { + return + } + + remove_task(id) + + new szTeam[16], szName[MAX_NAME_LENGTH], szAuthid[32], iStats[STATSX_MAX_STATS], iHits[MAX_BODYHITS], szWeapon[24] + new iUserid = get_user_userid(id) + new _max = xmod_get_maxweapons() + + get_user_team(id, szTeam, charsmax(szTeam)) + get_user_name(id, szName, charsmax(szName)) + get_user_authid(id, szAuthid, charsmax(szAuthid)) + + for (new i = 1 ; i < _max ; ++i) + { + if (get_user_wstats(id, i, iStats, iHits)) + { + xmod_get_wpnname(i, szWeapon, charsmax(szWeapon)) + + log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"%s^") (shots ^"%d^") (hits ^"%d^") (kills ^"%d^") (headshots ^"%d^") (tks ^"%d^") (damage ^"%d^") (deaths ^"%d^")", + szName, iUserid, szAuthid, szTeam, szWeapon, iStats[STATSX_SHOTS], iStats[STATSX_HITS], iStats[STATSX_KILLS], iStats[STATSX_HEADSHOTS], iStats[STATSX_TEAMKILLS], iStats[STATSX_DAMAGE], iStats[STATSX_DEATHS]) + log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"%s^") (head ^"%d^") (chest ^"%d^") (stomach ^"%d^") (leftarm ^"%d^") (rightarm ^"%d^") (leftleg ^"%d^") (rightleg ^"%d^")", + szName, iUserid, szAuthid, szTeam, szWeapon, iHits[HIT_HEAD], iHits[HIT_CHEST], iHits[HIT_STOMACH], iHits[HIT_LEFTARM], iHits[HIT_RIGHTARM], iHits[HIT_LEFTLEG], iHits[HIT_RIGHTLEG]) + } + } + + new iTime = get_user_time(id, 1) + + log_message("^"%s<%d><%s><%s>^" triggered ^"time^" (time ^"%d:%02d^")", szName, iUserid, szAuthid, szTeam, (iTime / 60), (iTime % 60)) + log_message("^"%s<%d><%s><%s>^" triggered ^"latency^" (ping ^"%d^")", szName, iUserid, szAuthid, szTeam, (g_pingSum[id] / (g_pingCount[id] ? g_pingCount[id] : 1))) +} + +public client_connect(id) +{ + g_inGame[id] = 0 +} + +public client_putinserver(id) +{ + g_inGame[id] = 1 + if (!is_user_bot(id)) + { + g_pingSum[id] = g_pingCount[id] = 0 + if (task_exists(id)) + remove_task(id) + set_task(19.5, "getPing", id, "", 0, "b") + } +} + +public getPing(id) +{ + new iPing, iLoss + + get_user_ping(id, iPing, iLoss) + g_pingSum[id] += iPing + ++g_pingCount[id] +} diff --git a/amxmodx/scripting/statscfg.sma b/amxmodx/scripting/statscfg.sma new file mode 100755 index 0000000..665d935 --- /dev/null +++ b/amxmodx/scripting/statscfg.sma @@ -0,0 +1,304 @@ +// vim: set ts=4 sw=4 tw=99 noet: +// +// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). +// Copyright (C) The AMX Mod X Development Team. +// +// This software is licensed under the GNU General Public License, version 3 or higher. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// https://alliedmods.net/amxmodx-license + +// +// Stats Configuration Plugin +// + +#include +#include + +#define MAX_MENU_DATA 72 + +new g_menuData[MAX_MENU_DATA][32] +new g_menuDataVar[MAX_MENU_DATA][32] +new g_menuDataId[MAX_MENU_DATA] +new g_menuDataNum +new g_menuPosition[MAX_PLAYERS + 1] +new g_fileToSave[64] +new bool:g_modified +new g_coloredMenus + +public plugin_precache() +{ + register_clcmd("amx_statscfgmenu", "cmdCfgMenu", ADMIN_CFG, "- displays stats configuration menu") + register_dictionary("statscfg.txt") + register_dictionary("common.txt") + register_concmd("amx_statscfg", "cmdCfg", ADMIN_CFG, "- displays help for stats configuration") +} + +public plugin_init() +{ + register_plugin("Stats Configuration", AMXX_VERSION_STR, "AMXX Dev Team") + register_menucmd(register_menuid("Stats Configuration"), 1023, "actionCfgMenu") + + get_configsdir(g_fileToSave, charsmax(g_fileToSave)) + format(g_fileToSave, charsmax(g_fileToSave), "%s/stats.ini", g_fileToSave) + loadSettings(g_fileToSave) + g_coloredMenus = colored_menus() +} + +public cmdCfg(id, level, cid) +{ + if (!cmd_access(id, level, cid, 1)) + return PLUGIN_HANDLED + + new cmds[32] + read_argv(1, cmds, charsmax(cmds)) + + new option = equali(cmds, "on") ? 1 : 0 + + if (!option) + option = equali(cmds, "off") ? 2 : 0 + + if (read_argc() > 2 && option) + { + new var[32], enabled = 0 + read_argv(2, var, charsmax(var)) + + for (new a = 0; a < g_menuDataNum; ++a) + { + if (containi(g_menuDataVar[a], var) != -1) + { + g_modified = true + ++enabled + if (option == 1) + { + set_xvar_num(g_menuDataId[a], 1) + console_print(id, "%L: %s", id, "STATS_ENABLED", g_menuData[a]) + } else { + set_xvar_num(g_menuDataId[a], 0) + console_print(id, "%L: %s", id, "STATS_DISABLED", g_menuData[a]) + } + } + } + + if (enabled) + console_print(id, "%L", id, "TOTAL_NUM", enabled) + else + console_print(id, "%L", id, "NO_OPTION", var) + } + else if (equali(cmds, "save")) + { + if (saveSettings(g_fileToSave)) + { + g_modified = false + console_print(id, "%L", id, "STATS_CONF_SAVED") + } + else + console_print(id, "%L", id, "STATS_CONF_FAILED") + } + else if (equali(cmds, "load")) + { + if (loadSettings(g_fileToSave)) + { + g_modified = false + console_print(id, "%L", id, "STATS_CONF_LOADED") + } + else + console_print(id, "%L", id, "STATS_CONF_FAIL_LOAD") + } + else if (equali(cmds, "list")) + { + new arg1[8] + new start = read_argv(2, arg1, charsmax(arg1)) ? str_to_num(arg1) : 1 + + if (--start < 0) start = 0 + + if (start >= g_menuDataNum) + start = g_menuDataNum - 1 + + new end = start + 10 + + if (end > g_menuDataNum) + end = g_menuDataNum + + new lName[16], lVariable[16], lStatus[16] + + format(lName, charsmax(lName), "%L", id, "NAME") + format(lVariable, charsmax(lVariable), "%L", id, "VARIABLE") + format(lStatus, charsmax(lStatus), "%L", id, "STATUS") + console_print(id, "^n----- %L: -----", id, "STATS_CONF") + console_print(id, " %-29.28s %-24.23s %-9.8s", lName, lVariable, lStatus) + + if (start != -1) + { + new lOnOff[16] + + for (new a = start; a < end; ++a) + { + format(lOnOff, charsmax(lOnOff), "%L", id, get_xvar_num(g_menuDataId[a]) ? "ON" : "OFF") + console_print(id, "%3d: %-29.28s %-24.23s %-9.8s", a + 1, g_menuData[a], g_menuDataVar[a], lOnOff) + } + } + + console_print(id, "----- %L -----", id, "STATS_ENTRIES_OF", start + 1, end, g_menuDataNum) + + if (end < g_menuDataNum) + console_print(id, "----- %L -----", id, "STATS_USE_MORE", end + 1) + else + console_print(id, "----- %L -----", id, "STATS_USE_BEGIN") + } + else if (equali(cmds, "add") && read_argc() > 3) + { + if (g_menuDataNum < MAX_MENU_DATA) + { + read_argv(2, g_menuData[g_menuDataNum], charsmax(g_menuData[])) + read_argv(3, g_menuDataVar[g_menuDataNum], charsmax(g_menuDataVar[])) + g_menuDataId[g_menuDataNum] = get_xvar_id(g_menuDataVar[g_menuDataNum]) + ++g_menuDataNum + } + else + console_print(id, "%L", id, "CANT_ADD_STATS") + } else { + console_print(id, "%L", id, "COM_STATS_USAGE") + console_print(id, "%L", id, "COM_STATS_COM") + console_print(id, "%L", id, "COM_STATS_ON") + console_print(id, "%L", id, "COM_STATS_OFF") + console_print(id, "%L", id, "COM_STATS_SAVE") + console_print(id, "%L", id, "COM_STATS_LOAD") + console_print(id, "%L", id, "COM_STATS_LIST") + console_print(id, "%L", id, "COM_STATS_ADD") + } + + return PLUGIN_HANDLED +} + +public cmdCfgMenu(id, level, cid) +{ + if (cmd_access(id, level, cid, 1)) + displayCfgMenu(id, g_menuPosition[id] = 0) + + return PLUGIN_HANDLED +} + +displayCfgMenu(id, pos) +{ + if (pos < 0) + return + + new menu_body[512], start = pos * 7 + + if (start >= g_menuDataNum) + start = pos = g_menuPosition[id] = 0 + + new len = format(menu_body, charsmax(menu_body), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "STATS_CONF", pos + 1, ((g_menuDataNum / 7)+((g_menuDataNum % 7) ? 1 : 0))) + new end = start + 7, keys = MENU_KEY_0|MENU_KEY_8, k = 0 + + if (end > g_menuDataNum) + end = g_menuDataNum + + for (new a = start; a < end; ++a) + { + keys |= (1< +#include +#include +#include +//-------------------------------- + +// Uncomment to activate log debug messages. +//#define STATSX_DEBUG + +// HUD statistics duration in seconds (minimum 1.0 seconds). +#define HUD_DURATION_CVAR "amx_statsx_duration" +#define HUD_DURATION "12.0" + +// HUD statistics stop relative freeze end in seconds. +// To stop before freeze end use a negative value. +#define HUD_FREEZE_LIMIT_CVAR "amx_statsx_freeze" +#define HUD_FREEZE_LIMIT "-2.0" + +// HUD statistics minimum duration, in seconds, to trigger the display logic. +#define HUD_MIN_DURATION 0.2 + +// Config plugin constants. +#define MODE_HUD_DELAY 0 // Make a 0.1 sec delay on HUD reset process. + +// You can also manualy enable or disable these options by setting them to 1 +// For example: +// public ShowAttackers = 1 +// However amx_statscfg command is recommended + +public KillerChat = 0 // displays killer hp&ap to victim console + // and screen + +public ShowAttackers = 0 // shows attackers +public ShowVictims = 0 // shows victims +public ShowKiller = 0 // shows killer +public ShowTeamScore = 0 // shows team score at round end +public ShowTotalStats = 0 // shows round total stats +public ShowBestScore = 0 // shows rounds best scored player +public ShowMostDisruptive = 0 // shows rounds most disruptive player + +public EndPlayer = 0 // displays player stats at the end of map +public EndTop15 = 0 // displays top15 at the end of map + +public SayHP = 0 // displays information about user killer +public SayStatsMe = 0 // displays user's stats and rank +public SayRankStats = 0 // displays user's rank stats +public SayMe = 0 // displays user's stats +public SayRank = 0 // displays user's rank +public SayReport = 0 // report user's weapon status to team +public SayScore = 0 // displays team's map score +public SayTop15 = 0 // displays first 15 players +public SayStatsAll = 0 // displays all players stats and rank + +public ShowStats = 1 // set client HUD-stats switched off by default +public ShowDistHS = 0 // show distance and HS in attackers and + // victims HUD lists +public ShowFullStats = 0 // show full HUD stats (more than 78 chars) + +public SpecRankInfo = 0 // displays rank info when spectating + +// Standard Contstants. +#define MAX_TEAMS 2 +#define MAX_WEAPON_LENGTH 31 +#define MAX_TEXT_LENGTH 255 +#define MAX_BUFFER_LENGTH 2047 + +// Global player flags. +new BODY_PART[MAX_BODYHITS][] = +{ + "WHOLEBODY", + "HEAD", + "CHEST", + "STOMACH", + "LEFTARM", + "RIGHTARM", + "LEFTLEG", + "RIGHTLEG" +} + +// Killer information, save killer info at the time when player is killed. +#define KILLED_KILLER_ID 0 // Killer userindex/user-ID +#define KILLED_KILLER_HEALTH 1 // Killer's health +#define KILLED_KILLER_ARMOUR 2 // Killer's armour +#define KILLED_TEAM 3 // Killer's team +#define KILLED_KILLER_STATSFIX 4 // Fix to register the last hit/kill + +new g_izKilled[MAX_PLAYERS + 1][5] + +// Menu variables and configuration +#define MAX_PPL_MENU_ACTIONS 2 // Number of player menu actions +#define PPL_MENU_OPTIONS 7 // Number of player options per displayed menu + +new g_iPluginMode = 0 + +new g_izUserMenuPosition[MAX_PLAYERS + 1] = {0, ...} +new g_izUserMenuAction[MAX_PLAYERS + 1] = {0, ...} +new g_izUserMenuPlayers[MAX_PLAYERS + 1][MAX_PLAYERS] + +new g_izSpecMode[MAX_PLAYERS + 1] = {0, ...} + +new g_izShowStatsFlags[MAX_PLAYERS + 1] = {0, ...} +new g_izStatsSwitch[MAX_PLAYERS + 1] = {0, ...} +new Float:g_fzShowUserStatsTime[MAX_PLAYERS + 1] = {0.0, ...} +new Float:g_fShowStatsTime = 0.0 +new Float:g_fFreezeTime = 0.0 +new Float:g_fFreezeLimitTime = 0.0 +new Float:g_fHUDDuration = 0.0 + +new g_iRoundEndTriggered = 0 +new g_iRoundEndProcessed = 0 + +new g_pFreezeTime = 0 +new g_pRoundTime = 0 +new g_pHudDuration = 0 +new g_pHudFreezeLimit = 0 + +new Float:g_fStartGame = 0.0 +new g_izTeamScore[MAX_TEAMS] = {0, ...} +new g_izTeamEventScore[MAX_TEAMS] = {0, ...} +new g_izTeamRndStats[MAX_TEAMS][STATSX_MAX_STATS] +new g_izTeamGameStats[MAX_TEAMS][STATSX_MAX_STATS] +new g_izUserUserID[MAX_PLAYERS + 1] = {0, ...} +new g_izUserAttackerDistance[MAX_PLAYERS + 1] = {0, ...} +new g_izUserVictimDistance[MAX_PLAYERS + 1][MAX_PLAYERS + 1] +new g_izUserRndName[MAX_PLAYERS + 1][MAX_NAME_LENGTH] +new g_izUserRndStats[MAX_PLAYERS + 1][STATSX_MAX_STATS] +new g_izUserGameStats[MAX_PLAYERS + 1][STATSX_MAX_STATS] + +// Common buffer to improve performance, as Small always zero-initializes all vars +new g_sBuffer[MAX_BUFFER_LENGTH + 1] = "" +new g_sScore[MAX_TEXT_LENGTH + 1] = "" +new g_sAwardAndScore[MAX_BUFFER_LENGTH + 1] = "" + +new t_sText[MAX_TEXT_LENGTH + 1] = "" +new t_sName[MAX_NAME_LENGTH + 1] = "" +new t_sWpn[MAX_WEAPON_LENGTH + 1] = "" + +new g_HudSync_EndRound +new g_HudSync_SpecInfo + +//-------------------------------- +// Initialize +//-------------------------------- +public plugin_init() +{ + // Register plugin. + register_plugin("StatsX", AMXX_VERSION_STR, "AMXX Dev Team") + register_dictionary("statsx.txt") + + // Register events. + register_event("TextMsg", "eventStartGame", "a", "2=#Game_Commencing", "2=#Game_will_restart_in") + RegisterHamPlayer(Ham_Spawn, "eventSpawn", 1) + register_event("RoundTime", "eventStartRound", "bc") + register_event("SendAudio", "eventEndRound", "a", "2=%!MRAD_terwin", "2=%!MRAD_ctwin", "2=%!MRAD_rounddraw") + register_event("TeamScore", "eventTeamScore", "a") + register_event("30", "eventIntermission", "a") + register_event("TextMsg", "eventSpecMode", "bd", "2&ec_Mod") + register_event("StatusValue", "eventShowRank", "bd", "1=2") + + // Register commands. + register_clcmd("say /hp", "cmdHp", 0, "- display info. about your killer (chat)") + register_clcmd("say /statsme", "cmdStatsMe", 0, "- display your stats (MOTD)") + register_clcmd("say /rankstats", "cmdRankStats", 0, "- display your server stats (MOTD)") + register_clcmd("say /me", "cmdMe", 0, "- display current round stats (chat)") + register_clcmd("say /score", "cmdScore", 0, "- display last score (chat)") + register_clcmd("say /rank", "cmdRank", 0, "- display your rank (chat)") + register_clcmd("say /report", "cmdReport", 0, "- display weapon status (say_team)") + register_clcmd("say /top15", "cmdTop15", 0, "- display top 15 players (MOTD)") + register_clcmd("say /stats", "cmdStats", 0, "- display players stats (menu/MOTD)") + register_clcmd("say /switch", "cmdSwitch", 0, "- switch client's stats on or off") + register_clcmd("say_team /hp", "cmdHp", 0, "- display info. about your killer (chat)") + register_clcmd("say_team /statsme", "cmdStatsMe", 0, "- display your stats (MOTD)") + register_clcmd("say_team /rankstats", "cmdRankStats", 0, "- display your server stats (MOTD)") + register_clcmd("say_team /me", "cmdMe", 0, "- display current round stats (chat)") + register_clcmd("say_team /score", "cmdScore", 0, "- display last score (chat)") + register_clcmd("say_team /rank", "cmdRank", 0, "- display your rank (chat)") + register_clcmd("say_team /report", "cmdReport", 0, "- display weapon status (say_team_team)") + register_clcmd("say_team /top15", "cmdTop15", 0, "- display top 15 players (MOTD)") + register_clcmd("say_team /stats", "cmdStats", 0, "- display players stats (menu/MOTD)") + register_clcmd("say_team /switch", "cmdSwitch", 0, "- switch client's stats on or off") + + // Register menus. + register_menucmd(register_menuid("Server Stats"), 1023, "actionStatsMenu") + + // Register special configuration setting and default value. + register_srvcmd("amx_statsx_mode", "cmdPluginMode", ADMIN_CFG, " - sets plugin options") + +#if defined STATSX_DEBUG + register_clcmd("say /hudtest", "cmdHudTest") +#endif + + g_pHudDuration = register_cvar(HUD_DURATION_CVAR, HUD_DURATION) + g_pHudFreezeLimit = register_cvar(HUD_FREEZE_LIMIT_CVAR, HUD_FREEZE_LIMIT) + + g_pFreezeTime = get_cvar_pointer("mp_freezetime") + g_pRoundTime = get_cvar_pointer("mp_roundtime") + + // Init buffers and some global vars. + g_sBuffer[0] = 0 + + g_HudSync_EndRound = CreateHudSyncObj() + g_HudSync_SpecInfo = CreateHudSyncObj() +} + +public plugin_cfg() +{ + new addStast[] = "amx_statscfg add ^"%s^" %s" + + server_cmd(addStast, "ST_SHOW_KILLER_CHAT", "KillerChat") + server_cmd(addStast, "ST_SHOW_ATTACKERS", "ShowAttackers") + server_cmd(addStast, "ST_SHOW_VICTIMS", "ShowVictims") + server_cmd(addStast, "ST_SHOW_KILLER", "ShowKiller") + server_cmd(addStast, "ST_SHOW_TEAM_SCORE", "ShowTeamScore") + server_cmd(addStast, "ST_SHOW_TOTAL_STATS", "ShowTotalStats") + server_cmd(addStast, "ST_SHOW_BEST_SCORE", "ShowBestScore") + server_cmd(addStast, "ST_SHOW_MOST_DISRUPTIVE", "ShowMostDisruptive") + server_cmd(addStast, "ST_SHOW_HUD_STATS_DEF", "ShowStats") + server_cmd(addStast, "ST_SHOW_DIST_HS_HUD", "ShowDistHS") + server_cmd(addStast, "ST_STATS_PLAYER_MAP_END", "EndPlayer") + server_cmd(addStast, "ST_STATS_TOP15_MAP_END", "EndTop15") + server_cmd(addStast, "ST_SAY_HP", "SayHP") + server_cmd(addStast, "ST_SAY_STATSME", "SayStatsMe") + server_cmd(addStast, "ST_SAY_RANKSTATS", "SayRankStats") + server_cmd(addStast, "ST_SAY_ME", "SayMe") + server_cmd(addStast, "ST_SAY_RANK", "SayRank") + server_cmd(addStast, "ST_SAY_REPORT", "SayReport") + server_cmd(addStast, "ST_SAY_SCORE", "SayScore") + server_cmd(addStast, "ST_SAY_TOP15", "SayTop15") + server_cmd(addStast, "ST_SAY_STATS", "SayStatsAll") + server_cmd(addStast, "ST_SPEC_RANK", "SpecRankInfo") + + // Update local configuration vars with value in cvars. + get_config_cvars() +} + +// Set hudmessage format. +set_hudtype_killer(Float:fDuration) + set_hudmessage(220, 80, 0, 0.05, 0.15, 0, 6.0, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0, -1) + +set_hudtype_endround(Float:fDuration) +{ + set_hudmessage(100, 200, 0, 0.05, 0.55, 0, 0.02, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0) +} + +set_hudtype_attacker(Float:fDuration) + set_hudmessage(220, 80, 0, 0.55, 0.35, 0, 6.0, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0, -1) + +set_hudtype_victim(Float:fDuration) + set_hudmessage(0, 80, 220, 0.55, 0.60, 0, 6.0, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0, -1) + +set_hudtype_specmode() +{ + set_hudmessage(255, 255, 255, 0.02, 0.96, 2, 0.05, 0.1, 0.01, 3.0, -1) +} + +#if defined STATSX_DEBUG +public cmdHudTest(id) +{ + new i, iLen + iLen = 0 + + for (i = 1; i < 20; i++) + iLen += formatex(g_sBuffer[iLen], charsmax(g_sBuffer) - iLen, "....x....1....x....2....x....3....x....4....x....^n") + + set_hudtype_killer(50.0) + show_hudmessage(id, "%s", g_sBuffer) +} +#endif + +// Stats formulas +Float:accuracy(izStats[STATSX_MAX_STATS]) +{ + return izStats[STATSX_SHOTS] ? (100.0 * float(izStats[STATSX_HITS]) / float(izStats[STATSX_SHOTS])) : (0.0); +} + +Float:effec(izStats[STATSX_MAX_STATS]) +{ + return izStats[STATSX_KILLS] ? (100.0 * float(izStats[STATSX_KILLS]) / float(izStats[STATSX_KILLS] + izStats[STATSX_DEATHS])) : (0.0); +} + +// Distance formula (metric) +Float:distance(iDistance) +{ + return float(iDistance) * 0.0254 +} + +// Get plugin config flags. +set_plugin_mode(id, sFlags[]) +{ + if (sFlags[0]) + g_iPluginMode = read_flags(sFlags) + + get_flags(g_iPluginMode, t_sText, charsmax(t_sText)) + console_print(id, "%L", id, "MODE_SET_TO", t_sText) + + return g_iPluginMode +} + +// Get config parameters. +get_config_cvars() +{ + g_fFreezeTime = floatmax(get_pcvar_float(g_pFreezeTime), 0.0); + + g_fHUDDuration = floatmax(get_pcvar_float(g_pHudDuration), 1.0); + + g_fFreezeLimitTime = get_pcvar_float(g_pHudFreezeLimit) +} + +// Get and format attackers header and list. +get_attackers(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] + new iAttacker + new iFound, iLen + + iFound = 0 + sBuffer[0] = 0 + + // Get and format header. Add killing attacker statistics if user is dead. + // Make sure shots is greater than zero or division by zero will occur. + // To print a '%', 4 of them must done in a row. + izStats[STATSX_SHOTS] = 0 + iAttacker = g_izKilled[id][KILLED_KILLER_ID] + + if (iAttacker) + get_user_astats(id, iAttacker, izStats, izBody) + + if (izStats[STATSX_SHOTS] && ShowFullStats) + { + get_user_name(iAttacker, t_sName, charsmax(t_sName)) + iLen = formatex(sBuffer, charsmax(sBuffer), "%L -- %s -- %0.2f%% %L:^n", id, "ATTACKERS", t_sName, accuracy(izStats), id, "ACC") + } + else + iLen = formatex(sBuffer, charsmax(sBuffer), "%L:^n", id, "ATTACKERS") + + // Get and format attacker list. + for (iAttacker = 1; iAttacker <= MaxClients; iAttacker++) + { + if (get_user_astats(id, iAttacker, izStats, izBody, t_sWpn, charsmax(t_sWpn))) + { + iFound = 1 + get_user_name(iAttacker, t_sName, charsmax(t_sName)) + + if (izStats[STATSX_KILLS]) + { + if (!ShowDistHS) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn) + else if (izStats[STATSX_HEADSHOTS]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id])) + else + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id])) + } + else + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", izStats[STATSX_DAMAGE], id, "DMG") + } + } + + if (!iFound) + sBuffer[0] = 0 + + return iFound +} + +// Get and format victims header and list +get_victims(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] + new iVictim + new iFound, iLen + + iFound = 0 + sBuffer[0] = 0 + + // Get and format header. + // Make sure shots is greater than zero or division by zero will occur. + // To print a '%', 4 of them must done in a row. + izStats[STATSX_SHOTS] = 0 + get_user_vstats(id, 0, izStats, izBody) + + if (izStats[STATSX_SHOTS]) + iLen = formatex(sBuffer, charsmax(sBuffer), "%L -- %0.2f%% %L:^n", id, "VICTIMS", accuracy(izStats), id, "ACC") + else + iLen = formatex(sBuffer, charsmax(sBuffer), "%L:^n", id, "VICTIMS") + + for (iVictim = 1; iVictim <= MaxClients; iVictim++) + { + if (get_user_vstats(id, iVictim, izStats, izBody, t_sWpn, charsmax(t_sWpn))) + { + iFound = 1 + get_user_name(iVictim, t_sName, charsmax(t_sName)) + + if (izStats[STATSX_DEATHS]) + { + if (!ShowDistHS) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn) + else if (izStats[STATSX_HEADSHOTS]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim])) + else + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim])) + } + else + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", izStats[STATSX_DAMAGE], id, "DMG") + } + } + + if (!iFound) + sBuffer[0] = 0 + + return iFound +} + +// Get and format kill info. +get_kill_info(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iFound, iLen + + iFound = 0 + sBuffer[0] = 0 + + if (iKiller && iKiller != id) + { + new izAStats[STATSX_MAX_STATS], izABody[MAX_BODYHITS], izVStats[STATSX_MAX_STATS], iaVBody[MAX_BODYHITS] + + iFound = 1 + get_user_name(iKiller, t_sName, charsmax(t_sName)) + + izAStats[STATSX_HITS] = 0 + izAStats[STATSX_DAMAGE] = 0 + t_sWpn[0] = 0 + get_user_astats(id, iKiller, izAStats, izABody, t_sWpn, charsmax(t_sWpn)) + + izVStats[STATSX_HITS] = 0 + izVStats[STATSX_DAMAGE] = 0 + get_user_vstats(id, iKiller, izVStats, iaVBody) + + iLen = formatex(sBuffer, charsmax(sBuffer), "%L^n", id, "KILLED_YOU_DIST", t_sName, t_sWpn, distance(g_izUserAttackerDistance[id])) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L^n", id, "DID_DMG_HITS", izAStats[STATSX_DAMAGE], izAStats[STATSX_HITS], g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L^n", id, "YOU_DID_DMG", izVStats[STATSX_DAMAGE], izVStats[STATSX_HITS]) + } + + return iFound +} + +// Get and format most disruptive. +add_most_disruptive(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iPlayer, iMaxDamageId, iMaxDamage, iMaxHeadShots + + iMaxDamageId = 0 + iMaxDamage = 0 + iMaxHeadShots = 0 + + // Find player. + for (iPlayer = 1; iPlayer <= MaxClients; iPlayer++) + { + if (g_izUserRndStats[iPlayer][STATSX_DAMAGE] >= iMaxDamage && (g_izUserRndStats[iPlayer][STATSX_DAMAGE] > iMaxDamage || g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] > iMaxHeadShots)) + { + iMaxDamageId = iPlayer + iMaxDamage = g_izUserRndStats[iPlayer][STATSX_DAMAGE] + iMaxHeadShots = g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] + } + } + + // Format statistics. + if (iMaxDamageId) + { + iPlayer = iMaxDamageId + + new Float:fGameEff = effec(g_izUserGameStats[iPlayer]) + new Float:fRndAcc = accuracy(g_izUserRndStats[iPlayer]) + + formatex(t_sText, charsmax(t_sText), "%L: %s^n%d %L / %d %L -- %0.2f%% %L / %0.2f%% %L^n", id, "MOST_DMG", g_izUserRndName[iPlayer], + g_izUserRndStats[iPlayer][STATSX_HITS], id, "HIT_S", iMaxDamage, id, "DMG", fGameEff, id, "EFF", fRndAcc, id, "ACC") + add(sBuffer, charsmax(sBuffer), t_sText) + } + + return iMaxDamageId +} + +// Get and format best score. +add_best_score(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iPlayer, iMaxKillsId, iMaxKills, iMaxHeadShots + + iMaxKillsId = 0 + iMaxKills = 0 + iMaxHeadShots = 0 + + // Find player + for (iPlayer = 1; iPlayer <= MaxClients; iPlayer++) + { + if (g_izUserRndStats[iPlayer][STATSX_KILLS] >= iMaxKills && (g_izUserRndStats[iPlayer][STATSX_KILLS] > iMaxKills || g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] > iMaxHeadShots)) + { + iMaxKillsId = iPlayer + iMaxKills = g_izUserRndStats[iPlayer][STATSX_KILLS] + iMaxHeadShots = g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] + } + } + + // Format statistics. + if (iMaxKillsId) + { + iPlayer = iMaxKillsId + + new Float:fGameEff = effec(g_izUserGameStats[iPlayer]) + new Float:fRndAcc = accuracy(g_izUserRndStats[iPlayer]) + + formatex(t_sText, charsmax(t_sText), "%L: %s^n%d %L / %d hs -- %0.2f%% %L / %0.2f%% %L^n", id, "BEST_SCORE", g_izUserRndName[iPlayer], + iMaxKills, id, "KILL_S", iMaxHeadShots, fGameEff, id, "EFF", fRndAcc, id, "ACC") + add(sBuffer, charsmax(sBuffer), t_sText) + } + + return iMaxKillsId +} + +// Get and format team score. +add_team_score(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new Float:fzMapEff[MAX_TEAMS], Float:fzMapAcc[MAX_TEAMS], Float:fzRndAcc[MAX_TEAMS] + + // Calculate team stats + for (new iTeam = 0; iTeam < MAX_TEAMS; iTeam++) + { + fzMapEff[iTeam] = effec(g_izTeamGameStats[iTeam]) + fzMapAcc[iTeam] = accuracy(g_izTeamGameStats[iTeam]) + fzRndAcc[iTeam] = accuracy(g_izTeamRndStats[iTeam]) + } + + // Format round team stats, MOTD + formatex(t_sText, charsmax(t_sText), "TERRORIST %d / %0.2f%% %L / %0.2f%% %L^nCT %d / %0.2f%% %L / %0.2f%% %L^n", g_izTeamScore[0], + fzMapEff[0], id, "EFF", fzRndAcc[0], id, "ACC", g_izTeamScore[1], fzMapEff[1], id, "EFF", fzRndAcc[1], id, "ACC") + add(sBuffer, charsmax(sBuffer), t_sText) +} + +// Get and format team stats, chat version +save_team_chatscore(id, sBuffer[MAX_TEXT_LENGTH + 1]) +{ + new Float:fzMapEff[MAX_TEAMS], Float:fzMapAcc[MAX_TEAMS], Float:fzRndAcc[MAX_TEAMS] + + // Calculate team stats + for (new iTeam = 0; iTeam < MAX_TEAMS; iTeam++) + { + fzMapEff[iTeam] = effec(g_izTeamGameStats[iTeam]) + fzMapAcc[iTeam] = accuracy(g_izTeamGameStats[iTeam]) + fzRndAcc[iTeam] = accuracy(g_izTeamRndStats[iTeam]) + } + + // Format game team stats, chat + formatex(sBuffer, charsmax(sBuffer), "TERRORIST %d / %0.2f%% %L / %0.2f%% %L -- CT %d / %0.2f%% %L / %0.2f%% %L", g_izTeamScore[0], + fzMapEff[0], id, "EFF", fzMapAcc[0], id, "ACC", g_izTeamScore[1], fzMapEff[1], id, "EFF", fzMapAcc[1], id, "ACC") +} + +// Get and format total stats. +add_total_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + formatex(t_sText, charsmax(t_sText), "%L: %d %L / %d hs -- %d %L / %d %L^n", id, "TOTAL", g_izUserRndStats[0][STATSX_KILLS], id, "KILL_S", + g_izUserRndStats[0][STATSX_HEADSHOTS], g_izUserRndStats[0][STATSX_HITS], id, "HITS", g_izUserRndStats[0][STATSX_SHOTS], id, "SHOT_S") + add(sBuffer, charsmax(sBuffer), t_sText) +} + +// Get and format a user's list of body hits from an attacker. +add_attacker_hits(id, iAttacker, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iFound = 0 + + if (iAttacker && iAttacker != id) + { + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS], iLen + + izStats[STATSX_HITS] = 0 + get_user_astats(id, iAttacker, izStats, izBody) + + if (izStats[STATSX_HITS]) + { + iFound = 1 + iLen = strlen(sBuffer) + get_user_name(iAttacker, t_sName, charsmax(t_sName)) + + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L:^n", id, "HITS_YOU_IN", t_sName) + + for (new i = 1; i < sizeof(izBody); i++) + { + if (!izBody[i]) + continue + + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L: %d^n", id, BODY_PART[i], izBody[i]) + } + } + } + + return iFound +} + +// Get and format killed stats: killer hp, ap, hits. +format_kill_ainfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iFound = 0 + + if (iKiller && iKiller != id) + { + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] + new iLen + + iFound = 1 + get_user_name(iKiller, t_sName, charsmax(t_sName)) + izStats[STATSX_HITS] = 0 + get_user_astats(id, iKiller, izStats, izBody, t_sWpn, charsmax(t_sWpn)) + + iLen = formatex(sBuffer, charsmax(sBuffer), "%L (%dhp, %dap) >>", id, "KILLED_BY_WITH", t_sName, t_sWpn, distance(g_izUserAttackerDistance[id]), + g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR]) + + if (izStats[STATSX_HITS]) + { + for (new i = 1; i < sizeof(izBody); i++) + { + if (!izBody[i]) + continue + + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, " %L: %d", id, BODY_PART[i], izBody[i]) + } + } + else + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, " %L", id, "NO_HITS") + } + else + formatex(sBuffer, charsmax(sBuffer), "%L", id, "YOU_NO_KILLER") + + return iFound +} + +// Get and format killed stats: hits, damage on killer. +format_kill_vinfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iFound = 0 + new izStats[STATSX_MAX_STATS] + new izBody[MAX_BODYHITS] + new iLen + + izStats[STATSX_HITS] = 0 + izStats[STATSX_DAMAGE] = 0 + get_user_vstats(id, iKiller, izStats, izBody) + + if (iKiller && iKiller != id) + { + iFound = 1 + get_user_name(iKiller, t_sName, charsmax(t_sName)) + iLen = formatex(sBuffer, charsmax(sBuffer), "%L >>", id, "YOU_HIT", t_sName, izStats[STATSX_HITS], izStats[STATSX_DAMAGE]) + } + else + iLen = formatex(sBuffer, charsmax(sBuffer), "%L >>", id, "LAST_RES", izStats[STATSX_HITS], izStats[STATSX_DAMAGE]) + + if (izStats[STATSX_HITS]) + { + for (new i = 1; i < sizeof(izBody); i++) + { + if (!izBody[i]) + continue + + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, " %L: %d", id, BODY_PART[i], izBody[i]) + } + } + else + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, " %L", id, "NO_HITS") + + return iFound +} + +// Get and format top 15. +format_top15(id, sBuffer[MAX_BUFFER_LENGTH + 1]) +{ + new iMax = get_statsnum() + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] + new iLen = 0 + + if (iMax > 15) + iMax = 15 + + new lKills[16], lDeaths[16], lHits[16], lShots[16], lEff[16], lAcc[16] + + formatex(lKills, charsmax(lKills), "%L", id, "KILLS") + formatex(lDeaths, charsmax(lDeaths), "%L", id, "DEATHS") + formatex(lHits, charsmax(lHits), "%L", id, "HITS") + formatex(lShots, charsmax(lShots), "%L", id, "SHOTS") + formatex(lEff, charsmax(lEff), "%L", id, "EFF") + formatex(lAcc, charsmax(lAcc), "%L", id, "ACC") + + ucfirst(lEff) + ucfirst(lAcc) + + iLen = formatex(sBuffer, charsmax(sBuffer), "
")
+	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%2s %-22.22s %6s %6s %6s %6s %4s %4s %4s^n", "#", "Nick", lKills, lDeaths, lHits, lShots, "HS", lEff, lAcc)
+
+	for (new i = 0; i < iMax && charsmax(sBuffer) - iLen > 0; i++)
+	{
+		get_stats(i, izStats, izBody, t_sName, charsmax(t_sName))
+		replace_string(t_sName, charsmax(t_sName), "<", "[")
+		replace_string(t_sName, charsmax(t_sName), ">", "]")
+		iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%2d %-22.22s %6d %6d %6d %6d %4d %3.0f%% %3.0f%%^n", i + 1, t_sName, izStats[STATSX_KILLS],
+						izStats[STATSX_DEATHS], izStats[STATSX_HITS], izStats[STATSX_SHOTS], izStats[STATSX_HEADSHOTS], effec(izStats), accuracy(izStats))
+	}
+}
+
+// Get and format rank stats.
+format_rankstats(id, sBuffer[MAX_BUFFER_LENGTH + 1], iMyId = 0)
+{
+	new izStats[STATSX_MAX_STATS] = {0, ...}
+	new izBody[MAX_BODYHITS]
+	new iRankPos, iLen
+	new lKills[16], lDeaths[16], lHits[16], lShots[16], lDamage[16], lEff[16], lAcc[16]
+
+	formatex(lKills, charsmax(lKills), "%L", id, "KILLS")
+	formatex(lDeaths, charsmax(lDeaths), "%L", id, "DEATHS")
+	formatex(lHits, charsmax(lHits), "%L", id, "HITS")
+	formatex(lShots, charsmax(lShots), "%L", id, "SHOTS")
+	formatex(lDamage, charsmax(lDamage), "%L", id, "DAMAGE")
+	formatex(lEff, charsmax(lEff), "%L", id, "EFF")
+	formatex(lAcc, charsmax(lAcc), "%L", id, "ACC")
+
+	ucfirst(lEff)
+	ucfirst(lAcc)
+
+	iRankPos = get_user_stats(id, izStats, izBody)
+	iLen = formatex(sBuffer, charsmax(sBuffer), "
")
+	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L %L^n^n", id, (!iMyId || iMyId == id) ? "YOUR" : "PLAYERS", id, "RANK_IS", iRankPos, get_statsnum())
+	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%6s: %d  (%d with hs)^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %0.2f%%^n%6s: %0.2f%%^n^n",
+					lKills, izStats[STATSX_KILLS], izStats[STATSX_HEADSHOTS], lDeaths, izStats[STATSX_DEATHS], lHits, izStats[STATSX_HITS], lShots, izStats[STATSX_SHOTS],
+					lDamage, izStats[STATSX_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
+
+	new L_BODY_PART[MAX_BODYHITS][32]
+
+	for (new i = 1; i < sizeof(L_BODY_PART); i++)
+	{
+		formatex(L_BODY_PART[i], charsmax(L_BODY_PART[]), "%L", id, BODY_PART[i])
+	}
+
+	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%10s:^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d", "HITS",
+					L_BODY_PART[HIT_HEAD], izBody[HIT_HEAD], L_BODY_PART[HIT_CHEST], izBody[HIT_CHEST], L_BODY_PART[HIT_STOMACH], izBody[HIT_STOMACH], L_BODY_PART[HIT_LEFTARM], izBody[HIT_LEFTARM], L_BODY_PART[HIT_RIGHTARM],
+					izBody[HIT_RIGHTARM], L_BODY_PART[HIT_LEFTLEG], izBody[HIT_LEFTLEG], L_BODY_PART[HIT_RIGHTLEG], izBody[HIT_RIGHTLEG])
+}
+
+// Get and format stats.
+format_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1])
+{
+	new izStats[STATSX_MAX_STATS] = {0, ...}
+	new izBody[MAX_BODYHITS]
+	new iWeapon, iLen
+	new lKills[16], lDeaths[16], lHits[16], lShots[16], lDamage[16], lEff[16], lAcc[16], lWeapon[16]
+
+	formatex(lKills, charsmax(lKills), "%L", id, "KILLS")
+	formatex(lDeaths, charsmax(lDeaths), "%L", id, "DEATHS")
+	formatex(lHits, charsmax(lHits), "%L", id, "HITS")
+	formatex(lShots, charsmax(lShots), "%L", id, "SHOTS")
+	formatex(lDamage, charsmax(lDamage), "%L", id, "DAMAGE")
+	formatex(lEff, charsmax(lEff), "%L", id, "EFF")
+	formatex(lAcc, charsmax(lAcc), "%L", id, "ACC")
+	formatex(lWeapon, charsmax(lWeapon), "%L", id, "WEAPON")
+
+	ucfirst(lEff)
+	ucfirst(lAcc)
+
+	get_user_wstats(id, 0, izStats, izBody)
+
+	iLen = formatex(sBuffer, charsmax(sBuffer), "
")
+	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%6s: %d  (%d with hs)^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %0.2f%%^n%6s: %0.2f%%^n^n",
+					lKills, izStats[STATSX_KILLS], izStats[STATSX_HEADSHOTS], lDeaths, izStats[STATSX_DEATHS], lHits, izStats[STATSX_HITS], lShots, izStats[STATSX_SHOTS],
+					lDamage, izStats[STATSX_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
+	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%-12.12s  %6s  %6s  %6s  %6s  %6s  %4s^n", lWeapon, lKills, lDeaths, lHits, lShots, lDamage, lAcc)
+
+	for (iWeapon = 1; iWeapon < xmod_get_maxweapons() && charsmax(sBuffer) - iLen > 0 ; iWeapon++)
+	{
+		if (get_user_wstats(id, iWeapon, izStats, izBody))
+		{
+			xmod_get_wpnname(iWeapon, t_sWpn, charsmax(t_sWpn))
+			iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%-12.12s  %6d  %6d  %6d  %6d  %6d  %3.0f%%^n", t_sWpn, izStats[STATSX_KILLS], izStats[STATSX_DEATHS],
+							izStats[STATSX_HITS], izStats[STATSX_SHOTS], izStats[STATSX_DAMAGE], accuracy(izStats))
+		}
+	}
+}
+
+// Format round end stats
+format_roundend_hudstats(id, sBuffer[MAX_BUFFER_LENGTH + 1])
+{
+	sBuffer[0] = 0
+
+	// Create round awards.
+	if (ShowMostDisruptive)
+		add_most_disruptive(id, sBuffer)
+	if (ShowBestScore)
+		add_best_score(id, sBuffer)
+
+	// Create round score.
+	// Compensate HUD message if awards are disabled.
+	if (ShowTeamScore || ShowTotalStats)
+	{
+		if (ShowMostDisruptive && ShowBestScore)
+			add(sBuffer, charsmax(sBuffer), "^n^n")
+		else if (ShowMostDisruptive || ShowBestScore)
+			add(sBuffer, charsmax(sBuffer), "^n^n^n^n")
+		else
+			add(sBuffer, charsmax(sBuffer), "^n^n^n^n^n^n")
+
+		if (ShowTeamScore)
+			add_team_score(id, sBuffer)
+
+		if (ShowTotalStats)
+			add_total_stats(id, sBuffer)
+	}
+}
+
+// Show round end stats. If gametime is zero then use default duration time.
+show_roundend_hudstats(id, Float:fGameTime, sBuffer[MAX_BUFFER_LENGTH + 1])
+{
+	// Bail out if there no HUD stats should be shown
+	// for this player or end round stats not created.
+	if (!g_izStatsSwitch[id]) return
+	if (!sBuffer[0]) return
+
+	// If round end timer is zero clear round end stats.
+	if (g_fShowStatsTime == 0.0)
+	{
+		ClearSyncHud(id, g_HudSync_EndRound)
+#if defined STATSX_DEBUG
+		log_amx("Clear round end HUD stats for #%d", id)
+#endif
+	}
+
+	// Set HUD-duration to default or remaining time.
+	new Float:fDuration
+
+	if (fGameTime == 0.0)
+		fDuration = g_fHUDDuration
+	else
+	{
+		fDuration = g_fShowStatsTime + g_fHUDDuration - fGameTime
+
+		if (fDuration > g_fFreezeTime + g_fFreezeLimitTime)
+			fDuration = g_fFreezeTime + g_fFreezeLimitTime
+	}
+
+	// Show stats only if more time left than coded minimum.
+	if (fDuration >= HUD_MIN_DURATION)
+	{
+		set_hudtype_endround(fDuration)
+		ShowSyncHudMsg(id, g_HudSync_EndRound, "%s", sBuffer)
+#if defined STATSX_DEBUG
+		log_amx("Show %1.2fs round end HUD stats for #%d", fDuration, id)
+#endif
+	}
+}
+
+// Show round end stats.
+show_user_hudstats(id, Float:fGameTime)
+{
+	// Bail out if there no HUD stats should be shown
+	// for this player or user stats timer is zero.
+	if (!g_izStatsSwitch[id]) return
+	if (g_fzShowUserStatsTime[id] == 0.0) return
+
+	// Set HUD-duration to default or remaining time.
+	new Float:fDuration
+
+	if (fGameTime == 0.0)
+		fDuration = g_fHUDDuration
+	else
+	{
+		fDuration = g_fzShowUserStatsTime[id] + g_fHUDDuration - fGameTime
+
+		if (fDuration > g_fFreezeTime + g_fFreezeLimitTime)
+			fDuration = g_fFreezeTime + g_fFreezeLimitTime
+	}
+
+	// Show stats only if more time left than coded minimum.
+	if (fDuration >= HUD_MIN_DURATION)
+	{
+		if (ShowKiller)
+		{
+			new iKiller
+
+			iKiller = g_izKilled[id][KILLED_KILLER_ID]
+			get_kill_info(id, iKiller, g_sBuffer)
+			add_attacker_hits(id, iKiller, g_sBuffer)
+			set_hudtype_killer(fDuration)
+			show_hudmessage(id, "%s", g_sBuffer)
+#if defined STATSX_DEBUG
+			log_amx("Show %1.2fs %suser HUD k-stats for #%d", fDuration, g_sBuffer[0] ? "" : "no ", id)
+#endif
+		}
+
+		if (ShowVictims)
+		{
+			get_victims(id, g_sBuffer)
+			set_hudtype_victim(fDuration)
+			show_hudmessage(id, "%s", g_sBuffer)
+#if defined STATSX_DEBUG
+			log_amx("Show %1.2fs %suser HUD v-stats for #%d", fDuration, g_sBuffer[0] ? "" : "no ", id)
+#endif
+		}
+
+		if (ShowAttackers)
+		{
+			get_attackers(id, g_sBuffer)
+			set_hudtype_attacker(fDuration)
+			show_hudmessage(id, "%s", g_sBuffer)
+#if defined STATSX_DEBUG
+			log_amx("Show %1.2fs %suser HUD a-stats for #%d", fDuration, g_sBuffer[0] ? "" : "no ", id)
+#endif
+		}
+	}
+}
+
+//------------------------------------------------------------
+// Plugin commands
+//------------------------------------------------------------
+
+// Set or get plugin config flags.
+public cmdPluginMode(id, level, cid)
+{
+	if (!cmd_access(id, level, cid, 1))
+		return PLUGIN_HANDLED
+
+	if (read_argc() > 1)
+		read_argv(1, g_sBuffer, charsmax(g_sBuffer))
+	else
+		g_sBuffer[0] = 0
+
+	set_plugin_mode(id, g_sBuffer)
+
+	return PLUGIN_HANDLED
+}
+
+// Display MOTD stats.
+public cmdStatsMe(id)
+{
+	if (!SayStatsMe)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	format_stats(id, g_sBuffer)
+	get_user_name(id, t_sName, charsmax(t_sName))
+	show_motd(id, g_sBuffer, t_sName)
+
+	return PLUGIN_CONTINUE
+}
+
+// Display MOTD rank.
+public cmdRankStats(id)
+{
+	if (!SayRankStats)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	format_rankstats(id, g_sBuffer)
+	get_user_name(id, t_sName, charsmax(t_sName))
+	show_motd(id, g_sBuffer, t_sName)
+
+	return PLUGIN_CONTINUE
+}
+
+// Display MOTD top15 ranked.
+public cmdTop15(id)
+{
+	if (!SayTop15)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	format_top15(id, g_sBuffer)
+	show_motd(id, g_sBuffer, "Top 15")
+
+	return PLUGIN_CONTINUE
+}
+
+// Display killer information.
+public cmdHp(id)
+{
+	if (!SayHP)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	new iKiller = g_izKilled[id][KILLED_KILLER_ID]
+
+	format_kill_ainfo(id, iKiller, g_sBuffer)
+	client_print(id, print_chat, "* %s", g_sBuffer)
+
+	return PLUGIN_CONTINUE
+}
+
+// Display user stats.
+public cmdMe(id)
+{
+	if (!SayMe)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	format_kill_vinfo(id, 0, g_sBuffer)
+	client_print(id, print_chat, "* %s", g_sBuffer)
+
+	return PLUGIN_CONTINUE
+}
+
+// Display user rank
+public cmdRank(id)
+{
+	if (!SayRank)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS]
+	new iRankPos, iRankMax
+	new Float:fEff, Float:fAcc
+
+	iRankPos = get_user_stats(id, izStats, izBody)
+	iRankMax = get_statsnum()
+
+	fEff = effec(izStats)
+	fAcc = accuracy(izStats)
+
+	client_print(id, print_chat, "* %L", id, "YOUR_RANK_IS", iRankPos, iRankMax, izStats[STATSX_KILLS], izStats[STATSX_HITS], fEff, fAcc)
+
+	return PLUGIN_CONTINUE
+}
+
+// Report user weapon status to team.
+public cmdReport(id)
+{
+	if (!SayReport)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	new iWeapon, iClip, iAmmo, iHealth, iArmor
+
+	iWeapon = get_user_weapon(id, iClip, iAmmo)
+
+	if (iWeapon != 0)
+		xmod_get_wpnname(iWeapon, t_sWpn, charsmax(t_sWpn))
+
+	iHealth = get_user_health(id)
+	iArmor = get_user_armor(id)
+
+	new lWeapon[16]
+
+	formatex(lWeapon, charsmax(lWeapon), "%L", LANG_SERVER, "WEAPON")
+	strtolower(lWeapon)
+
+	if (iClip >= 0)
+	{
+		formatex(g_sBuffer, charsmax(g_sBuffer), "%s: %s, %L: %d/%d, %L: %d, %L: %d", lWeapon, t_sWpn, LANG_SERVER, "AMMO", iClip, iAmmo, LANG_SERVER, "HEALTH", iHealth, LANG_SERVER, "ARMOR", iArmor)
+	}
+	else
+		formatex(g_sBuffer, charsmax(g_sBuffer), "%s: %s, %L: %d, %L: %d", lWeapon, t_sWpn[7], LANG_SERVER, "HEALTH", iHealth, LANG_SERVER, "ARMOR", iArmor)
+
+	engclient_cmd(id, "say_team", g_sBuffer)
+
+	return PLUGIN_CONTINUE
+}
+
+// Display team map score
+public cmdScore(id)
+{
+	if (!SayScore)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	save_team_chatscore(id, g_sScore)
+	client_print(id, print_chat, "%L: %s", id, "GAME_SCORE", g_sScore)
+
+	return PLUGIN_CONTINUE
+}
+
+// Client switch to enable or disable stats announcements.
+public cmdSwitch(id)
+{
+	g_izStatsSwitch[id] = (g_izStatsSwitch[id]) ? 0 : -1
+	num_to_str(g_izStatsSwitch[id], t_sText, charsmax(t_sText))
+	client_cmd(id, "setinfo _amxstatsx %s", t_sText)
+
+	new lEnDis[32]
+
+	formatex(lEnDis, charsmax(lEnDis), "%L", id, g_izStatsSwitch[id] ? "ENABLED" : "DISABLED")
+	client_print(id, print_chat, "* %L", id, "STATS_ANNOUNCE", lEnDis)
+
+	return PLUGIN_CONTINUE
+}
+
+// Player stats menu.
+public cmdStats(id)
+{
+	if (!SayStatsAll)
+	{
+		client_print(id, print_chat, "%L", id, "DISABLED_MSG")
+		return PLUGIN_HANDLED
+	}
+
+	showStatsMenu(id, g_izUserMenuPosition[id] = 0)
+
+	return PLUGIN_CONTINUE
+}
+
+//--------------------------------
+// Menu
+//--------------------------------
+
+public actionStatsMenu(id, key)
+{
+	switch (key)
+	{
+		// Key '1' to '7', execute action on this option
+		case 0..6:
+		{
+			new iOption, iIndex
+			iOption = (g_izUserMenuPosition[id] * PPL_MENU_OPTIONS) + key
+
+			if (iOption >= 0 && iOption < 32)
+			{
+				iIndex = g_izUserMenuPlayers[id][iOption]
+
+				if (is_user_connected(iIndex))
+				{
+					switch (g_izUserMenuAction[id])
+					{
+						case 0: format_stats(iIndex, g_sBuffer)
+						case 1: format_rankstats(iIndex, g_sBuffer, id)
+						default: g_sBuffer[0] = 0
+					}
+
+					if (g_sBuffer[0])
+					{
+						get_user_name(iIndex, t_sName, charsmax(t_sName))
+						show_motd(id, g_sBuffer, t_sName)
+					}
+				}
+			}
+
+			showStatsMenu(id, g_izUserMenuPosition[id])
+		}
+		// Key '8', change action
+		case 7:
+		{
+			g_izUserMenuAction[id]++
+
+			if (g_izUserMenuAction[id] >= MAX_PPL_MENU_ACTIONS)
+				g_izUserMenuAction[id] = 0
+
+			showStatsMenu(id, g_izUserMenuPosition[id])
+		}
+		// Key '9', select next page of options
+		case 8: showStatsMenu(id, ++g_izUserMenuPosition[id])
+		// Key '10', cancel or go back to previous menu
+		case 9:
+		{
+			if (g_izUserMenuPosition[id] > 0)
+				showStatsMenu(id, --g_izUserMenuPosition[id])
+		}
+	}
+
+	return PLUGIN_HANDLED
+}
+
+new g_izUserMenuActionText[MAX_PPL_MENU_ACTIONS][] = {"Show stats", "Show rank stats"}
+
+showStatsMenu(id, iMenuPos)
+{
+	new iLen, iKeyMask, iPlayers
+	new iUserIndex, iMenuPosMax, iMenuOption, iMenuOptionMax
+
+	get_players(g_izUserMenuPlayers[id], iPlayers)
+	iMenuPosMax = ((iPlayers - 1) / PPL_MENU_OPTIONS) + 1
+
+	// If menu pos does not excist use last menu (if players has left)
+	if (iMenuPos >= iMenuPosMax)
+		iMenuPos = iMenuPosMax - 1
+
+	iUserIndex = iMenuPos * PPL_MENU_OPTIONS
+	iLen = formatex(g_sBuffer, charsmax(g_sBuffer), "\y%L\R%d/%d^n\w^n", id, "SERVER_STATS", iMenuPos + 1, iMenuPosMax)
+	iMenuOptionMax = iPlayers - iUserIndex
+
+	if (iMenuOptionMax > PPL_MENU_OPTIONS)
+		iMenuOptionMax = PPL_MENU_OPTIONS
+
+	for (iMenuOption = 0; iMenuOption < iMenuOptionMax; iMenuOption++)
+	{
+		get_user_name(g_izUserMenuPlayers[id][iUserIndex++], t_sName, charsmax(t_sName))
+		iKeyMask |= (1< iUserIndex)
+	{
+		iLen += formatex(g_sBuffer[iLen], charsmax(g_sBuffer) - iLen, "^n9. %L...", id, "MORE")
+		iKeyMask |= MENU_KEY_9
+	}
+
+	if (iMenuPos > 0)
+		iLen += formatex(g_sBuffer[iLen], charsmax(g_sBuffer) - iLen, "^n0. %L", id, "BACK")
+	else
+		iLen += formatex(g_sBuffer[iLen], charsmax(g_sBuffer) - iLen, "^n0. %L", id, "EXIT")
+
+	show_menu(id, iKeyMask, g_sBuffer, -1, "Server Stats")
+
+	return PLUGIN_HANDLED
+}
+
+//------------------------------------------------------------
+// Plugin events
+//------------------------------------------------------------
+
+// Reset game stats on game start and restart.
+public eventStartGame()
+{
+	read_data(2, t_sText, charsmax(t_sText))
+
+	if (t_sText[6] == 'w')
+	{
+		read_data(3, t_sText, charsmax(t_sText))
+		g_fStartGame = get_gametime() + float(str_to_num(t_sText))
+	}
+	else
+		g_fStartGame = get_gametime()
+
+	return PLUGIN_CONTINUE
+}
+
+// Round start
+public eventStartRound()
+{
+	new iTeam, id, i
+
+	new Float:roundtime = get_pcvar_float(g_pRoundTime)
+	if (read_data(1) >= floatround(roundtime * 60.0,floatround_floor) || (roundtime == 2.3 && read_data(1) == 137)) // these round too weird for it to work through pawn, have to add an exception for it
+	{
+#if defined STATSX_DEBUG
+		log_amx("Reset round stats")
+#endif
+
+		// Reset game stats on game start and restart.
+		if (g_fStartGame > 0.0 && g_fStartGame <= get_gametime())
+		{
+#if defined STATSX_DEBUG
+			log_amx("Reset game stats")
+#endif
+			g_fStartGame = 0.0
+
+			// Clear team and game stats.
+			for (iTeam = 0; iTeam < MAX_TEAMS; iTeam++)
+			{
+				g_izTeamEventScore[iTeam] = 0
+
+				for (i = 0; i < sizeof(g_izTeamGameStats[]); i++)
+					g_izTeamGameStats[iTeam][i] = 0
+			}
+
+			// Clear game stats, incl '0' that is sum of all users.
+			for (id = 0; id <= MaxClients; id++)
+			{
+				for (i = 0; i < sizeof(g_izUserGameStats[]); i++)
+					g_izUserGameStats[id][i] = 0
+			}
+		}
+
+		// Update team score with "TeamScore" event values and
+		// clear team round stats.
+		for (iTeam = 0; iTeam < MAX_TEAMS; iTeam++)
+		{
+			g_izTeamScore[iTeam] = g_izTeamEventScore[iTeam]
+
+			for (i = 0; i < sizeof(g_izTeamRndStats[]); i++)
+				g_izTeamRndStats[iTeam][i] = 0
+		}
+
+		// Clear user round stats, incl '0' that is sum of all users.
+		for (id = 0; id <= MaxClients; id++)
+		{
+			g_izUserRndName[id][0] = 0
+
+			for (i = 0; i < sizeof(g_izUserRndStats[]); i++)
+				g_izUserRndStats[id][i] = 0
+
+			g_fzShowUserStatsTime[id] = 0.0
+		}
+
+		// Allow end round stats and reset end round triggered indicator.
+		g_iRoundEndTriggered = 0
+		g_iRoundEndProcessed = 0
+		g_fShowStatsTime = 0.0
+
+		// Update local configuration vars with value in cvars.
+		get_config_cvars()
+	}
+
+	return PLUGIN_CONTINUE
+}
+
+// Reset killer info on round restart.
+public eventSpawn(id)
+{
+	if (!is_user_alive(id))
+		return HAM_IGNORED
+
+	new args[1]
+	args[0] = id
+
+	if (g_iPluginMode & MODE_HUD_DELAY)
+		set_task(0.1, "delay_spawn", 200 + id, args, sizeof(args))
+	else
+		delay_spawn(args)
+
+	return HAM_IGNORED
+}
+
+public delay_spawn(args[])
+{
+	new id = args[0]
+	new Float:fGameTime
+
+	// Show user and score round stats after spawn
+#if defined STATSX_DEBUG
+	log_amx("Spawn for #%d", id)
+#endif
+	fGameTime = get_gametime()
+	show_user_hudstats(id, fGameTime)
+
+	if (g_izStatsSwitch[id] && g_sAwardAndScore[0])
+	{
+		format_roundend_hudstats(id, g_sAwardAndScore)
+		show_roundend_hudstats(id, fGameTime, g_sAwardAndScore)
+	}
+
+	// Reset round stats
+	g_izKilled[id][KILLED_KILLER_ID] = 0
+	g_izKilled[id][KILLED_KILLER_STATSFIX] = 0
+	g_izShowStatsFlags[id] = -1		// Initialize flags
+	g_fzShowUserStatsTime[id] = 0.0
+	g_izUserAttackerDistance[id] = 0
+
+	for (new i = 1; i <= MaxClients; i++)
+		g_izUserVictimDistance[id][i] = 0
+
+	return PLUGIN_CONTINUE
+}
+
+// Save killer info on death.
+public client_death(killer, victim, wpnindex, hitplace, TK)
+{
+	// Bail out if no killer.
+	if (!killer)
+		return PLUGIN_CONTINUE
+
+	if (killer != victim)
+	{
+		new iaVOrigin[3], iaKOrigin[3]
+		new iDistance
+
+		get_user_origin(victim, iaVOrigin)
+		get_user_origin(killer, iaKOrigin)
+
+		g_izKilled[victim][KILLED_KILLER_ID] = killer
+		g_izKilled[victim][KILLED_KILLER_HEALTH] = get_user_health(killer)
+		g_izKilled[victim][KILLED_KILLER_ARMOUR] = get_user_armor(killer)
+		g_izKilled[victim][KILLED_KILLER_STATSFIX] = 0
+
+		iDistance = get_distance(iaVOrigin, iaKOrigin)
+		g_izUserAttackerDistance[victim] = iDistance
+		g_izUserVictimDistance[killer][victim] = iDistance
+	}
+
+	g_izKilled[victim][KILLED_TEAM] = get_user_team(victim)
+	g_izKilled[victim][KILLED_KILLER_STATSFIX] = 1
+
+	// Display kill stats for the player if round
+	// end stats was not processed.
+	if (!g_iRoundEndProcessed)
+		kill_stats(victim)
+
+	return PLUGIN_CONTINUE
+}
+
+// Display hudmessage stats on death.
+// This will also update all round and game stats.
+// Must be called at least once per round.
+kill_stats(id)
+{
+	// Bail out if user stats timer is non-zero,
+	// ie function already called.
+	if (g_fzShowUserStatsTime[id] > 0.0)
+	{
+		return
+	}
+
+	new team = get_user_team(id)
+	if (team < 1 || team > 2)
+	{
+		return
+	}
+
+	// Flag kill stats displayed for this player.
+	g_fzShowUserStatsTime[id] = get_gametime()
+
+	// Add user death stats to user round stats
+	new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS]
+	new iTeam, i
+	new iKiller
+
+	iKiller = g_izKilled[id][KILLED_KILLER_ID]
+
+	// Get user's team (if dead use the saved team)
+	if (iKiller)
+		iTeam = g_izKilled[id][KILLED_TEAM] - 1
+	else
+		iTeam = get_user_team(id) - 1
+
+	get_user_name(id, g_izUserRndName[id], charsmax(g_izUserRndName[]))
+
+	if (get_user_rstats(id, izStats, izBody))
+	{
+		// Update user's team round stats
+		if (iTeam >= 0 && iTeam < MAX_TEAMS)
+		{
+			for (i = 0; i < sizeof(izStats); i++)
+			{
+				g_izTeamRndStats[iTeam][i] += izStats[i]
+				g_izTeamGameStats[iTeam][i] += izStats[i]
+				g_izUserRndStats[0][i] += izStats[i]
+				g_izUserGameStats[0][i] += izStats[i]
+			}
+		}
+
+		// Update user's round stats
+		if (g_izUserUserID[id] == get_user_userid(id))
+		{
+			for (i = 0; i < sizeof(izStats); i++)
+			{
+				g_izUserRndStats[id][i] += izStats[i]
+				g_izUserGameStats[id][i] += izStats[i]
+			}
+		} else {
+			g_izUserUserID[id] = get_user_userid(id)
+
+			for (i = 0; i < sizeof(izStats); i++)
+			{
+				g_izUserRndStats[id][i] = izStats[i]
+				g_izUserGameStats[id][i] = izStats[i]
+			}
+		}
+
+	}	// endif (get_user_rstats())
+
+	// Report stats in the chat section, if player is killed.
+	if (KillerChat && iKiller && iKiller != id)
+	{
+		if (format_kill_ainfo(id, iKiller, g_sBuffer))
+		{
+			client_print(id, print_chat, "* %s", g_sBuffer)
+			format_kill_vinfo(id, iKiller, g_sBuffer)
+		}
+
+		client_print(id, print_chat, "* %s", g_sBuffer)
+	}
+
+	// Display player stats info.
+#if defined STATSX_DEBUG
+	log_amx("Kill stats for #%d", id)
+#endif
+	show_user_hudstats(id, 0.0)
+}
+
+public eventEndRound()
+{
+	// Update local configuration vars with value in cvars.
+	get_config_cvars()
+
+	// If first end round event in the round, calculate team score.
+	if (!g_iRoundEndTriggered)
+	{
+		read_data(2, t_sText, charsmax(t_sText))
+
+		if (t_sText[7] == 't')			// Terrorist wins
+			g_izTeamScore[0]++
+		else if (t_sText[7] == 'c')		// CT wins
+			g_izTeamScore[1]++
+	}
+
+	set_task(0.3, "ERTask", 997)
+
+	return PLUGIN_CONTINUE
+}
+
+public ERTask()
+{
+	// Flag round end triggered.
+	g_iRoundEndTriggered = 1
+
+	// Display round end stats to all players.
+	endround_stats()
+}
+
+endround_stats()
+{
+	// Bail out if end round stats has already been processed
+	// or round end not triggered.
+	if (g_iRoundEndProcessed || !g_iRoundEndTriggered)
+		return
+
+	new iaPlayers[MAX_PLAYERS], iPlayer, iPlayers, id
+
+	get_players(iaPlayers, iPlayers)
+
+	// Display attacker & victim list for all living players.
+	// This will also update all round and game stats for all players
+	// not killed.
+#if defined STATSX_DEBUG
+	log_amx("End round stats")
+#endif
+
+	// Get and save round end stats time.
+	g_fShowStatsTime = get_gametime()
+
+	for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
+	{
+		id = iaPlayers[iPlayer]
+
+		if (g_fzShowUserStatsTime[id] == 0.0)
+		{
+			kill_stats(id)
+		}
+
+		if (!g_izStatsSwitch[id])
+			continue
+
+		format_roundend_hudstats(id, g_sAwardAndScore)
+		show_roundend_hudstats(id, 0.0, g_sAwardAndScore)
+	}
+
+	// Flag round end processed.
+	g_iRoundEndProcessed = 1
+}
+
+public eventTeamScore()
+{
+	new sTeamID[1 + 1], iTeamScore
+	read_data(1, sTeamID, charsmax(sTeamID))
+	iTeamScore = read_data(2)
+	g_izTeamEventScore[(sTeamID[0] == 'C') ? 1 : 0] = iTeamScore
+
+	return PLUGIN_CONTINUE
+}
+
+public eventIntermission()
+{
+	if (EndPlayer || EndTop15)
+		set_task(1.0, "end_game_stats", 900)
+}
+
+public end_game_stats()
+{
+	new iaPlayers[MAX_PLAYERS], iPlayer, iPlayers, id
+
+	if (EndPlayer)
+	{
+		get_players(iaPlayers, iPlayers)
+
+		for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
+		{
+			id = iaPlayers[iPlayer]
+
+			if (!g_izStatsSwitch[id])
+				continue	// Do not show any stats
+
+			cmdStatsMe(id)
+		}
+	}
+	else if (EndTop15)
+	{
+		get_players(iaPlayers, iPlayers)
+		format_top15(0, g_sBuffer)
+
+		for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
+		{
+			id = iaPlayers[iPlayer]
+
+			if (!g_izStatsSwitch[id])
+				continue	// Do not show any stats
+
+			show_motd(id, g_sBuffer, "Top 15")
+		}
+	}
+
+	return PLUGIN_CONTINUE
+}
+
+public eventSpecMode(id)
+{
+	new sData[12]
+	read_data(2, sData, charsmax(sData))
+	g_izSpecMode[id] = (sData[10] == '2')
+
+	return PLUGIN_CONTINUE
+}
+
+public eventShowRank(id)
+{
+	if (SpecRankInfo && g_izSpecMode[id])
+	{
+		new iPlayer = read_data(2)
+
+		if (is_user_connected(iPlayer))
+		{
+			new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS]
+			new iRankPos, iRankMax
+
+			get_user_name(iPlayer, t_sName, charsmax(t_sName))
+
+			iRankPos = get_user_stats(iPlayer, izStats, izBody)
+			iRankMax = get_statsnum()
+
+			set_hudtype_specmode()
+			ShowSyncHudMsg(id, g_HudSync_SpecInfo, "%L", id, "X_RANK_IS", t_sName, iRankPos, iRankMax)
+		}
+	}
+
+	return PLUGIN_CONTINUE
+}
+
+public client_connect(id)
+{
+	if (ShowStats)
+	{
+		get_user_info(id, "_amxstatsx", t_sText, charsmax(t_sText))
+		g_izStatsSwitch[id] = (t_sText[0]) ? str_to_num(t_sText) : -1
+	}
+	else
+		g_izStatsSwitch[id] = 0
+
+	g_izKilled[id][KILLED_KILLER_ID] = 0
+	g_izKilled[id][KILLED_KILLER_STATSFIX] = 0
+	g_izShowStatsFlags[id] = 0		// Clear all flags
+	g_fzShowUserStatsTime[id] = 0.0
+
+	return PLUGIN_CONTINUE
+}
diff --git a/amxmodx/scripting/sys_timing.sma b/amxmodx/scripting/sys_timing.sma
new file mode 100644
index 0000000..1fab8d6
--- /dev/null
+++ b/amxmodx/scripting/sys_timing.sma
@@ -0,0 +1,90 @@
+#include amxmodx
+#include amxmisc
+#define MAX_PLAYERS 32
+new g_iHeadcount, g_timing, g_iTic_quota, g_iTic_sleep, g_iTic;
+
+/*
+ * Experimental for any OS but Linux gets the higher numbers with pingboost.
+ * DO NOT put sys_ticrate anywhere as a parameter on the server launch code.
+*/
+
+public plugin_init()
+
+{
+    register_plugin("Variable sys_ticrate", "A", ".sρiηX҉.");
+    
+    g_timing     = register_cvar("sys_timing",  "1"); //0|1 disables|enables plugin.
+    g_iTic_sleep = register_cvar("sys_sleep",  "32"); //Tic hibernation rate.
+    g_iTic_quota = register_cvar("sys_quota", "312"); //Tic rate quota.
+    g_iTic       = get_cvar_pointer("sys_ticrate"); //Base tic rate. Only used to launch server with.
+
+}
+
+
+public client_putinserver(id)
+
+{
+    if (get_pcvar_num(g_timing) == 1)
+    {
+    new iAlloted_Tic;
+
+    if( is_user_connected(id) && (!is_user_bot(id)) && (iPlayers() >= 1) ) {
+
+        iAlloted_Tic = (iPlayers() * get_pcvar_num(g_iTic_quota) )
+        
+        set_pcvar_num(g_iTic,iAlloted_Tic)
+        
+        }
+    }
+}
+
+/*
+ * 
+ * name: client_disconnect(id) or client_disconnected(id)
+ * @param depends on what flavor of amxx you use.
+ * @return triggers Sys_ticrate adjustments when players leave.
+ * 
+ */
+
+    #if AMXX_VERSION_NUM < 183;
+
+public client_disconnect(id)
+
+    #else
+
+public client_disconnected(id)
+
+    #endif
+    {
+    if (get_pcvar_num(g_timing) == 1){
+    if (iPlayers() < 2){
+        set_pcvar_num(g_iTic,get_pcvar_num(g_iTic_sleep));
+        }
+            else client_putinserver(id);
+    }
+}
+
+/*
+ * 
+ * name: stock iPlayers()
+ * @param depends on what flavor of amxx you use.
+ * @return total number of humans on multi-player.
+ * 
+ */
+
+stock iPlayers()
+
+{
+    #if AMXX_VERSION_NUM == 182;
+        new players[ MAX_PLAYERS ],pNum
+        get_players(players,pNum,"ch")
+        g_iHeadcount = pNum;
+
+    #else
+
+        g_iHeadcount = get_playersnum_ex(GetPlayersFlags:GetPlayers_ExcludeBots)
+
+    #endif
+
+    return g_iHeadcount
+}
diff --git a/amxmodx/scripting/telemenu.sma b/amxmodx/scripting/telemenu.sma
new file mode 100755
index 0000000..37fc820
--- /dev/null
+++ b/amxmodx/scripting/telemenu.sma
@@ -0,0 +1,231 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+//     https://alliedmods.net/amxmodx-license
+
+//
+// Teleport Menu Plugin
+//
+
+#include 
+#include 
+#include 
+
+new g_menuPosition[MAX_PLAYERS + 1]
+new g_menuPlayers[MAX_PLAYERS + 1][MAX_PLAYERS]
+new g_menuPlayersNum[MAX_PLAYERS + 1]
+new g_menuOption[MAX_PLAYERS + 1] = {-1, ...}
+new Float:g_menuOrigin[MAX_PLAYERS + 1][3]
+new Float:g_menuVAngle[MAX_PLAYERS + 1][3]
+new g_coloredMenus
+
+new g_bDuckingStateSaved
+#define SaveInDuckingState(%1)		g_bDuckingStateSaved |= 1<<(%1&31)
+#define SaveNoDuckingState(%1)		g_bDuckingStateSaved &= ~(1<<(%1&31))
+#define HasInDuckingStateSaved(%1)	g_bDuckingStateSaved & 1<<(%1&31)
+
+public plugin_init()
+{
+	register_plugin("Teleport Menu", AMXX_VERSION_STR, "AMXX Dev Team")
+	register_dictionary("telemenu.txt")
+	register_dictionary("common.txt")
+	register_clcmd("amx_teleportmenu", "cmdTelMenu", ADMIN_CFG, "- displays teleport menu")
+	register_menucmd(register_menuid("Teleport Menu"), 1023, "actionTelMenu")
+
+	g_coloredMenus = colored_menus()
+}
+
+public actionTelMenu(id, key)
+{
+	switch (key)
+	{
+		case 6:
+		{
+			g_menuOption[id] = 1 - g_menuOption[id]
+			displayTelMenu(id, g_menuPosition[id])
+		}
+		case 7:
+		{
+			if (g_menuOption[id] < 0)	/* unlocking position for the first time */
+				g_menuOption[id] = 0
+
+			getTeleportData(id, g_menuOrigin[id], g_menuVAngle[id])
+
+			if (pev(id, pev_flags) & FL_DUCKING && is_user_alive(id))
+				SaveInDuckingState(id)
+			else
+				SaveNoDuckingState(id)
+
+			displayTelMenu(id, g_menuPosition[id])
+		}
+		case 8: displayTelMenu(id, ++g_menuPosition[id])
+		case 9: displayTelMenu(id, --g_menuPosition[id])
+		default:
+		{
+			new player = g_menuPlayers[id][g_menuPosition[id] * 6 + key]
+			new name2[MAX_NAME_LENGTH]
+
+			get_user_name(player, name2, charsmax(name2))
+
+			if (!is_user_alive(player))
+			{
+				client_print(id, print_chat, "%L", id, "CANT_PERF_DEAD", name2)
+				displayTelMenu(id, g_menuPosition[id])
+				return PLUGIN_HANDLED
+			}
+
+			if (g_menuOption[id] > 0)
+			{
+				if (HasInDuckingStateSaved(id))
+				{
+					static Float:VEC_DUCK_VIEW[3] = {0.0, 0.0, -1.0}
+
+					if (VEC_DUCK_VIEW[2] == -1.0)
+					{
+						new modname[16]
+
+						get_modname(modname, charsmax(modname))
+						if (equal(modname, "cstrike")	// Counter-Strike 1.6
+						|| equal(modname, "czero")	// Counter-Strike: Condition Zero
+						|| equal(modname, "valve")	// Half-Life
+						|| equal(modname, "tfc")	// Team Fortress Classic
+						|| equal(modname, "gearbox"))	// Half-Life: Opposing Force
+							VEC_DUCK_VIEW[2] = 12.0
+						else if (equal(modname, "dod"))	// Day of Defeat
+							VEC_DUCK_VIEW[2] = 18.0
+						else if (equal(modname, "ts"))	// The Specialists
+							VEC_DUCK_VIEW[2] = 16.0
+						else
+							VEC_DUCK_VIEW[2] = 0.0
+					}
+					if (VEC_DUCK_VIEW[2] > 0.0)
+					{
+						set_pev(id, pev_flags, pev(id, pev_flags) | FL_DUCKING)
+						set_pev(id, pev_view_ofs, VEC_DUCK_VIEW)
+					}
+				}
+				doTeleport(player, g_menuOrigin[id], g_menuVAngle[id])
+			} else {
+				new Float:origin[3], Float:vAngle[3]
+
+				getTeleportData(id, origin, vAngle)
+				doTeleport(player, origin, vAngle)
+			}
+
+			new authid[32], authid2[32], name[MAX_NAME_LENGTH]
+
+			get_user_authid(id, authid, charsmax(authid))
+			get_user_authid(player, authid2, charsmax(authid2))
+			get_user_name(id, name, charsmax(name))
+
+			log_amx("Cmd: ^"%s<%d><%s><>^" teleport ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, name2, get_user_userid(player), authid2)
+
+			show_activity_key("ADMIN_TELEPORT_1", "ADMIN_TELEPORT_2", name, name2)
+
+			displayTelMenu(id, g_menuPosition[id])
+		}
+	}
+
+	return PLUGIN_HANDLED
+}
+
+getTeleportData(id, Float:origin[3], Float:vAngle[3])
+{
+	pev(id, pev_origin, origin)
+	pev(id, pev_v_angle, vAngle)
+}
+
+doTeleport(id, const Float:origin[3], const Float:vAngle[3])
+{
+	engfunc(EngFunc_SetOrigin, id, origin)
+	set_pev(id, pev_angles, vAngle)
+	set_pev(id, pev_fixangle, 1)
+}
+
+displayTelMenu(id, pos)
+{
+	if (pos < 0)
+		return
+
+	get_players(g_menuPlayers[id], g_menuPlayersNum[id])
+
+	new menuBody[512]
+	new b = 0
+	new i
+	new name[MAX_NAME_LENGTH]
+	new start = pos * 6
+	new bool:blockMenu = (is_user_alive(id) && g_menuOption[id] < 1) ? true : false
+
+	if (start >= g_menuPlayersNum[id])
+		start = pos = g_menuPosition[id] = 0
+
+	new len = formatex(menuBody, charsmax(menuBody), g_coloredMenus ? "\y%L\R%d/%d^n\w^n" : "%L %d/%d^n^n", id, "TELE_MENU", pos + 1, (g_menuPlayersNum[id] / 6 + ((g_menuPlayersNum[id] % 6) ? 1 : 0)))
+	new end = start + 6
+	new keys = MENU_KEY_0|MENU_KEY_8
+
+	if (end > g_menuPlayersNum[id])
+		end = g_menuPlayersNum[id]
+
+	for (new a = start; a < end; ++a)
+	{
+		i = g_menuPlayers[id][a]
+		get_user_name(i, name, charsmax(name))
+
+		if (blockMenu || !is_user_alive(i) || (id != i && get_user_flags(i) & ADMIN_IMMUNITY))
+		{
+			++b
+
+			if (g_coloredMenus)
+				len += formatex(menuBody[len], charsmax(menuBody)-len, "\d%d. %s^n\w", b, name)
+			else
+				len += formatex(menuBody[len], charsmax(menuBody)-len, "#. %s^n", name)
+		} else {
+			keys |= (1< 0)	// 1
+	{
+		keys |= MENU_KEY_7
+		len += formatex(menuBody[len], charsmax(menuBody)-len, "^n7. To location: %.0f %.0f %.0f^n", g_menuOrigin[id][0], g_menuOrigin[id][1], g_menuOrigin[id][2])
+	}
+	else if (g_menuOption[id])	// -1
+	{
+		if (g_coloredMenus)
+			len += formatex(menuBody[len], charsmax(menuBody)-len, "^n\d7. %L^n\w", id, "CUR_LOC")
+		else
+			len += formatex(menuBody[len], charsmax(menuBody)-len, "^n#. %L^n", id, "CUR_LOC")
+	} else {					// 0
+		keys |= MENU_KEY_7
+		len += formatex(menuBody[len], charsmax(menuBody)-len, "^n7. %L^n", id, "CUR_LOC")
+	}
+
+	len += formatex(menuBody[len], charsmax(menuBody)-len, "8. %L^n", id, "SAVE_LOC")
+
+	if (end != g_menuPlayersNum[id])
+	{
+		formatex(menuBody[len], charsmax(menuBody)-len, "^n9. %L...^n0. %L", id, "MORE", id, pos ? "BACK" : "EXIT")
+		keys |= MENU_KEY_9
+	}
+	else
+		formatex(menuBody[len], charsmax(menuBody)-len, "^n0. %L", id, pos ? "BACK" : "EXIT")
+
+	show_menu(id, keys, menuBody, -1, "Teleport Menu")
+}
+
+public cmdTelMenu(id, level, cid)
+{
+	if (cmd_access(id, level, cid, 1))
+		displayTelMenu(id, g_menuPosition[id] = 0)
+
+	return PLUGIN_HANDLED
+}
diff --git a/amxmodx/scripting/timeleft.sma b/amxmodx/scripting/timeleft.sma
new file mode 100755
index 0000000..e03b77a
--- /dev/null
+++ b/amxmodx/scripting/timeleft.sma
@@ -0,0 +1,272 @@
+// vim: set ts=4 sw=4 tw=99 noet:
+//
+// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
+// Copyright (C) The AMX Mod X Development Team.
+//
+// This software is licensed under the GNU General Public License, version 3 or higher.
+// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
+//     https://alliedmods.net/amxmodx-license
+
+//
+// TimeLeft Plugin
+//
+
+#include 
+
+const TASK_TIMEREMAIN_SHORT = 8648458	// 0.8s repeat task
+const TASK_TIMEREMAIN_LARGE = 34543		// 1.0s repeat task
+
+// time display flags
+const TD_BOTTOM_WHITE_TEXT = 1			// a - display white text on bottom
+const TD_USE_VOICE = 2					// b - use voice
+const TD_NO_REMAINING_VOICE = 4			// c - don't add "remaining" (only in voice)
+const TD_NO_HOURS_MINS_SECS_VOICE = 8		// d - don't add "hours/minutes/seconds" (only in voice)
+const TD_SHOW_SPEAK_VALUES_BELOW = 16	// e - show/speak if current time is less than this set in parameter
+
+new g_TimeSet[32][2]
+new g_LastTime
+new g_CountDown
+new g_Switch
+
+// pcvars
+new g_amx_time_voice, g_amx_timeleft
+new g_mp_timelimit
+
+public plugin_init()
+{
+	register_plugin("TimeLeft", AMXX_VERSION_STR, "AMXX Dev Team")
+	register_dictionary("timeleft.txt")
+	g_amx_time_voice = register_cvar("amx_time_voice", "1")
+	register_srvcmd("amx_time_display", "setDisplaying")
+	g_amx_timeleft = register_cvar("amx_timeleft", "00:00", FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_UNLOGGED|FCVAR_SPONLY)
+	register_clcmd("say timeleft", "sayTimeLeft", 0, "- displays timeleft")
+	register_clcmd("say thetime", "sayTheTime", 0, "- displays current time")
+	
+	set_task(0.8, "timeRemain", TASK_TIMEREMAIN_SHORT, "", 0, "b")
+
+	g_mp_timelimit = get_cvar_pointer("mp_timelimit")
+}
+
+public sayTheTime(id)
+{
+	if (get_pcvar_num(g_amx_time_voice))
+	{
+		new mhours[6], mmins[6], whours[32], wmins[32], wpm[6]
+		
+		get_time("%H", mhours, charsmax(mhours))
+		get_time("%M", mmins, charsmax(mmins))
+		
+		new mins = str_to_num(mmins)
+		new hrs = str_to_num(mhours)
+		
+		if (mins)
+			num_to_word(mins, wmins, charsmax(wmins))
+		else
+			wmins[0] = EOS
+		
+		if (hrs < 12)
+			wpm = "am "
+		else
+		{
+			if (hrs > 12) hrs -= 12
+			wpm = "pm "
+		}
+
+		if (hrs) 
+			num_to_word(hrs, whours, charsmax(whours))
+		else
+			whours = "twelve "
+		
+		client_cmd(id, "spk ^"fvox/time_is_now %s_period %s%s^"", whours, wmins, wpm)
+	}
+	
+	new ctime[64]
+	
+	get_time("%m/%d/%Y - %H:%M:%S", ctime, charsmax(ctime))
+	client_print(0, print_chat, "%L:   %s", LANG_PLAYER, "THE_TIME", ctime)
+	
+	return PLUGIN_CONTINUE
+}
+
+public sayTimeLeft(id)
+{
+	if (get_pcvar_float(g_mp_timelimit))
+	{
+		new a = get_timeleft()
+		
+		if (get_pcvar_num(g_amx_time_voice))
+		{
+			new svoice[128]
+			setTimeVoice(svoice, charsmax(svoice), 0, a)
+			client_cmd(id, "%s", svoice)
+		}
+		client_print(0, print_chat, "%L:  %d:%02d", LANG_PLAYER, "TIME_LEFT", (a / 60), (a % 60))
+	}
+	else
+		client_print(0, print_chat, "%L", LANG_PLAYER, "NO_T_LIMIT")
+	
+	return PLUGIN_CONTINUE
+}
+
+setTimeText(text[], len, tmlf, id)
+{
+	new secs = tmlf % 60
+	new mins = tmlf / 60
+	
+	if (secs == 0)
+		formatex(text, len, "%d %L", mins, id, (mins > 1) ? "MINUTES" : "MINUTE")
+	else if (mins == 0)
+		formatex(text, len, "%d %L", secs, id, (secs > 1) ? "SECONDS" : "SECOND")
+	else
+		formatex(text, len, "%d %L %d %L", mins, id, (mins > 1) ? "MINUTES" : "MINUTE", secs, id, (secs > 1) ? "SECONDS" : "SECOND")
+}
+
+setTimeVoice(text[], len, flags, tmlf)
+{
+	new temp[7][32]
+	new secs = tmlf % 60
+	new mins = tmlf / 60
+	
+	// for (new a = 0;a < 7;++a) // we just created it, already null
+		// temp[a][0] = 0
+
+	if (secs > 0)
+	{
+		num_to_word(secs, temp[4], charsmax(temp[]))
+		
+		if ( ~flags & TD_NO_HOURS_MINS_SECS_VOICE ) 
+			temp[5] = "seconds "	/* there is no "second" in default hl */
+	}
+	
+	if (mins > 59)
+	{
+		new hours = mins / 60
+		
+		num_to_word(hours, temp[0], charsmax(temp[]))
+		
+		if ( ~flags & TD_NO_HOURS_MINS_SECS_VOICE )
+			temp[1] = "hours "
+		
+		mins = mins % 60
+	}
+	
+	if (mins > 0)
+	{
+		num_to_word(mins, temp[2], charsmax(temp[]))
+		
+		if ( ~flags & TD_NO_HOURS_MINS_SECS_VOICE )
+			temp[3] = "minutes "
+	}
+	
+	if ( ~flags & TD_NO_REMAINING_VOICE )
+		temp[6] = "remaining "
+	
+	return formatex(text, len, "spk ^"vox/%s%s%s%s%s%s%s^"", temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6])
+}
+
+findDispFormat(_time)
+{
+	// it is important to check i _time)
+			{
+				if (!g_Switch)
+				{
+					g_CountDown = g_Switch = _time
+					remove_task(TASK_TIMEREMAIN_SHORT)
+					set_task(1.0, "timeRemain", TASK_TIMEREMAIN_LARGE, "", 0, "b")
+				}
+				
+				return i
+			}
+		}
+		else if (g_TimeSet[i][0] == _time)
+		{
+			return i
+		}
+	}
+	
+	return -1
+}
+
+public setDisplaying()
+{
+	new arg[32], flags[32], num[32]
+	new argc = read_argc() - 1
+	new i = 0
+
+	while (i < argc && i < sizeof(g_TimeSet))
+	{
+		read_argv(i + 1, arg, charsmax(arg))
+		parse(arg, flags, charsmax(flags), num, charsmax(num))
+		
+		g_TimeSet[i][0] = str_to_num(num)
+		g_TimeSet[i][1] = read_flags(flags)
+		
+		i++
+	}
+
+	if( i < sizeof(g_TimeSet) )
+		g_TimeSet[i][0] = 0 // has to be zeroed in case command is sent twice
+	
+	return PLUGIN_HANDLED
+}
+
+public timeRemain(param[])
+{
+	new gmtm = get_timeleft()
+	new tmlf = g_Switch ? --g_CountDown : gmtm
+	new stimel[12]
+	
+	formatex(stimel, charsmax(stimel), "%02d:%02d", gmtm / 60, gmtm % 60)
+	set_pcvar_string(g_amx_timeleft, stimel)
+	
+	if (g_Switch && gmtm > g_Switch)
+	{
+		remove_task(TASK_TIMEREMAIN_LARGE)
+		g_Switch = 0
+		set_task(0.8, "timeRemain", TASK_TIMEREMAIN_SHORT, "", 0, "b")
+		
+		return
+	}
+
+	if (tmlf > 0 && g_LastTime != tmlf)
+	{
+		g_LastTime = tmlf
+		new tm_set = findDispFormat(tmlf)
+		
+		if (tm_set != -1)
+		{
+			new flags = g_TimeSet[tm_set][1]
+			new arg[128]
+			
+			if (flags & TD_BOTTOM_WHITE_TEXT)
+			{
+				new players[MAX_PLAYERS], pnum, plr
+				
+				get_players(players, pnum, "c")
+
+				if (flags & TD_SHOW_SPEAK_VALUES_BELOW) // yes this is correct flag, just because message should be shorter if it is shown every seconds
+					set_hudmessage(255, 255, 255, -1.0, 0.85, 0, 0.0, 1.1, 0.1, 0.5, -1)
+				else
+					set_hudmessage(255, 255, 255, -1.0, 0.85, 0, 0.0, 3.0, 0.0, 0.5, -1)
+					
+				for (new i = 0; i < pnum; i++)
+				{
+					plr = players[i]
+					setTimeText(arg, charsmax(arg), tmlf, plr)
+					show_hudmessage(plr, "%s", arg)
+				}
+			}
+
+			if (flags & TD_USE_VOICE)
+			{
+				setTimeVoice(arg, charsmax(arg), flags, tmlf)
+				client_cmd(0, "%s", arg)
+			}
+		}
+	}
+}
diff --git a/amxmodx/scripting/uq_jumpstats.sma b/amxmodx/scripting/uq_jumpstats.sma
new file mode 100644
index 0000000..3cae430
--- /dev/null
+++ b/amxmodx/scripting/uq_jumpstats.sma
@@ -0,0 +1,6034 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+//line 3247
+#define PLUGIN "UQJS"
+#define VERSION "1.10"
+#define AUTHOR "MichaelKheel"
+
+new g_ClFilterStuffCmd[33];
+#define prefix "^1[^4f0.gg^1]"
+#define min_pre "60"
+#define FPS_TASK_ID 927560
+#define GRAVITY  800.0
+#define NSTRAFES 14
+#define SQLCVARSNUM 4
+#define NTECHNUM 26
+
+new angles_arry[33],Float:old_angles[33][3],lost_frame_count[33][NSTRAFES],line_lost[33][NSTRAFES][160],FullJumpFrames[33],heystats,max_players,bool:duckbhop_bug_pre[33],bool:dropupcj[33],Float:first_duck_z[33],Float:checkladdertime[33],bool:ladderbug[33],bool:login[33];
+new uq_istrafe,kz_uq_istrafe,bug_check[33],bool:bug_true[33],bool:find_ladder[33],bool:Checkframes[33],type_button_what[33][100];
+new beam_type[33],min_prestrafe[33],dropbhop[33],ddnum[33],bool:dropaem[33],bool:ddforcj[33];
+new kz_uq_min_other,bool:slide_protec[33],bool:UpcjFail[33],bool:upBhop[33],Float:upheight[33];
+new beam_entity[33][160],ent_count[33],g_sql_pid[33];
+
+new bool:height_show[33],bool:firstfall_ground[33],framecount[33],bool:firstladder[33];
+new Float:FallTime[33],Float:FallTime1[33],multiscj[33],multidropcj[33],bool:enable_sound[33];
+new jumpblock[33],Float:edgedist[33];
+new bool:failed_jump[33],bhop_num[33],bool:Show_edge_Fail[33],bool:Show_edge[33],bool:fps_hight[33],bool:first_ground_bhopaem[33];
+
+new line_erase[33][NSTRAFES],line_erase_strnum[33];
+
+new max_edge,min_edge,NSTRAFES1,max_strafes,Float:nextbhoptime[33],Float:bhopaemtime[33],Float:ground_bhopaem_time[33],Float:SurfFrames[33],Float:oldSurfFrames[33],bool:first_air[33];
+new bool:preessbutton[33],button_what[33],bool:gBeam_button[33][100],gBeam_button_what[33][100];
+new bool:h_jumped[33],Float:heightoff_origin[33],Float:x_heightland_origin[33],bool:x_jump[33],Float:laddertime[33],bool:edgedone[33];
+new schetchik[33],Float:changetime[33],bool:edgeshow[33],bool:slide[33],pre_type[33][33];
+
+new bool:ingame_strafe[33],bool:ljpre[33],Float:distance[33],detecthj[33],bool:doubleduck[33];
+new Float:doubletime[33],bool:multibhoppre[33],kz_uq_fps,bool:duckbhop[33],MAX_DISTANCE,Float:upbhop_koeff[33];
+new Float:rDistance[3],Float:frame2time,bool:touch_ent[33],bool:ddbeforwj[33],bool:gHasColorChat[33],Float:old_angle1[33];
+new bool:g_lj_stats[33],strafe_num[33],bool:g_Jumped[33],bool:g_reset[33],Float:gBeam_points[33][100][3],gBeam_duck[33][100],gBeam_count[33];
+
+new gBeam,waits[33],waits1[33],Float:slideland[33],bool:backwards[33],bool:hookcheck[33],Float:timeonground[33];
+new kz_uq_lj,kz_uq_cj,kz_uq_dcj,kz_uq_mcj ,kz_uq_ladder,kz_uq_ldbj,kz_uq_bj,kz_uq_sbj,kz_uq_drbj,kz_uq_drsbj,kz_uq_drcj,kz_uq_wj;  
+
+new oldpre[33],oldljpre[33],oldfail[33],Float:starthj[33][3],Float:stophj[33][3], Float:endhj[33][3];
+new bool:landslide[33],strafecounter_oldbuttons[33],Float:Fulltime,Float:needslide[33],Float:groundslide[33];
+new jj,sync_[33],goodSyncTemp,badSyncTemp,strafe_lost_frame[33][NSTRAFES],Float:time_,Float:strafe_stat_time[33][NSTRAFES],Float:strafe_stat_speed[33][NSTRAFES][2];
+new strafe_stat_sync[33][NSTRAFES][2],strLen,strMess[40*NSTRAFES],strMessBuf[40*NSTRAFES];
+
+new strL,strM[40*NSTRAFES],strMBuf[40*NSTRAFES],Float:firstvel[33],Float:secvel[33],Float:firstorig[33][3],Float:secorig[33][3];
+new Float:fSpeed, Float:speed, Float:TempSpeed[33],Float:velocity[3],Float:statsduckspeed[33][100]; 
+new bool:slidim[33],Float:slidedist[33],edgefriction,mp_footsteps,sv_cheats,sv_maxspeed,sv_stepsize,sv_maxvelocity;
+
+new kz_min_dcj,kz_stats_x,kz_stats_y,Float:stats_x,Float:stats_y,taskslide[33],taskslide1[33],bool:failslide[33];
+new Float:failslidez[33],kz_strafe_x,kz_strafe_y,Float:strafe_x,Float:strafe_y,Float:laddist[33],kz_duck_x;
+new kz_duck_y,Float:duck_x,Float:duck_y,bool:bhopaem[33],bool:nextbhop[33],kz_stats_red,kz_stats_green, kz_stats_blue, kz_failstats_red,kz_failstats_green;
+new kz_failstats_blue, kz_sounds, kz_airaccelerate,kz_legal_settings;
+
+new kz_uq_dscj,kz_uq_mscj,kz_uq_dropscj,kz_uq_dropdscj,kz_uq_dropmscj,kz_uq_duckbhop,kz_uq_bhopinduck,kz_uq_realldbhop,kz_uq_multibhop,kz_uq_upbj,kz_uq_upbhopinduck,kz_uq_upsbj,kz_uq_dropdcj,kz_uq_dropmcj;
+
+new user_block[33][2],Float:slidez[33][4][3];
+
+new CjafterJump[33],bool:ddafterJump[33],bool:cjjump[33],bool:serf_reset[33],entlist[256],ent,nLadder,Float:ladderxyz[256][3],Float:ladderminxyz[256][3], Float:laddersize[256][3], nashladder,bool:ladderjump[33];
+new bool:kz_stats_pre[33], bool:kz_beam[33],bool:showpre[33],bool:showjofon[33],bool:speedon[33],bool:jofon[33];
+
+new Float:dropbjorigin[33][3], Float:falloriginz[33],Float:origin[3],ducks[33], movetype[33];
+static Float:maxspeed[33], Float:prestrafe[33],JumpType:jump_type[33],JumpType:old_type_dropbj[33], frames[33], frames_gained_speed[33], bool:turning_left[33];
+static bool:turning_right[33],bool:started_cj_pre[33],bool:in_duck[33], bool:in_bhop[33],bool:in_air[33],bool:in_ladder[33];
+new bool:failearly[33],bool:firstshow[33],bool:first_onground[33],bool:notjump[33],bool:OnGround[33],bool:donehook[33];
+
+new bool:streifstat[33],Jtype[33][33],Jtype1[33][33],Jtype_old_dropbj[33][33],Jtype_old_dropbj1[33][33],Float:weapSpeed[33],Float:weapSpeedOld[33];
+new airacel[33][33],bool:firstfr[33],kz_speed_x,kz_speed_y,hud_stats,hud_streif,hud_pre,hud_duck,hud_speed; 
+new kz_uq_connect,bool:duckstring[33],bool:showduck[33],Float:surf[33];
+new bool:first_surf[33],oldjump_type[33],oldjump_typ1[33],jump_typeOld[33],mapname[33],Float:duckstartz[33],direct_for_strafe[33];
+new Float:height_difference[33],bool:jumpoffirst[33],bool:posibleScj[33];
+new kz_uq_noslow,kz_prest_x,kz_prest_y,kz_speed_r,kz_speed_g,kz_speed_b,kz_prest_r,kz_prest_g,kz_prest_b;
+
+new bool:touch_somthing[33],record_start[33];
+new showtime_st_stats[33];
+
+new Float:jof[33],Float:speedshowing[33];
+
+new g_playername[33][64], g_playersteam[33][35], g_playerip[33][16];
+new sql_JumpType[33];
+new Float:oldjump_height[33],Float:jheight[33],bool:jheight_show[33];
+
+new uq_lj,uq_cj,uq_dcj,uq_mcj,uq_ladder,uq_ldbj,uq_bj,uq_sbj,uq_drbj,uq_drsbj,uq_drcj;  
+new uq_wj,uq_dscj,uq_mscj,uq_dropscj,uq_dropdscj,uq_dropmscj,uq_duckbhop,uq_bhopinduck;
+new uq_realldbhop,uq_upbj,uq_upbhopinduck,uq_upsbj,uq_multibhop,uq_dropdcj,uq_dropmcj;
+new max_distance,min_distance_other,min_distance,uq_airaccel,leg_settings,uq_sounds;
+new uq_maxedge,uq_minedge,uq_min_pre,speed_r,speed_g,speed_b,Float:speed_x,Float:speed_y,h_speed;
+new prest_r,prest_g,prest_b,Float:prest_x,Float:prest_y,h_prest,h_stats,h_duck,h_streif;
+new uq_noslow,uq_fps,stats_r,stats_b,stats_g,f_stats_r,f_stats_b,f_stats_g;
+new uq_bug,kz_uq_bug,kz_uq_script_detection,uq_script_detection;
+new logs_path[128];
+new sv_airaccelerate, sv_gravity;
+
+new Trie:JumpPlayers;
+
+enum JumpType {
+  Type_LongJump = 0,
+  Type_HighJump = 1,
+  Type_CountJump = 2,
+  Type_BhopLongJump = 3,
+  Type_Slide = 4,
+  Type_StandupBhopLongJump = 5,
+  Type_WeirdLongJump = 6,
+  Type_Drop_BhopLongJump = 7,
+  Type_Nothing = 8,
+  Type_Double_CountJump = 9,
+  Type_Multi_CountJump = 11,
+  Type_DuckBhop = 12,
+  Type_ladder = 13,
+  Type_None = 14,
+  Type_ladderBhop = 15,
+  Type_Nothing2 = 16,
+  Type_Real_ladder_Bhop = 17,
+  Type_Drop_CountJump = 18, 
+  Type_StandUp_CountJump = 19,
+  Type_Multi_Bhop = 20,
+  Type_Up_Bhop = 21,
+  Type_Up_Stand_Bhop = 22,
+  Type_Up_Bhop_In_Duck = 23,
+  Type_Bhop_In_Duck = 24,
+  Type_Null = 25
+};
+
+new Type_List[NTECHNUM][] = {
+  "lj", "scj", "cj", "wj", "bj", "sbj", "ladder",
+  "ldbhop", "dropcj", "dropbj", "dcj", "dscj",
+  "dropscj", "dropdscj", "duckbhop", "bhopinduck",
+  "realldbhop", "upbj", "upsbj", "upbhopinduck",
+  "dropdcj", "mcj", "mscj", "dropmscj", "multibhop", "dropmcj"
+};
+
+public plugin_init() {
+  register_plugin(PLUGIN, VERSION, AUTHOR);
+
+  kz_min_dcj = register_cvar("kz_uq_min_dist", "215");
+  MAX_DISTANCE = register_cvar("kz_uq_max_dist", "290");
+  
+  kz_stats_red = register_cvar("kz_uq_stats_red", "0");    
+  kz_stats_green = register_cvar("kz_uq_stats_green", "255");
+  kz_stats_blue = register_cvar("kz_uq_stats_blue", "159");
+  kz_failstats_red = register_cvar("kz_uq_failstats_red", "255");    
+  kz_failstats_green = register_cvar("kz_uq_failstats_green", "0");
+  kz_failstats_blue = register_cvar("kz_uq_failstats_blue", "109");
+  
+  kz_sounds = register_cvar("kz_uq_sounds", "1");
+  kz_legal_settings = register_cvar("kz_uq_legal_settings", "1");
+  kz_airaccelerate = register_cvar("kz_uq_airaccelerate", "0");
+  
+  kz_stats_x = register_cvar("kz_uq_stats_x", "-1.0");    
+  kz_stats_y = register_cvar("kz_uq_stats_y", "0.70");
+  kz_strafe_x = register_cvar("kz_uq_strafe_x", "0.70");    
+  kz_strafe_y = register_cvar("kz_uq_strafe_y", "0.35");
+  kz_duck_x = register_cvar("kz_uq_duck_x", "0.6");    
+  kz_duck_y = register_cvar("kz_uq_duck_y", "0.78");
+  kz_speed_x = register_cvar("kz_uq_speed_x", "-1.0");    
+  kz_speed_y = register_cvar("kz_uq_speed_y", "0.83");
+  kz_prest_x = register_cvar("kz_uq_prestrafe_x", "-1.0");    
+  kz_prest_y = register_cvar("kz_uq_prestrafe_y", "0.65");
+  
+  kz_speed_r = register_cvar("kz_uq_speed_red", "255");    
+  kz_speed_g = register_cvar("kz_uq_speed_green", "255");
+  kz_speed_b = register_cvar("kz_uq_speed_blue", "255");    
+  kz_prest_r = register_cvar("kz_uq_prestrafe_red", "255");    
+  kz_prest_g = register_cvar("kz_uq_prestrafe_green", "255");
+  kz_prest_b = register_cvar("kz_uq_prestrafe_blue", "255");
+  
+  hud_stats = register_cvar("kz_uq_hud_stats", "3");    
+  hud_streif = register_cvar("kz_uq_hud_strafe", "4");
+  hud_pre = register_cvar("kz_uq_hud_pre", "1");    
+  hud_duck = register_cvar("kz_uq_hud_duck", "1");
+  hud_speed = register_cvar("kz_uq_hud_speed", "2");
+  
+  kz_uq_lj = register_cvar("kz_uq_lj", "1");  
+  kz_uq_cj = register_cvar("kz_uq_cj", "1");  
+  kz_uq_dcj = register_cvar("kz_uq_dcj", "1");  
+  kz_uq_mcj = register_cvar("kz_uq_mcj", "1");  
+  kz_uq_ladder = register_cvar("kz_uq_ladder", "1");  
+  kz_uq_ldbj = register_cvar("kz_uq_ldbj", "1");  
+  kz_uq_bj = register_cvar("kz_uq_bj", "1");  
+  kz_uq_sbj = register_cvar("kz_uq_sbj", "1");  
+  kz_uq_drbj = register_cvar("kz_uq_drbj", "1");  
+  kz_uq_drsbj = register_cvar("kz_uq_scj", "1");  
+  kz_uq_drcj = register_cvar("kz_uq_drcj", "1");  
+  kz_uq_wj = register_cvar("kz_uq_wj", "1");  
+  
+  kz_uq_dscj = register_cvar("kz_uq_dscj", "1");  
+  kz_uq_mscj = register_cvar("kz_uq_mscj", "1");
+  kz_uq_dropscj = register_cvar("kz_uq_dropscj", "1");
+  kz_uq_dropdscj = register_cvar("kz_uq_dropdscj", "1");
+  kz_uq_dropmscj = register_cvar("kz_uq_dropmscj", "1");
+  kz_uq_duckbhop = register_cvar("kz_uq_duckbhop", "1");
+  kz_uq_bhopinduck = register_cvar("kz_uq_bhopinduck", "1");
+  kz_uq_realldbhop = register_cvar("kz_uq_realldbhop", "1");
+  kz_uq_upbj = register_cvar("kz_uq_upbj", "1");
+  kz_uq_upbhopinduck = register_cvar("kz_uq_upbhopinduck", "1");
+  kz_uq_upsbj = register_cvar("kz_uq_upsbj", "1");
+  kz_uq_multibhop = register_cvar("kz_uq_multibhop", "1");
+  kz_uq_dropdcj = register_cvar("kz_uq_dropdcj", "1");
+  kz_uq_dropmcj = register_cvar("kz_uq_dropmcj", "1");
+  
+  kz_uq_connect = register_cvar("kz_uq_connect", "abdehklmn");
+  kz_uq_fps = register_cvar("kz_uq_fps", "1");  
+  kz_uq_istrafe = register_cvar("kz_uq_istrafes", "0");
+  
+  max_edge = register_cvar("kz_uq_max_block", "290");
+  min_edge = register_cvar("kz_uq_min_block", "100");
+  kz_uq_min_other = register_cvar("kz_uq_min_dist_other", "120");
+  max_strafes = register_cvar("kz_uq_max_strafes", "14");
+  
+  kz_uq_bug = register_cvar("kz_uq_bug_check", "1");
+  kz_uq_noslow = register_cvar("kz_uq_noslowdown", "0");
+  
+  kz_uq_script_detection = register_cvar("kz_uq_script_detection", "1");
+  
+  register_cvar("uq_jumpstats", VERSION, FCVAR_SERVER|FCVAR_SPONLY);
+    
+  register_clcmd( "say /strafe", "streif_stats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /strafes", "streif_stats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /strafestat", "streif_stats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /strafestats", "streif_stats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /showpre", "show_pre", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /duck", "pre_stats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /ducks", "pre_stats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /uqstats", "cmdljStats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /ljstats", "cmdljStats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /stats", "cmdljStats", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /height", "heightshow", ADMIN_ALL, "- enabled/disables");
+  register_clcmd( "say /fall", "heightshow", ADMIN_ALL, "- enabled/disables");
+  
+  register_clcmd("say /uqbeam", "cmdljbeam", ADMIN_ALL);
+  register_clcmd("say /beam", "cmdljbeam", ADMIN_ALL);
+  register_clcmd("say /ljbeam", "cmdljbeam", ADMIN_ALL);
+  //register_clcmd("say /speed", "show_speed", ADMIN_ALL);
+  //register_clcmd("say speed", "show_speed", ADMIN_ALL);
+  register_clcmd("say /colorchat", "cmdColorChat", ADMIN_ALL);
+  register_clcmd("say colorchat", "cmdColorChat", ADMIN_ALL);
+  register_clcmd("say /bhopwarn", "show_early", ADMIN_ALL);
+  register_clcmd("say /multibhop", "multi_bhop", ADMIN_ALL);
+  register_clcmd("say /duckspre", "duck_show", ADMIN_ALL);
+  register_clcmd("say /duckpre", "duck_show", ADMIN_ALL);
+  register_clcmd("say /ljpre", "lj_show", ADMIN_ALL);
+  register_clcmd("say /prelj", "lj_show", ADMIN_ALL);
+  register_clcmd("say /uqsound", "enable_sounds", ADMIN_ALL);
+  register_clcmd("say /uqsounds", "enable_sounds", ADMIN_ALL);
+  
+  register_clcmd("say /failedge", "ShowedgeFail", ADMIN_ALL);
+  register_clcmd("say /failedg", "ShowedgeFail", ADMIN_ALL);
+  register_clcmd("say /edgefail", "ShowedgeFail", ADMIN_ALL);
+  register_clcmd("say /edgfail", "ShowedgeFail", ADMIN_ALL);
+  register_clcmd("say /edge", "Showedge", ADMIN_ALL);
+  register_clcmd("say /edg", "Showedge", ADMIN_ALL);
+  
+  register_clcmd("say /joftrainer", "trainer_jof", ADMIN_ALL);
+  register_clcmd("say joftrainer", "trainer_jof", ADMIN_ALL);
+  register_clcmd("say /joftr", "trainer_jof", ADMIN_ALL);
+  register_clcmd("say joftr", "trainer_jof", ADMIN_ALL);
+  
+  register_clcmd("say /jof", "show_jof", ADMIN_ALL);
+  register_clcmd("say jof", "show_jof", ADMIN_ALL);
+  
+  register_clcmd("say /jheight", "show_jheight", ADMIN_ALL);
+  register_clcmd("say jheight", "show_jheight", ADMIN_ALL);
+  
+  register_clcmd("say /istrafe", "ingame_st_stats", ADMIN_ALL);
+  register_clcmd("say istrafe", "ingame_st_stats", ADMIN_ALL);
+  
+  register_clcmd("say /options", "Option", ADMIN_ALL);
+  register_clcmd("say /ljsmenu", "Option", ADMIN_ALL);
+  register_clcmd("say /ljsmenu2", "Option2", ADMIN_ALL);
+  register_clcmd("say /uqmenu", "Option", ADMIN_ALL);
+  register_clcmd("say /option", "Option", ADMIN_ALL);
+
+  register_menucmd(register_menuid("StatsOptionMenu1"), 1023, "OptionMenu1");
+  register_menucmd(register_menuid("StatsOptionMenu2"), 1023, "OptionMenu2");
+  register_menucmd(register_menuid("StatsOptionMenu3"), 1023, "OptionMenu3");
+  
+  edgefriction = get_cvar_pointer("edgefriction");
+  mp_footsteps = get_cvar_pointer("mp_footsteps");
+  sv_cheats = get_cvar_pointer("sv_cheats");
+  sv_maxspeed = get_cvar_pointer("sv_maxspeed");
+  sv_stepsize = get_cvar_pointer("sv_stepsize");
+  sv_maxvelocity = get_cvar_pointer("sv_maxvelocity");
+  sv_airaccelerate = get_cvar_pointer("sv_airaccelerate");
+  sv_gravity = get_cvar_pointer("sv_gravity");
+
+  register_forward(FM_Touch, "fwdTouch", 1);
+  register_forward(FM_PlayerPreThink, "fwdPreThink", 0 );
+  register_forward(FM_PlayerPostThink, "fwdPostThink", 0 );
+  
+  RegisterHam(Ham_Spawn, "player", "FwdPlayerSpawn", 1);
+  RegisterHam(Ham_Killed, "player", "FwdPlayerDeath", 1);
+  RegisterHam(Ham_Touch, "player", "HamTouch");
+  
+  register_event("ResetHUD", "ResetHUD", "b");
+  
+  max_players = get_maxplayers() + 1;
+  
+  ent = find_ent_by_class(-1, "func_ladder");
+  while(ent > 0) {
+    entity_get_vector(ent, EV_VEC_maxs, ladderxyz[nLadder]);
+    entity_get_vector(ent, EV_VEC_mins, ladderminxyz[nLadder]);
+    entity_get_vector(ent, EV_VEC_size, laddersize[nLadder]);
+    entlist[nLadder] = ent;
+    
+    ent = find_ent_by_class(ent, "func_ladder");
+    nLadder++;
+  }
+  
+  get_mapname(mapname, 32);
+  
+  // Logs
+  new logs[64];
+  get_localinfo("amxx_logs", logs, 63);
+  formatex(logs_path, 127, "%s\uq_jumpstats.txt", logs);
+}
+
+public plugin_cfg() {
+  new cvarfiles[256];
+  kz_get_configsfile(cvarfiles, charsmax(cvarfiles));
+  
+  if(file_exists(cvarfiles)) {
+    server_cmd("exec %s", cvarfiles);
+    server_exec();
+  }
+
+  uq_min_pre = str_to_num(min_pre);
+  uq_maxedge = get_pcvar_num(max_edge);
+  uq_minedge = get_pcvar_num(min_edge);
+  uq_istrafe = get_pcvar_num(kz_uq_istrafe);
+  NSTRAFES1 = get_pcvar_num(max_strafes);
+  stats_x = get_pcvar_float(kz_stats_x);
+  stats_y = get_pcvar_float(kz_stats_y);
+  strafe_x = get_pcvar_float(kz_strafe_x);
+  strafe_y = get_pcvar_float(kz_strafe_y);
+  duck_x = get_pcvar_float(kz_duck_x);
+  duck_y = get_pcvar_float(kz_duck_y);
+  prest_r = get_pcvar_num(kz_prest_r);
+  prest_g = get_pcvar_num(kz_prest_g);
+  prest_b = get_pcvar_num(kz_prest_b);
+  prest_x = get_pcvar_float(kz_prest_x);
+  prest_y = get_pcvar_float(kz_prest_y);
+  h_prest = get_pcvar_num(hud_pre);
+  h_stats = get_pcvar_num(hud_stats);
+  h_duck = get_pcvar_num(hud_duck);
+  h_streif = get_pcvar_num(hud_streif);
+  stats_r = get_pcvar_num(kz_stats_red);
+  stats_b = get_pcvar_num(kz_stats_blue);
+  stats_g = get_pcvar_num(kz_stats_green);
+  f_stats_r = get_pcvar_num(kz_failstats_red);
+  f_stats_b = get_pcvar_num(kz_failstats_blue);
+  f_stats_g = get_pcvar_num(kz_failstats_green);
+  uq_lj = get_pcvar_num(kz_uq_lj);  
+  uq_cj = get_pcvar_num(kz_uq_cj);  
+  uq_dcj = get_pcvar_num(kz_uq_dcj);  
+  uq_mcj = get_pcvar_num(kz_uq_mcj);  
+  uq_ladder = get_pcvar_num(kz_uq_ladder);  
+  uq_ldbj = get_pcvar_num(kz_uq_ldbj);  
+  uq_bj = get_pcvar_num(kz_uq_bj);  
+  uq_sbj = get_pcvar_num(kz_uq_sbj);  
+  uq_drbj = get_pcvar_num(kz_uq_drbj);  
+  uq_drsbj = get_pcvar_num(kz_uq_drsbj);  
+  uq_drcj = get_pcvar_num(kz_uq_drcj);  
+  uq_wj = get_pcvar_num(kz_uq_wj);
+  uq_dscj = get_pcvar_num(kz_uq_dscj);  
+  uq_mscj = get_pcvar_num(kz_uq_mscj);
+  uq_dropscj = get_pcvar_num(kz_uq_dropscj);
+  uq_dropdscj = get_pcvar_num(kz_uq_dropdscj);
+  uq_dropmscj = get_pcvar_num(kz_uq_dropmscj);
+  uq_duckbhop = get_pcvar_num(kz_uq_duckbhop);
+  uq_bhopinduck = get_pcvar_num(kz_uq_bhopinduck);
+  uq_realldbhop = get_pcvar_num(kz_uq_realldbhop);
+  uq_upbj = get_pcvar_num(kz_uq_upbj);
+  uq_upbhopinduck = get_pcvar_num(kz_uq_upbhopinduck);
+  uq_upsbj =  get_pcvar_num(kz_uq_upsbj);
+  uq_multibhop = get_pcvar_num(kz_uq_multibhop);
+  uq_dropdcj = get_pcvar_num(kz_uq_dropdcj);
+  uq_dropmcj = get_pcvar_num(kz_uq_dropmcj);
+  leg_settings = get_pcvar_num(kz_legal_settings);  
+  uq_airaccel = get_pcvar_num( kz_airaccelerate );
+  min_distance = get_pcvar_num(kz_min_dcj);
+  min_distance_other = get_pcvar_num(kz_uq_min_other);
+  max_distance = get_pcvar_num(MAX_DISTANCE);
+  uq_sounds = get_pcvar_num(kz_sounds);
+  uq_fps = get_pcvar_num(kz_uq_fps);
+  speed_r = get_pcvar_num(kz_speed_r);
+  speed_g = get_pcvar_num(kz_speed_g);
+  speed_b = get_pcvar_num(kz_speed_b);
+  speed_x = get_pcvar_float(kz_speed_x);
+  speed_y = get_pcvar_float(kz_speed_y);
+  h_speed = get_pcvar_num(hud_speed);
+  uq_bug = get_pcvar_num(kz_uq_bug);
+  uq_noslow = get_pcvar_num(kz_uq_noslow);
+  uq_script_detection = get_pcvar_num(kz_uq_script_detection);
+    
+  new plugin_id = find_plugin_byfile("uq_jumpstats_tops.amxx");
+  
+  if(plugin_id==-1) {
+    log_amx("Can't find uq_jumpstats_tops.amxx");
+    server_print("[uq_jumpstats] Can't find uq_jumpstats_tops.amxx");
+  }
+
+  if(leg_settings) {
+    set_cvar_string("edgefriction", "2");
+    set_cvar_string("mp_footsteps", "1");
+    set_cvar_string("sv_cheats", "0");
+    set_cvar_string("sv_gravity", "800");
+    set_cvar_string("sv_airaccelerate", "100");
+    set_cvar_string("sv_maxspeed", "320");
+    set_cvar_string("sv_stepsize", "18");
+    set_cvar_string("sv_maxvelocity", "2000");
+  }
+        
+  set_task(0.2, "stats_sql");
+  JumpPlayers = TrieCreate();
+}
+
+#include 
+
+public plugin_precache() {
+  gBeam = precache_model("sprites/zbeam6.spr");
+  precache_sound("misc/impressive.wav");
+  precache_sound("misc/perfect.wav");
+  precache_sound("misc/mod_godlike.wav");
+  precache_sound("misc/holyshit.wav");
+  precache_sound("misc/mod_wickedsick.wav");
+  precache_sound("misc/dominatingkz.wav");
+  
+  precache_model("models/hairt.mdl");
+  heystats = precache_model("sprites/zbeam6.spr");
+}
+
+bool:valid_id(id) {
+  if(id>0 && id<33)
+    return true;
+  return false;
+}
+
+bool:check_for_bug_distance(Float:check_distance,type,mSpeed) {
+  new minys = floatround((250.0-mSpeed)*0.73,floatround_floor);
+  if(type == 1 && check_distance > (260 - minys))
+    return true;
+  else if(type == 2 && check_distance > (277 - minys))
+    return true;
+  else if(type == 3 && check_distance > (253 - minys))
+    return true;
+  else if(type == 4 && check_distance > 200)
+    return true;
+  else if(type == 5 && check_distance > 225 - minys)
+    return true;
+  else if(type == 6 && check_distance > 180 - minys)
+    return true;
+  return false;
+}
+
+bool:is_user_ducking(id) {
+  if(!valid_id(id))
+    return false;
+  
+  new Float:abs_min[3], Float:abs_max[3];
+  
+  pev(id, pev_absmin, abs_min);
+  pev(id, pev_absmax, abs_max);
+  
+  abs_min[2] += 64.0;
+  
+  if(abs_min[2] < abs_max[2])
+    return false;
+  
+  return true;
+}
+
+stock IsOnGround(id) {    
+  new flags = pev(id, pev_flags);
+  if((flags & FL_ONGROUND) || (flags & FL_PARTIALGROUND) ||( flags & FL_INWATER ) ||( flags & FL_CONVEYOR ) ||( flags & FL_FLOAT))
+    return true;
+  return false;
+}
+
+public Log_script(f_frames,cheated_frames,id,Float:log_dist,Float:log_max,Float:log_pre,log_str,log_sync,jump_type_str[],wpn_str[],punishments[],t_str[40*NSTRAFES]) {
+  new Date[20];
+  get_time("%m/%d/%y %H:%M:%S", Date, 19)  ;
+  new username[33];
+  get_user_name(id, username, 32);
+  new userip[16];
+  get_user_ip(id, userip, 15, 1);
+  new authid[35];
+  get_user_authid(id, authid, 34);
+  new main_text[512];
+  
+  write_file(logs_path, "---------------------------------------------------", -1);
+  formatex(main_text, 511, "%s |%s |%s |%s |%s |%s ^n", Date,username, authid, userip, "Script",punishments);
+  write_file(logs_path, main_text, -1);
+  formatex(main_text, 511, "Type: %s ::: Weapon: %s^nDistance: %.03f Maxspeed: %.03f Prestrafe: %.03f Strafes: %d Sync: %d^n",jump_type_str,wpn_str,log_dist,log_max,log_pre,log_str,log_sync);
+  write_file(logs_path, main_text, -1);
+  formatex(main_text, 511, "Total Frames: %d^nCheated Frames: %d^n",f_frames,cheated_frames);
+  write_file(logs_path, main_text, -1);
+  
+  new strf[40];
+  for(new ll=1; (ll <= log_str) && (ll < NSTRAFES);ll++) {
+    strtok(t_str,strf,40,t_str,40*NSTRAFES,'^n');
+    replace(strf,40,"^n","");
+    write_file(logs_path, strf, -1);
+  }
+  write_file(logs_path, "---------------------------------------------------", -1);
+}
+
+public fnClientCvarResult(id, const szCvar[], const szValue[]) {
+  if(equali(szCvar, "cl_filterstuffcmd") && szValue[0] != 'B')
+    g_ClFilterStuffCmd[id] = str_to_num(szValue);
+}
+
+public tskFps(id) {
+  if(leg_settings) {
+    id -= 434490;
+    new authid[32];
+    get_user_authid(id, authid, 31);
+    client_cmd(id, ";^"gl_vsync^" 0;^"fps_override^" 0;^"cl_forwardspeed^" 400;^"cl_backspeed^" 400;^"cl_sidespeed^" 400");
+    query_client_cvar(id, "cl_filterstuffcmd", "fnClientCvarResult");
+    if(!g_ClFilterStuffCmd[id])
+      client_cmd(id, ";^"developer^" 0;^"fps_max^" 99.5");
+    if(equal(authid, "VALVE_ID_LAN") || equal(authid, "STEAM_ID_LAN") || strlen(authid) > 18)
+      client_cmd(id, ";^"developer^" 0;^"fps_max^" 101");
+    else
+      client_cmd(id, ";^"fps_max^" 99.5");
+  }
+}
+public server_frame() {
+  if(leg_settings) {
+    if(get_pcvar_num(edgefriction) != 2) set_pcvar_num(edgefriction, 2);
+    if(get_pcvar_num(mp_footsteps) != 1) set_pcvar_num(mp_footsteps, 1);
+    if(get_pcvar_num(sv_cheats) != 0)  set_pcvar_num(sv_cheats, 0);
+    if(get_pcvar_num(sv_gravity)!= 800) set_pcvar_num(sv_gravity, 800);
+    if(get_pcvar_num(sv_maxspeed) != 320)  set_pcvar_num(sv_maxspeed, 320);
+    if(get_pcvar_num(sv_stepsize) != 18) set_pcvar_num(sv_stepsize, 18);
+    if(get_pcvar_num(sv_maxvelocity) != 2000) set_pcvar_num(sv_maxvelocity, 2000);
+  }
+}
+public client_putinserver(id) {
+  if(speedon[id] && !is_user_hltv(id))
+    set_task(0.1, "DoSpeed", id+212299, "", 0, "b", 0);
+  
+  get_user_name(id, g_playername[id], 63);
+  get_user_ip(id, g_playerip[id], 15, 1);
+  get_user_authid(id, g_playersteam[id], 35);
+
+  player_load_info(id);
+}
+public Dojof(taskid) {
+  taskid -= 212398;
+  
+  static alive, spectatedplayer;
+  alive = g_alive[taskid];
+  spectatedplayer = get_spectated_player(taskid);
+  
+  if((alive || spectatedplayer > 0)) {
+    new show_id;
+    if(alive)
+      show_id = taskid;
+    else
+      show_id = spectatedplayer;
+    
+    if(jof[show_id] != 0.0) {  
+      if(jof[show_id] > 5.0)
+        set_hudmessage(255, 255, 255, -1.0, 0.6, 0, 0.0, 0.7, 0.0, 0.0, h_speed);
+      else
+        set_hudmessage(255, 0, 0, -1.0, 0.6, 0, 0.0, 0.7, 0.0, 0.0, h_speed);
+      show_hudmessage(taskid, "JumpOff: %f", jof[show_id]);
+    }
+  }
+}
+
+public DoSpeed(taskid) {
+  taskid -= 212299;
+  
+  static alive, spectatedplayer;
+  alive = g_alive[taskid];
+  spectatedplayer = get_spectated_player(taskid);
+  
+  if((alive || spectatedplayer > 0)) {
+    new show_id;
+    if(alive)
+      show_id = taskid;
+    else
+      show_id = spectatedplayer;
+    set_hudmessage(speed_r, speed_g, speed_b, speed_x, speed_y, 0, 0.0, 0.2, 0.0, 0.0, h_speed);
+    show_hudmessage(taskid, "%d units/sec", floatround(speedshowing[show_id], floatround_floor));    
+  }
+}
+public wait(id) {
+  id -= 3313;
+  waits[id] = 1;
+}
+
+public wait1(id) {
+  id -= 3214;
+  waits1[id] = 1;
+}
+
+public client_command(id) {
+  static command[32];
+  read_argv(0, command, 31);
+
+  static const forbidden[][] = {
+    "tele", "tp", "gocheck", "gc", "stuck", "unstuck", "start", "reset", "restart",
+    "spawn", "respawn"
+  };
+
+  if(record_start[id] == 0 && equali(command, "fullupdate"))
+    record_start[id] = 1;
+  else if(record_start[id]==1 && equali(command, "specmode")) {
+    set_hudmessage(255, 255, 255, 0.72, 0.0, 0, 6.0, 1.0);
+    show_hudmessage(id, "%L",LANG_SERVER,"UQSTATS_INFOSTS",VERSION);
+    record_start[id]=0;
+  }
+  if(is_user_alive(id)) {
+    if(equali(command, "say")) {
+      read_args(command, 31);
+      remove_quotes(command);
+    }
+    if(equali(command, "+hook")) {
+      JumpReset(id);
+      donehook[id] = true;
+      hookcheck[id] = false;
+    }
+    else if(command[0] == '/' || command[0] == '.') {
+      copy(command, 31, command[1]);
+      for(new i ; i < sizeof(forbidden) ; i++) {
+        if(equali(command, forbidden[i])) {
+          JumpReset(id);
+          break;
+        }
+      }
+    }
+  }
+}
+
+public freeze(id) {
+  if(IsOnGround(id))
+  return PLUGIN_HANDLED;
+
+  set_pev(id, pev_velocity, { 0.0 , 0.0 , 0.0 });
+  set_pev(id, pev_flags, pev(id, pev_flags) | FL_FROZEN);
+
+  new flags = pev(id, pev_flags);
+  if(flags & FL_FROZEN)
+    set_pev(id, pev_flags, flags & ~FL_FROZEN);
+  return PLUGIN_HANDLED;
+}
+
+public remove_beam_ent(id) {
+  for(new i=0;ist_finish;j=j-1.0) {
+        beam_entity[id][ent_count[id]] = create_entity("info_target");
+    
+        entity_set_model(beam_entity[id][ent_count[id]], "models/hairt.mdl");
+        
+        new Float:ent_org[3];
+        if(direct[0]) {
+          ent_org[0] = temp_or[1];
+          ent_org[1] = j;
+        }
+        else {
+          ent_org[0] = j;
+          ent_org[1] = temp_or[1];
+        }
+        if(i % 2 != 0)
+          ent_org[2] = temp_or[2];
+        else 
+          ent_org[2] = temp_or[2] - 4.0;
+        
+        entity_set_origin(beam_entity[id][ent_count[id]], ent_org);
+        
+        message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0, 0, 0}, id);
+        
+        write_byte(TE_BEAMENTPOINT);
+        write_short(beam_entity[id][ent_count[id]]);
+        
+        if(direct[0]) {
+          write_coord(floatround(temp_or[1]));
+          write_coord(floatround(j));
+        }
+        else {
+          write_coord(floatround(j));
+          write_coord(floatround(temp_or[1]));
+        }
+        
+        if(i % 2 != 0)
+          write_coord(floatround(temp_or[2]+4.0));
+        else 
+          write_coord(floatround(temp_or[2]));
+
+        write_short(heystats);
+        write_byte(0);
+        write_byte(5);
+        write_byte(showtime_st_stats[id]);
+        write_byte(5);
+        write_byte(0);
+          
+        if(l_lost[i][count_l]) {
+          write_byte(255);
+          write_byte(0);
+          write_byte(0);
+          line_lost[id][i][count_l] = 0;
+        }
+        else {
+          write_byte(0);
+          write_byte(255);
+          write_byte(0);
+        }
+        
+        write_byte(200);
+        write_byte(1);
+        message_end();
+        count_l++;
+        ent_count[id]++;
+      }
+      temp_start = st_finish;
+    }
+  }
+  else {
+    new Float:temp_start=os_start;
+    beam_entity[id][ent_count[id]] = create_entity("info_target");
+    
+    entity_set_model(beam_entity[id][ent_count[id]], "models/hairt.mdl");
+    
+    new Float:ent_or[3];
+    if(direct[0]) {
+      ent_or[0] = temp_or[1];
+      ent_or[1] = temp_start;
+    }
+    else {
+      ent_or[0] = temp_start;
+      ent_or[1] = temp_or[1];
+    }
+    ent_or[2] = temp_or[2];
+    
+    entity_set_origin(beam_entity[id][ent_count[id]], ent_or);
+    
+    message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0, 0, 0}, id);
+    
+    write_byte(TE_BEAMENTPOINT);
+    write_short(beam_entity[id][ent_count[id]]);
+    
+    if(direct[0]) {
+      write_coord(floatround(temp_or[1]));
+      write_coord(floatround(temp_start + full));
+    }
+    else {
+      write_coord(floatround(temp_start + full));
+      write_coord(floatround(temp_or[1]));
+    }
+    write_coord(floatround(temp_or[2]));
+
+    write_short(heystats);
+    write_byte(0);
+    write_byte(5);
+    write_byte(showtime_st_stats[id]);
+    write_byte(1);
+    write_byte(0);
+    
+    write_byte(0);
+    write_byte(0);
+    write_byte(255);
+  
+    write_byte(150);
+    write_byte(1);
+    message_end();
+    
+    ent_count[id]++;
+    
+    for(new i=0;i<2;i++) {
+      beam_entity[id][ent_count[id]] = create_entity("info_target");
+    
+      entity_set_model(beam_entity[id][ent_count[id]], "models/hairt.mdl");
+      
+      new Float:ent_org[3];
+      if(direct[0]) {
+        ent_org[0] = temp_or[1];
+        
+        if(i == 1)
+          ent_org[1] = temp_start + full;
+        else
+          ent_org[1] = temp_start;
+      }
+      else {
+        if(i == 1)
+          ent_org[0] = temp_start + full;
+        else
+          ent_org[0] = temp_start;
+          
+        ent_org[1] = temp_or[1];
+      }
+      ent_org[2] = temp_or[2] - 10.0;
+      
+      entity_set_origin(beam_entity[id][ent_count[id]], ent_org);
+      
+      message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0, 0, 0}, id);
+      
+      write_byte(TE_BEAMENTPOINT);
+      write_short(beam_entity[id][ent_count[id]]);
+      if(direct[0]) {
+        write_coord(floatround(temp_or[1]));
+        if(i == 1)
+          write_coord(floatround(temp_start + full));
+        else
+          write_coord(floatround(temp_start));
+      }
+      else {
+        if(i == 1)
+          write_coord(floatround(temp_start + full));
+        else
+          write_coord(floatround(temp_start));
+        write_coord(floatround(temp_or[1]));
+      }
+      write_coord(floatround(temp_or[2]+10.0));
+
+      write_short(heystats);
+      write_byte(0);
+      write_byte(5);
+      write_byte(showtime_st_stats[id]);
+      write_byte(5);
+      write_byte(0);
+      
+      write_byte(0);
+      write_byte(0);
+      write_byte(255);
+    
+      write_byte(150);
+      write_byte(1);
+      message_end();
+      
+      ent_count[id]++;
+    }
+    
+    for(new i=1;i<=str_num;i++) {
+      new Float:st_start,Float:st_finish;
+      
+      st_finish = temp_start + strafe_lost[i] + strafe_frame1[i] + strafe_frame2[i];
+      st_start = temp_start + strafe_lost[i];
+      
+      for(new Float:j=st_start,count_l=0;j NSTRAFES1) {
+          g_reset[id] = true;
+          for(new i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i])) {
+              set_hudmessage(255, 255, 255, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats);
+              show_hudmessage(i,"You have exceeded the maximum number of strafes^n(Server max value ^"%d^", You Strafes is ^"%d^")",NSTRAFES1,strafe_num[id]);  
+            }
+          }
+          return FMRES_IGNORED;
+        }
+        
+        if((button&IN_RIGHT || button&IN_LEFT) && !(flags&FL_ONGROUND)) {
+          for(new i = 1; i < max_players; i++ ) {
+            if((i == id || is_spec_user[i])) {
+              client_print(i,print_center,"Script or you use left(right) key");
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+          }
+        }
+        new airace,aircj;
+        if(uq_airaccel) {
+          airace = 100;
+          formatex(airacel[id],32,"(100aa)");
+          aircj = 10;
+        }
+        else {
+          airace = 10;
+          aircj = 0;
+          formatex(airacel[id],32,"");
+        }
+        new spd;
+        if(equali(mapname,"slide_gs_longjumps") || equali(mapname,"b2j_slide_longjumps"))
+          spd = 1400;
+        else
+          spd = 385;
+        
+        if(speed> spd || weapSpeedOld[id] != weapSpeed[id]) {
+          if(weapSpeedOld[id] != weapSpeed[id])
+            changetime[id]=get_gametime();
+          JumpReset(id);
+          return FMRES_IGNORED;
+        }
+        
+        if(leg_settings==1 && (get_pcvar_num(edgefriction) != 2 || fGravity != 1.0 || get_pcvar_num(mp_footsteps) != 1
+            || get_pcvar_num(sv_cheats) != 0
+            || get_pcvar_num(sv_gravity) != 800
+            || get_pcvar_num(sv_airaccelerate) != airace
+            || get_pcvar_num(sv_maxspeed) != 320
+            || get_pcvar_num(sv_stepsize) != 18
+            || get_pcvar_num(sv_maxvelocity) != 2000
+            || pev(id, pev_waterlevel) >= 2 )) {
+          JumpReset(id);
+          return FMRES_IGNORED;
+        }
+      
+        if(!(button&IN_MOVELEFT) && oldbuttons&IN_MOVELEFT) {
+          preessbutton[id] = false;
+          button_what[id] = 0;
+        }
+        else if(oldbuttons&IN_MOVERIGHT && !(button&IN_MOVERIGHT)) {
+          button_what[id] = 0;
+          preessbutton[id] = false;
+        }
+        else if(oldbuttons&IN_BACK && !(button&IN_BACK)) {
+          preessbutton[id] = false;
+          button_what[id] = 0;
+        }
+        else if(oldbuttons&IN_FORWARD && !(button&IN_FORWARD)) {
+          preessbutton[id] = false;
+          button_what[id] = 0;
+        }
+        if(!(flags&FL_ONGROUND)) {
+          last_land_time[id] = get_gametime();
+          jof[id]=0.0;
+        }
+        
+        if(bhopaem[id] == true && !(flags&FL_ONGROUND) && movetype[id] != MOVETYPE_FLY)
+          bhopaemtime[id] = get_gametime();
+        else if(bhopaem[id] == true && flags&FL_ONGROUND && get_gametime() - bhopaemtime[id] > 0.1 && movetype[id] != MOVETYPE_FLY)
+          bhopaem[id] = false;
+        
+        if(nextbhop[id] == true && flags&FL_ONGROUND && first_ground_bhopaem[id] == false) {
+          first_ground_bhopaem[id] = true;
+          ground_bhopaem_time[id] = get_gametime();
+        }
+        else if(nextbhop[id] == true && !(flags&FL_ONGROUND) && first_ground_bhopaem[id] == true && movetype[id] != MOVETYPE_FLY)
+          first_ground_bhopaem[id] = false;
+        
+        if(nextbhop[id]==true && flags&FL_ONGROUND && first_ground_bhopaem[id]==true && (get_gametime()-ground_bhopaem_time[id]>0.1) && movetype[id] != MOVETYPE_FLY) {
+          first_ground_bhopaem[id] = false;
+          bhopaem[id] = false;
+          nextbhop[id] = false;
+        }
+        
+        if(nextbhop[id] == true && !(flags&FL_ONGROUND) && movetype[id] != MOVETYPE_FLY)
+          nextbhoptime[id] = get_gametime();
+        if(nextbhop[id] == true && flags&FL_ONGROUND && get_gametime()-nextbhoptime[id]>0.1 && movetype[id] != MOVETYPE_FLY)
+          nextbhop[id]=false;
+        if(flags & FL_ONGROUND && h_jumped[id] == false && movetype[id] != MOVETYPE_FLY)
+          heightoff_origin[id] = 0.0;
+        if(flags & FL_ONGROUND && button&IN_BACK && backwards[id] == false)
+          backwards[id] = true;
+        else if(flags & FL_ONGROUND && button&IN_FORWARD && backwards[id])
+          backwards[id] = false;
+        if(flags & FL_ONGROUND && button&IN_JUMP && !(oldbuttons&IN_JUMP) && movetype[id] != MOVETYPE_FLY) {
+          if(is_user_ducking(id))
+            heightoff_origin[id] = origin[2] + 18;
+          else
+            heightoff_origin[id] = origin[2];
+          
+          h_jumped[id] = true;
+        }
+        else if(flags & FL_ONGROUND && h_jumped[id] && movetype[id] != MOVETYPE_FLY) {
+          new Float:heightland_origin;
+          if(is_user_ducking(id))
+            heightland_origin = origin[2] + 18;
+          else
+            heightland_origin = origin[2];
+          
+          for(new i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i])) {  
+              if(height_show[i] == true) {
+                if(heightland_origin-heightoff_origin[id]==0.0) {
+                  set_hudmessage(prest_r,prest_g, prest_b, stats_x, stats_y, 0, 0.0, 0.7, 0.1, 0.1, h_stats);
+                  show_hudmessage(i, "Jump realise at the same height");
+                }
+                else if(heightland_origin-heightoff_origin[id]>0.0) {
+                  set_hudmessage(prest_r,prest_g, prest_b, stats_x, stats_y, 0, 0.0, 0.7, 0.1, 0.1, h_stats);
+                  show_hudmessage(i, "Height distance: %.03f",heightland_origin-heightoff_origin[id]);
+                }
+                else if(heightland_origin-heightoff_origin[id]<0.0) {
+                  set_hudmessage(prest_r,prest_g, prest_b, stats_x, stats_y, 0, 0.0, 0.7, 0.1, 0.1, h_stats);
+                  show_hudmessage(i, "Fall distance: %.03f",floatabs(heightland_origin-heightoff_origin[id]));
+                }
+              }
+            }
+          }
+          for(new i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i])) {
+              if(height_show[i]==true) {
+                if(heightland_origin-heightoff_origin[id]==0.0)
+                  client_print(i, print_console,"Jump realise at the same height");
+                else if(heightland_origin-heightoff_origin[id]>0.0)
+                  client_print(i, print_console,"Height distance: %.03f",heightland_origin-heightoff_origin[id]);
+                else if(heightland_origin-heightoff_origin[id]<0.0)
+                  client_print(i, print_console,"Fall distance: %.03f",floatabs(heightland_origin-heightoff_origin[id]));
+              }
+            }
+          }
+          h_jumped[id] = false;
+        }
+        
+        if((movetype[id] != MOVETYPE_FLY)) {
+          if(firstfr[id] == false) {
+            firstfr[id] = true;
+            pev(id, pev_velocity, velocity);
+            pev(id, pev_origin, origin);
+            if((g_Jumped[id] == true || !(flags&FL_ONGROUND)))
+              firstvel[id] = velocity[2];
+            firstorig[id] = origin;
+          }
+          else if(firstfr[id] == true) {
+            pev(id, pev_origin, origin);
+            pev(id, pev_velocity, velocity);
+            secorig[id] = origin;
+            if((g_Jumped[id] == true || !(flags&FL_ONGROUND)))
+              secvel[id] = velocity[2];
+            firstfr[id] = false;
+          }
+          if(!(flags&FL_ONGROUND) && first_air[id] == false) {
+            framecount[id]++;
+            if(framecount[id] == 2)
+              first_air[id] = true;
+            
+            SurfFrames[id] = floatabs(firstvel[id] - secvel[id]);
+            
+            if(floatabs(firstvel[id]-secvel[id])>41)
+              SurfFrames[id] = oldSurfFrames[id];
+            oldSurfFrames[id] = SurfFrames[id];
+          }
+          if(flags&FL_ONGROUND && first_air[id] == true) {
+            first_air[id] = false;
+            framecount[id] = 0;
+          }
+          if(!(flags&FL_ONGROUND) && SurfFrames[id]<7.9 && uq_fps==1 && fps_hight[id]==false)
+            fps_hight[id] = true;
+          if((flags&FL_ONGROUND) && SurfFrames[id]>7.9 && fps_hight[id])
+            fps_hight[id] = false;
+      
+          if(!(flags&FL_ONGROUND) && 1.7*floatabs(firstvel[id]-secvel[id])20.0) {
+            groundslide[id] = 0.0;
+            waits[id] = 0;
+            slidim[id] = false;
+            taskslide[id] = 0;
+            failslide[id] = false;
+            slide[id] = false;
+            g_Jumped[id] = false;
+            return FMRES_IGNORED;
+          }
+          
+          if((g_Jumped[id]==true || h_jumped[id]) && get_distance_f(firstorig[id],secorig[id])>6.0) {
+            h_jumped[id] = false;
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+        }
+        if(slidim[id] == true) {
+          pev(id, pev_origin, origin);
+          new Float:start[33][3],Float:end[33][3];
+        
+          start[id][0] = origin[0];
+          start[id][1] = origin[1] + 16.0;
+          start[id][2] = origin[2];
+          end[id][0] = origin[0];
+          end[id][1] = origin[1] + 16.0;
+          end[id][2] = origin[2] - 500.0;
+          
+          engfunc(EngFunc_TraceLine, start[id], end[id], IGNORE_GLASS, id, 0); 
+          get_tr2(0, TR_vecEndPos, slidez[id][0]);
+      
+          start[id][0] = origin[0];
+          start[id][1] = origin[1] - 16.0;
+          start[id][2] = origin[2];
+          end[id][0] = origin[0];
+          end[id][1] = origin[1] - 16.0;
+          end[id][2] = origin[2] - 500.0;
+          
+          engfunc(EngFunc_TraceLine, start[id], end[id], IGNORE_GLASS, id, 0); 
+          get_tr2(0, TR_vecEndPos, slidez[id][1]);
+          
+          start[id][0] = origin[0] + 16.0;
+          start[id][1] = origin[1];
+          start[id][2] = origin[2];
+          end[id][0] = origin[0] + 16.0;
+          end[id][1] = origin[1];
+          end[id][2] = origin[2] - 500.0;
+          
+          engfunc(EngFunc_TraceLine, start[id], end[id], IGNORE_GLASS, id, 0); 
+          get_tr2( 0, TR_vecEndPos, slidez[id][2]);
+          
+          start[id][0] = origin[0] - 16.0;
+          start[id][1] = origin[1];
+          start[id][2] = origin[2];
+          end[id][0] = origin[0] - 16.0;
+          end[id][1] = origin[1];
+          end[id][2] = origin[2] - 500.0;
+          
+          engfunc(EngFunc_TraceLine, start[id], end[id], IGNORE_GLASS, id, 0); 
+          get_tr2(0, TR_vecEndPos, slidez[id][3]);
+          
+          for(new i=0;i<4;i++) {    
+            if(i != 3) {
+              if(slidez[id][i][2] > slidez[id][i+1][2]) {
+                needslide[id] = slidez[id][i][2];
+                groundslide[id] = slidez[id][i+1][2];
+              
+                if(needslide[id] - groundslide[id] > 149.0 && landslide[id] == false) {
+                  landslide[id] = true;
+                  pev(id, pev_origin, origin);
+                  if(!(is_user_ducking(id)))
+                    origin[2] -= 36.0;
+                  else
+                    origin[2] -= 18.0;
+                  
+                  slideland[id] = origin[2];
+                  slidedist[id] = slideland[id] - groundslide[id];
+                  maxspeed[id] = speed;
+                }
+              }
+            }
+          }
+        
+          if(taskslide[id] == 0) {
+            set_task(0.4, "wait", id + 3313);
+            taskslide[id] = 1;
+          }
+          
+          pev(id, pev_velocity, velocity);
+          if(velocity[1] == 0.0 && failslide[id] == false && !(flags&FL_ONGROUND) && waits[id] == 1) {
+            if(!(is_user_ducking(id)))
+              origin[2] -= 36.0;
+            else
+              origin[2] -= 18.0;
+            failslidez[id] = origin[2];
+            failslide[id] = true;      
+          }
+        }
+        
+        if(flags&FL_ONGROUND && slidim[id] == true && Pmaxspeed == 250.0) {
+          for(new i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i]) && g_lj_stats[i] == true) {
+              if(needslide[id] - groundslide[id] == slidedist[id]) {
+                client_print(i, print_console, "Slide Distance: %d.xxx",floatround(slidedist[id], floatround_floor));
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats);
+                show_hudmessage(i, "Slide Distance: %d.xxx",floatround(slidedist[id], floatround_floor));
+              }
+              else {
+                client_print(i, print_console, "Slide Distance: %f",slidedist[id]);
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats);
+                show_hudmessage(i, "Slide Distance: %f",slidedist[id]);
+              }
+            }
+          }
+                  
+          new iPlayers[32],iNum; 
+          get_players(iPlayers, iNum, "ch");
+          for(new i=0;i 0 && floatabs(velocity[1]) > floatabs(velocity[0]))
+                direct_for_strafe[id] = 1;
+              else if(velocity[1] < 0 && floatabs(velocity[1]) > floatabs(velocity[0]))
+                direct_for_strafe[id] = 2;
+              else if(velocity[0] > 0 && floatabs(velocity[0]) > floatabs(velocity[1]))
+                direct_for_strafe[id] = 3;
+              else if(velocity[0] < 0 && floatabs(velocity[0]) > floatabs(velocity[1]))
+                direct_for_strafe[id] = 4;
+            }
+          }
+          
+          oldjump_height[id] = floatabs(jumpoff_origin[id][2] - origin[2]);
+          
+          if(bug_check[id] == 0 && floatfract(velocity[2]) == 0)
+            bug_check[id] = 1;
+          else if(bug_check[id] == 1 && floatfract(velocity[2]) == 0) {
+            bug_true[id] = true;
+            bug_check[id] = 0;
+          }
+          if(!in_bhop[id])
+            fnSaveBeamPos(id);
+          static Float:old_speed[33];
+          if(speed > old_speed[id])
+            frames_gained_speed[id]++;
+          frames[id]++;
+          
+          old_speed[id] = speed;
+      
+          if(speed > maxspeed[id]) {
+            if(strafe_num[id] < NSTRAFES)
+              strafe_stat_speed[id][strafe_num[id]][0] += speed - maxspeed[id];
+            maxspeed[id] = speed;
+          }
+          if((speed < TempSpeed[id]) && (strafe_num[id] < NSTRAFES)) {
+            strafe_stat_speed[id][strafe_num[id]][1] += TempSpeed[id] - speed;
+            if(strafe_stat_speed[id][strafe_num[id]][1] > 5) {
+              if(floatabs(firstvel[id] - secvel[id]) < SurfFrames[id] - 0.1)
+                Checkframes[id] = true;
+              else if(floatabs(firstvel[id] - secvel[id]) > SurfFrames[id])
+                Checkframes[id] = true;
+            }
+          }
+          TempSpeed[id] = speed;
+          
+          if((origin[2] + 18.0 - jumpoff_origin[id][2] < 0))
+            failed_jump[id] = true;
+          else if((is_user_ducking(id) ? (origin[2] + 18) : origin[2]) >= jumpoff_origin[id][2]) {
+            failed_origin[id] = origin;
+            failed_ducking[id] = is_user_ducking(id);
+            failed_velocity[id] = velocity;
+            origin[2] = pre_jumpoff_origin[id][2];  
+          }
+          if(first_frame[id]) {
+            first_frame[id] = false;
+            frame_velocity[id][0] = velocity;
+            
+            gBeam_count[id] = 0;
+            for(new i = 0; i < 100; i++) {
+              gBeam_points[id][i][0] = 0.0;
+              gBeam_points[id][i][1] = 0.0;
+              gBeam_points[id][i][2] = 0.0;
+              gBeam_duck[id][i] = false;
+              gBeam_button[id][i] = false;
+            }
+            
+            if(in_bhop[id] && jump_type[id]!=Type_DuckBhop) {
+              if(upBhop[id]) {
+                if(jump_type[id] == Type_Up_Bhop_In_Duck) {
+                  formatex(Jtype[id], 32, "Up Bhop In Duck");
+                  formatex(Jtype1[id], 32, "ubid");
+                }
+                else if(velocity[2] < upbhop_koeff[id]) {
+                  jump_type[id] = Type_Up_Bhop;
+                  formatex(Jtype[id], 32, "Up BhopJump");
+                  formatex(Jtype1[id], 32, "ubj");
+                }
+                else {
+                  jump_type[id] = Type_Up_Stand_Bhop;
+                  formatex(Jtype[id], 32, "Up StandUp BhopJump");
+                  formatex(Jtype1[id], 32, "usbj");
+                }
+                upBhop[id] = false;
+              }
+              else if(jump_type[id] == Type_Bhop_In_Duck) {
+                formatex(Jtype[id], 32, "Bhop In Duck");
+                formatex(Jtype1[id], 32, "bid");
+              }
+              else if(velocity[2] < 229.0) {
+                jump_type[id] = Type_BhopLongJump;
+                formatex(Jtype[id], 32, "BhopJump");
+                formatex(Jtype1[id], 32, "bj");
+              }
+              else {
+                jump_type[id] = Type_StandupBhopLongJump;
+                formatex(Jtype[id], 32, "StandUp BhopJump");
+                formatex(Jtype1[id], 32, "sbj");
+                jumpoff_origin[id][2] = pre_jumpoff_origin[id][2];
+              }
+              for(new i = 1; i < max_players; i++) {
+                if((i == id || is_spec_user[i])) {  
+                  if(showpre[i]==true && prestrafe[id]>min_prestrafe[id]) {
+                    if((Pmaxspeed * 1.2)>prestrafe[id]) {
+                      if(jump_type[id] == Type_Up_Bhop_In_Duck && (uq_upbhopinduck == 1)) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Up Bhop In Duck Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(jump_type[id] == Type_Up_Bhop && (uq_upbj == 1)) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Up Bhop Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(jump_type[id] == Type_Up_Stand_Bhop && (uq_upsbj == 1)) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Up StandUp Bhop Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(jump_type[id] == Type_Bhop_In_Duck && uq_bhopinduck == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Bhop In Duck Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(jump_type[id] == Type_BhopLongJump && uq_bj == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "BJ Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(jump_type[id] == Type_StandupBhopLongJump && uq_sbj == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "SBJ Pre: %.03f", prestrafe[id]);
+                      }
+                    }
+                    else {  
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 1.5, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "Your prestrafe %.01f is too high (%.01f)", prestrafe[id], Pmaxspeed * 1.2);
+                    }
+                  }
+                }
+              }
+            }
+            else if(jump_type[id] == Type_DuckBhop) {
+              for(new i = 1; i < max_players; i++) {
+                if((i == id || is_spec_user[i])) {
+                  if(showpre[i] == true && speed > 50.0) {
+                    if((Pmaxspeed * 1.2) > speed) {
+                      if(prestrafe[id] < 200) {
+                        if(jump_type[id] == Type_DuckBhop && (uq_duckbhop == 1)) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Duck Bhop Pre: %.03f", prestrafe[id]);
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          } 
+          else
+            frame_velocity[id][1] = velocity;
+          
+          if(in_bhop[id])
+            fnSaveBeamPos(id);
+      
+          if(detecthj[id] != 1) {  
+            starthj[id][0] = origin[0];
+            starthj[id][1] = origin[1];
+            starthj[id][2] = jumpoff_origin[id][2] + 28.0;
+            stophj[id][0] = origin[0];
+            stophj[id][1] = origin[1];
+            stophj[id][2] = starthj[id][2] - 133.0; 
+              
+            engfunc(EngFunc_TraceLine, starthj[id], stophj[id], IGNORE_MONSTERS, id, 0);
+            get_tr2(0, TR_vecEndPos, endhj[id]);
+            
+            if(starthj[id][2] - endhj[id][2] < 133.0 && (starthj[id][2] - endhj[id][2] - 64) != 0 && (starthj[id][2] - endhj[id][2] - 64) > 0 && detecthj[id] != 1)
+              detecthj[id] = 2;
+            if(starthj[id][2] - endhj[id][2] >= 133.0 && detecthj[id] != 2)
+              detecthj[id] = 1;
+          }
+          
+          if(ddafterJump[id])
+            ddafterJump[id] = false;  
+        }
+        
+        if(notjump[id] && bhopaem[id])
+          notjump[id] = false;
+        
+        if(flags&FL_ONGROUND) {
+          surf[id] = 0.0;
+          if(!pev(id, pev_solid)) {
+            static ClassName[32];
+            pev(pev(id, pev_groundentity), pev_classname, ClassName, 32);
+      
+            if(equali(ClassName, "func_train")
+                || equali(ClassName, "func_conveyor") 
+                || equali(ClassName, "trigger_push") || equali(ClassName, "trigger_gravity")) {
+              JumpReset(id);
+              set_task(0.4, "JumpReset", id);
+            }
+            else if(equali(ClassName, "func_door") || equali(ClassName, "func_door_rotating")) {
+              JumpReset(id);
+              set_task(0.4, "JumpReset", id);  
+            }
+          }
+          
+          pev(id, pev_origin, origin);
+          notjump[id] = true;
+          if(is_user_ducking(id))
+            falloriginz[id] = origin[2] + 18;
+          else
+            falloriginz[id] = origin[2];
+          
+          if(OnGround[id] == false) {  
+            if(dropbhop[id] || in_ladder[id] || jump_type[id] == Type_WeirdLongJump || jump_type[id] == Type_ladderBhop || jump_type[id] == Type_Drop_BhopLongJump)
+              FallTime[id] = get_gametime();
+            OnGround[id] = true;
+          }
+        }
+        
+        if(!(flags&FL_ONGROUND) && notjump[id] == true && (movetype[id] != MOVETYPE_FLY) && jump_type[id] != Type_ladderBhop) {  
+          pev(id, pev_origin, origin);
+          OnGround[id] = false;
+          pev(id, pev_velocity, velocity);
+          new Float:tempfall;
+          if(is_user_ducking(id))
+            tempfall = origin[2] + 18;
+          else
+            tempfall = origin[2];
+          
+          if(falloriginz[id] - tempfall > 1.0
+              && !cjjump[id] && (ddforcj[id]
+              || jump_type[id] == Type_Drop_CountJump
+              || jump_type[id] == Type_StandUp_CountJump
+              || jump_type[id] == Type_None
+              || jump_type[id] == Type_CountJump
+              || jump_type[id] == Type_Multi_CountJump
+              || jump_type[id] == Type_Double_CountJump)) {
+            oldjump_type[id] = 0;
+      
+            formatex(Jtype[id], 32, "WeirdJump");
+            formatex(Jtype1[id], 32, "wj");
+            
+            if(ddforcj[id])
+              ddforcj[id] = false;
+            
+            jump_type[id] = Type_WeirdLongJump;
+          }
+          
+          if(velocity[2] == -240.0) {
+            oldjump_type[id] = 0;
+            ddbeforwj[id] = true;
+            jump_type[id] = Type_WeirdLongJump;  
+            formatex(Jtype[id], 32, "WeirdJump after dd");
+            formatex(Jtype1[id], 32, "dd+wj");
+          }
+        }
+        else if(!(flags&FL_ONGROUND) && notjump[id] == false && (movetype[id] != MOVETYPE_FLY) && in_ladder[id] == false && jump_type[id] != Type_Slide) {
+          oldjump_type[id] = 0;
+          OnGround[id] = false;
+      
+          pev(id, pev_velocity, velocity);
+          pev(id, pev_origin, origin);
+          
+          new Float:drbh;
+          if(is_user_ducking(id))
+            drbh = origin[2] + 18;
+          else
+            drbh = origin[2];
+      
+          if(dropbjorigin[id][2] - drbh > 2.0) {
+            if(dropbjorigin[id][2] - drbh < 30 && jump_type[id] != Type_Drop_BhopLongJump && jump_type[id] != Type_None) {
+              old_type_dropbj[id] = jump_type[id];
+              formatex(Jtype_old_dropbj[id], 32, Jtype[id]);
+              formatex(Jtype_old_dropbj1[id], 32, Jtype1[id]);
+            }
+            
+            jump_type[id] = Type_Drop_BhopLongJump;
+            formatex(Jtype[id], 32, "Drop Bhop");
+            formatex(Jtype1[id], 32, "drbj");
+            nextbhop[id] = false;
+            bhopaem[id] = false;
+            dropbhop[id] = true;
+          }
+        }
+        
+        if(movetype[id] == MOVETYPE_FLY) {
+          OnGround[id] = false;
+          firstvel[id] = 8.0;
+          secvel[id] = 0.0;
+          checkladdertime[id] = get_gametime();
+        }
+        if(movetype[id] == MOVETYPE_FLY && firstladder[id] == false) {
+          firstladder[id] = true;
+          nextbhop[id] = false;
+          bhopaem[id] = false;
+          h_jumped[id] = false;
+          JumpReset(id);
+          return FMRES_IGNORED;
+        }
+        if(movetype[id] != MOVETYPE_FLY && firstladder[id] == true && flags&FL_ONGROUND)
+          firstladder[id] = false;
+        if((movetype[id] == MOVETYPE_FLY) &&  (button&IN_FORWARD || button&IN_BACK || button&IN_LEFT || button&IN_RIGHT)) {
+          ladderjump[id] = true;
+          find_sphere_class (id, "func_ladder", 18.0, entlist1, 1);
+          
+          if(entlist1[0] != 0)
+            for(new i=0;i laddersize[nashladder][1])
+            laddist[id] = laddersize[nashladder][1] + 0.03125;
+          
+          if(laddist[id] > 10)
+            laddist[id] = 4.0;
+          ladderjump[id] = false;  
+          TempSpeed[id] = 0.0;
+          static i;
+          for(i = 0; i < NSTRAFES; i++) {
+            strafe_stat_speed[id][i][0] = 0.0;
+            strafe_stat_speed[id][i][1] = 0.0;
+            strafe_stat_sync[id][i][0] = 0;
+            strafe_stat_sync[id][i][1] = 0;
+            strafe_stat_time[id][i] = 0.0;
+            strafe_lost_frame[id][i] = 0;
+            
+          }
+          in_air[id] = true;
+          in_ladder[id] = true;
+          g_Jumped[id] = true;
+          first_frame[id] = true;
+          
+          turning_right[id] = false;
+          turning_left[id] = false;
+          
+          for(i = 0; i < 2; i++) {
+            frame_origin[id][i][0] = 0.0;
+            frame_origin[id][i][1] = 0.0;
+            frame_origin[id][i][2] = 0.0;
+            frame_velocity[id][i][0] = 0.0;
+            frame_velocity[id][i][1] = 0.0;
+            frame_velocity[id][i][2] = 0.0;
+          }
+          for(i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i])) {
+              if(showpre[id] == true && uq_ladder == 1) {
+                set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 1.0, 0.1, 0.1, h_prest);
+                show_hudmessage(i, "Ladder Pre: %f", prestrafe[id]);
+              }
+            }
+          }
+        }
+        
+        if(button & IN_JUMP && flags & FL_ONGROUND) {
+          x_jump[id] = true;
+          if(is_user_ducking(id))
+            x_heightland_origin[id] = origin[2] + 18;
+          else
+            x_heightland_origin[id] = origin[2];
+        }
+        
+        if((x_jump[id] == true || in_ladder[id]) && button & IN_DUCK && !(oldbuttons &IN_DUCK) && flags & FL_ONGROUND) {
+          if(x_jump[id]) {
+            x_jump[id] = false;
+            
+            new Float:heightland_origin;
+            if(is_user_ducking(id))
+              heightland_origin = origin[2] + 18;
+            else
+              heightland_origin = origin[2];
+            if(heightland_origin - x_heightland_origin[id] > 0) {
+              JumpReset(id);
+              UpcjFail[id] = true;
+              return FMRES_IGNORED;
+            }
+            ddforcj[id] = true;
+          }
+          else if(in_ladder[id]) {
+            new Float:heightland_origin;
+            if(is_user_ducking(id))
+              heightland_origin = origin[2] + 18;
+            else
+              heightland_origin = origin[2];
+            
+            if(heightland_origin - jumpoff_origin[id][2] > -64) {
+              JumpReset(id);
+              UpcjFail[id]=true;
+              in_ladder[id]=false;
+              return FMRES_IGNORED;
+            }
+          }
+        }
+        
+        if(cjjump[id] == false
+            && (button & IN_DUCK || oldbuttons & IN_DUCK)
+            && (jump_type[id] == Type_Drop_CountJump
+            || ddafterJump[id] || jump_type[id] == Type_CountJump
+            || jump_type[id] == Type_Multi_CountJump
+            || jump_type[id] == Type_Double_CountJump)) {
+          if(origin[2] - duckstartz[id] < -1.21 && origin[2] - duckstartz[id] > -2.0) {
+            if(ddafterJump[id]) {
+              nextbhop[id] = false;
+              bhopaem[id] = false;
+            }
+            if(jump_typeOld[id] == 1)
+              multiscj[id] = 0;  
+            else if(jump_typeOld[id] == 2)
+              multiscj[id] = 1;
+            else if(jump_typeOld[id] == 3)
+              multiscj[id] = 2;
+            jump_type[id] = Type_StandUp_CountJump;
+            
+            formatex(Jtype[id], 32, "StandUp CountJump");
+            formatex(Jtype1[id], 32, "scj");
+            
+            FallTime[id] = get_gametime();
+          }
+        }
+        
+        if(button & IN_DUCK && !(oldbuttons &IN_DUCK) && flags & FL_ONGROUND) {
+          nextbhop[id] = false;
+          bhopaem[id] = false;
+          
+          doubleduck[id] = true;
+          doubletime[id] = get_gametime();
+          FallTime1[id] = get_gametime();
+          ddnum[id]++;
+        }
+        
+        if(flags & FL_ONGROUND) {
+          if(duckstartz[id] - origin[2] < 18.0
+              && doubleduck[id] == true
+              && (get_gametime() - doubletime[id] > 0.4)
+              && ddbeforwj[id] == false
+              && (jump_type[id] == Type_CountJump
+              || jump_type[id] == Type_Multi_CountJump
+              || jump_type[id] == Type_Double_CountJump)) {
+            JumpReset(id);
+            doubleduck[id] = false;
+          }
+        }
+        pev(id, pev_origin, origin);
+        if(slide_protec[id] == false
+            && button & IN_JUMP
+            && !(oldbuttons & IN_JUMP)
+            && flags & FL_ONGROUND
+            && bhopaem[id] == true
+            && ddafterJump[id] == true
+            && UpcjFail[id] == false) {
+          if(touch_ent[id])
+            JumpReset(id);
+          ddnum[id] = 0;
+          notjump[id] = false;
+          strafe_num[id] = 0;
+            
+          if(get_gametime() - changetime[id] < 0.5) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          
+          if(task_exists(id + 2311))
+            remove_task(id + 2311);
+        
+          jumpoff_origin[id] = origin;
+        
+          if(is_user_ducking(id) == true)
+            jumpoff_origin[id][2] = origin[2] + 18.0;
+          else
+            jumpoff_origin[id][2] = origin[2];
+          
+          jumpoff_time[id] = get_gametime();
+          strafecounter_oldbuttons[id] = 0;
+      
+          pev(id, pev_velocity, velocity);
+          secorig[id] = origin;
+          
+          nextbhop[id] = true;
+          if(jump_type[id] == Type_Drop_CountJump
+              || jump_type[id] == Type_StandUp_CountJump
+              || jump_type[id] == Type_CountJump
+              || jump_type[id] == Type_Multi_CountJump
+              || jump_type[id] == Type_Double_CountJump) {
+            cjjump[id] = true;
+          }
+          if((jump_type[id] == Type_CountJump
+              || jump_type[id] == Type_Multi_CountJump
+              || jump_type[id] == Type_Double_CountJump)
+              && floatabs(duckstartz[id] - jumpoff_origin[id][2]) > 4.0) {
+            if(speed < 200.0) {
+              jump_type[id] = Type_LongJump;
+              formatex(Jtype[id], 32, "LongJump");
+              formatex(Jtype1[id], 32, "lj");
+            }
+            else {
+              jump_type[id] = Type_WeirdLongJump;  
+              formatex(Jtype[id], 32, "WeirdJump");
+              formatex(Jtype1[id], 32, "wj");
+            }
+          }
+          
+          TempSpeed[id] = 0.0;
+          
+          static i;
+          for(i = 0; i < NSTRAFES; i++) {
+            strafe_stat_speed[id][i][0] = 0.0;
+            strafe_stat_speed[id][i][1] = 0.0;
+            strafe_stat_sync[id][i][0] = 0;
+            strafe_stat_sync[id][i][1] = 0;
+            strafe_stat_time[id][i] = 0.0;
+            strafe_lost_frame[id][i] = 0;
+          }
+          in_air[id] = true;
+          g_Jumped[id] = true;
+          first_frame[id] = true;
+          
+          prestrafe[id] = speed;
+          maxspeed[id] = speed;
+          
+          turning_right[id] = false;
+          turning_left[id] = false;
+      
+          for(i = 0; i < 2; i++) {
+            frame_origin[id][i][0] = 0.0;
+            frame_origin[id][i][1] = 0.0;
+            frame_origin[id][i][2] = 0.0;
+            frame_velocity[id][i][0] = 0.0;
+            frame_velocity[id][i][1] = 0.0;
+            frame_velocity[id][i][2] = 0.0;
+          }
+          
+          for(i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i])) {
+              if((Pmaxspeed * 1.2) > prestrafe[id]) {  
+                if(prestrafe[id] > min_prestrafe[id]) {
+                  if(jump_type[id] == Type_Double_CountJump && showpre[id] == true && uq_dcj == 1) {
+                    if(CjafterJump[id] == 2) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "DCJ After Bhop Jump Pre: %.03f", prestrafe[id]);
+                    }
+                  }
+                  else if(jump_type[id] == Type_CountJump && showpre[id] == true && uq_cj == 1) {
+                    if(CjafterJump[id] == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "CJ After Bhop Jump Pre: %.03f", prestrafe[id]);
+                    }
+                  }
+                  else if(jump_type[id] == Type_Multi_CountJump  && showpre[id] == true && uq_mcj == 1) {
+                    if(CjafterJump[id] == 3) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "MCJ After Bhop Jump Pre: %.03f", prestrafe[id]);
+                    }
+                  }
+                }
+              }
+              else if(showpre[id] == true) {
+                set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 1.5, 0.1, 0.1, h_prest);
+                show_hudmessage(i, "Your prestrafe %.03f is too high (%.01f)", prestrafe[id], Pmaxspeed * 1.2);
+              }  
+            }
+          }
+        }
+        else if(slide_protec[id] == false && button & IN_JUMP && !( oldbuttons & IN_JUMP ) && flags & FL_ONGROUND && bhopaem[id] == false && UpcjFail[id] == false) {  
+          bhop_num[id] = 0;
+          notjump[id] = false;
+          if(ddforcj[id] == true) {
+            ddforcj[id] = false;
+            if(nextbhop[id]) {
+              if(ddnum[id] == 1) {
+                jump_type[id] = Type_CountJump;
+                CjafterJump[id] = 1;
+              }
+              else if(ddnum[id] == 2) {
+                jump_type[id] = Type_Double_CountJump;
+                CjafterJump[id] = 2;
+              }
+              else if(ddnum[id] >= 3) {
+                jump_type[id] = Type_Multi_CountJump;
+                CjafterJump[id] = 3;
+              }
+              ddnum[id] = 0;
+              nextbhop[id] = false;
+              bhopaem[id] = false;
+            }
+            else if(jump_type[id] == Type_Real_ladder_Bhop)
+              jump_type[id] = Type_Drop_CountJump;
+          }
+          oldjump_height[id] = 0.0;
+          jheight[id] = 0.0;
+          
+          if(nextbhop[id] && ddafterJump[id] == false) {
+            FullJumpFrames[id] = 0;
+            direct_for_strafe[id] = 0;
+            
+            if(uq_istrafe) {
+              for(new i=0;i<=line_erase_strnum[id];i++) {
+                for(new j = 0; j <= line_erase[id][i]; j++) {
+                  line_lost[id][i][j] = 0;
+                  lost_frame_count[id][i] = 0;
+                }
+              }
+            }
+            
+            edgedone[id] = false;
+            if(get_gametime() - checkladdertime[id] < 0.5)
+              ladderbug[id] = true;
+            
+            if(touch_ent[id])
+              JumpReset(id);
+            ddnum[id] = 0;
+            
+            if(cjjump[id] == true && (get_gametime() - duckoff_time[id]) < 0.2) {
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+          
+            if(oldbuttons & IN_DUCK && button & IN_DUCK && duckbhop[id]==true && (jump_type[id]==Type_HighJump || jump_type[id]==Type_LongJump || jump_type[id]==Type_None)) {
+              jump_type[id] = Type_DuckBhop;
+              formatex(Jtype[id], 32, "DuckBhop");
+              formatex(Jtype1[id], 32, "dkbj");
+              duckbhop[id] = false;
+            }
+            
+            bhopaem[id] = true;
+            
+            pev(id, pev_origin, origin);
+            static bool:ducking;
+            ducking = is_user_ducking(id);
+            strafecounter_oldbuttons[id] = 0;
+          
+            strafe_num[id] = 0;
+            TempSpeed[id] = 0.0;
+            in_bhop[id] = true;
+            pre_jumpoff_origin[id] = jumpoff_origin[id];
+            jumpoff_foot_height[id] = ducking ? origin[2] - 18.0 : origin[2] - 36.0;
+            
+            jumpoff_time[id] = get_gametime();
+            
+            new Float:checkbhop;
+            
+            if(is_user_ducking(id) == true)
+              checkbhop = jumpoff_origin[id][2] - origin[2] - 18.0;
+            else
+              checkbhop = jumpoff_origin[id][2] - origin[2];
+            
+            if(checkbhop < -1.0) {
+              if(button & IN_DUCK)
+                jump_type[id] = Type_Up_Bhop_In_Duck;
+              upbhop_koeff[id]=UpBhop_calc(floatabs(checkbhop));
+              upheight[id] = floatabs(checkbhop);
+              upBhop[id] = true;
+            }
+            else if(jump_type[id]!=Type_DuckBhop) {
+              if(button & IN_DUCK)
+                jump_type[id] = Type_Bhop_In_Duck;
+            }
+            
+            jumpoff_origin[id] = origin;
+            if(is_user_ducking(id) == true)
+              jumpoff_origin[id][2] = origin[2]+18.0;
+            else
+              jumpoff_origin[id][2] = origin[2];
+            
+            pev(id, pev_velocity, velocity);
+            first_frame[id] = true;
+            
+            prestrafe[id] = speed;
+            maxspeed[id] = speed;
+            
+            static i;
+            for(i = 0; i < NSTRAFES; i++) {
+              strafe_stat_speed[id][i][0] = 0.0;
+              strafe_stat_speed[id][i][1] = 0.0;
+              strafe_stat_sync[id][i][0] = 0;
+              strafe_stat_sync[id][i][1] = 0;
+              strafe_stat_time[id][i] = 0.0;
+              strafe_lost_frame[id][i] = 0;
+            }
+            for(i = 0; i < 2; i++) {
+              frame_origin[id][i][0] = 0.0;
+              frame_origin[id][i][1] = 0.0;
+              frame_origin[id][i][2] = 0.0;
+              frame_velocity[id][i][0] = 0.0;
+              frame_velocity[id][i][1] = 0.0;
+              frame_velocity[id][i][2] = 0.0;
+            }
+            in_air[id] = true;
+            g_Jumped[id] = true;
+            turning_right[id] = false;
+            turning_left[id] = false;
+          }
+          else {
+            if(get_gametime() - checkladdertime[id] < 0.5 && jump_type[id] != Type_ladderBhop)
+              ladderbug[id] = true;
+            
+            if(touch_ent[id])
+              JumpReset(id);
+            ddnum[id] = 0;
+            if(in_ladder[id] == true) {
+              in_ladder[id] = false;
+              jump_type[id] = Type_Real_ladder_Bhop;
+              formatex(Jtype[id], 32, "Real Ladder bhop");
+              formatex(Jtype1[id], 32, "rldbj");
+            }
+            
+            strafe_num[id] = 0;
+            
+            if(get_gametime() - changetime[id] < 0.5) {
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+            
+            if(task_exists(id + 2311))
+              remove_task(id + 2311);
+            
+            pev(id, pev_velocity, velocity);
+            
+            if(jump_type[id] != Type_ladderBhop) {
+              if(oldjump_typ1[id] == 1) {
+                jump_type[id] = Type_ladderBhop;
+                oldjump_typ1[id] = 0;
+              }
+            }
+            
+            jumpoff_origin[id] = origin;
+            
+            if(is_user_ducking(id))
+              jumpoff_origin[id][2] = origin[2] + 18.0;
+            else
+              jumpoff_origin[id][2] = origin[2];
+            
+            jumpoff_time[id] = get_gametime();
+            strafecounter_oldbuttons[id] = 0;
+            
+            pev(id, pev_origin, origin);
+            if(is_user_ducking(id))
+              dropbjorigin[id][2] = origin[2] + 18;
+            else
+              dropbjorigin[id][2] = origin[2];
+            dropbjorigin[id][0] = origin[0];
+            dropbjorigin[id][1] = origin[1];
+            pev(id, pev_velocity, velocity);
+            secorig[id] = origin;
+            
+            nextbhop[id] = true;
+            
+            if(dropbhop[id] && jump_type[id] != Type_Drop_CountJump && jump_type[id] != Type_StandUp_CountJump) {
+              dropbhop[id] = false;
+              jump_type[id] = Type_Drop_BhopLongJump; 
+            }
+            else
+              dropbhop[id] = false;
+            
+            if(jump_type[id]==Type_CountJump || jump_type[id]==Type_Multi_CountJump || jump_type[id]==Type_Double_CountJump)
+              cjjump[id] = true;
+            if((jump_type[id] == Type_CountJump
+                || jump_type[id] == Type_Multi_CountJump
+                || jump_type[id] == Type_Double_CountJump)
+                && floatabs(duckstartz[id] - jumpoff_origin[id][2]) > 4.0) {
+              if(speed < 200.0) {
+                jump_type[id] = Type_LongJump;
+                formatex(Jtype[id], 32, "LongJump");
+                formatex(Jtype1[id], 32, "lj");
+              }
+              else {
+                jump_type[id] = Type_WeirdLongJump;  
+                formatex(Jtype[id], 32, "WeirdJump");
+                formatex(Jtype1[id], 32, "wj");
+              }
+            }
+            if(jump_type[id] == Type_Drop_CountJump && multidropcj[id] == 0 && (origin[2] - first_duck_z[id]) > 4) {
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+            prestrafe[id] = speed;
+            maxspeed[id] = speed;
+            new Float:kkk;
+              
+            kkk = 1.112 * Pmaxspeed;
+            
+            if(prestrafe[id] < kkk
+                && jump_type[id] != Type_ladderBhop
+                && jump_type[id] != Type_Drop_BhopLongJump
+                && jump_type[id] != Type_WeirdLongJump
+                && jump_type[id] != Type_CountJump
+                && jump_type[id] != Type_Multi_CountJump
+                && jump_type[id] != Type_Double_CountJump
+                && jump_type[id] != Type_BhopLongJump
+                && jump_type[id] != Type_StandupBhopLongJump
+                && jump_type[id] != Type_Drop_CountJump) {
+              if(jump_type[id] != Type_Drop_CountJump && jump_type[id] != Type_StandUp_CountJump && jump_type[id] != Type_Real_ladder_Bhop) {
+                jump_type[id] = Type_LongJump;
+                formatex(Jtype[id], 32, "LongJump");
+                formatex(Jtype1[id], 32, "lj");
+                
+                if((jumpoff_origin[id][2] - origin[2]) == 18.0 && oldbuttons & IN_DUCK && button & IN_DUCK && duckbhop[id] == false) {
+                  duckbhop[id] = true;
+                  find_sphere_class(id, "func_ladder", 100.0, entlist1, 1);
+                  if(entlist1[0] != 0) {
+                    if(get_gametime() - checkladdertime[id] < 0.1 || prestrafe[id] > 110)
+                      ladderbug[id] = true;
+                    else if(entlist1[0] != 0)
+                      ladderbug[id] = true;
+                    find_ladder[id] = true;
+                  }
+                }
+                else
+                  duckbhop[id] = false;
+              }
+            }
+            
+            TempSpeed[id] = 0.0;
+            
+            static i;
+            for(i = 0; i < NSTRAFES; i++) {
+              strafe_stat_speed[id][i][0] = 0.0;
+              strafe_stat_speed[id][i][1] = 0.0;
+              strafe_stat_sync[id][i][0] = 0;
+              strafe_stat_sync[id][i][1] = 0;
+              strafe_stat_time[id][i] = 0.0;
+              strafe_lost_frame[id][i] = 0;
+            }
+            in_air[id] = true;
+            g_Jumped[id] = true;
+            first_frame[id] = true;
+            
+            prestrafe[id] = speed;
+            maxspeed[id] = speed;
+            
+            turning_right[id] = false;
+            turning_left[id] = false;
+            
+            for(i = 0; i < 2; i++) {
+              frame_origin[id][i][0] = 0.0;
+              frame_origin[id][i][1] = 0.0;
+              frame_origin[id][i][2] = 0.0;
+              frame_velocity[id][i][0] = 0.0;
+              frame_velocity[id][i][1] = 0.0;
+              frame_velocity[id][i][2] = 0.0;
+            }
+            
+            if(jump_type[id] == Type_LongJump && prestrafe[id] > kkk) {
+              jump_type[id] = Type_WeirdLongJump;
+              formatex(Jtype[id], 32, "WeirdJump");
+              formatex(Jtype1[id], 32, "wj");
+            }
+            
+            for(i = 1; i < max_players; i++) {
+              if((i == id || is_spec_user[i])) {
+                if((Pmaxspeed * 1.2) > prestrafe[id]) {  
+                  if(prestrafe[id] > min_prestrafe[id]) {
+                    if(jump_type[id] == Type_Double_CountJump && showpre[id] == true && uq_dcj == 1) {
+                      if(CjafterJump[id] == 2) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "DCJ After Jump Pre: %.03f", prestrafe[id]);
+                      }
+                      else {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "DCJ Pre: %.03f", prestrafe[id]);
+                      }
+                    }
+                    else if(jump_type[id] == Type_CountJump && showpre[id] == true && uq_cj == 1) {
+                      if(CjafterJump[id] == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "CJ After Jump Pre: %.03f", prestrafe[id]);
+                      }
+                      else {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "CJ Pre: %.03f", prestrafe[id]);
+                      }
+                    }
+                    else if(jump_type[id] == Type_Multi_CountJump && showpre[id] == true && uq_mcj == 1) {
+                      if(CjafterJump[id] == 3) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "MCJ After Jump Pre: %.03f", prestrafe[id]);
+                      }
+                      else {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "MCJ Pre: %.03f", prestrafe[id]);
+                      }
+                    }
+                    else if(jump_type[id] == Type_LongJump && showpre[id] == true && ljpre[id] == true && uq_lj == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "Prestrafe: %.03f", prestrafe[id]);
+                    }
+                    else if(jump_type[id] == Type_WeirdLongJump && showpre[id] == true && ddbeforwj[id] == true && uq_wj == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "DD+WJ Pre: %.03f", prestrafe[id]);
+                    }
+                    else if(jump_type[id] == Type_WeirdLongJump && showpre[id] == true && ddbeforwj[id] == false && uq_wj == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "WJ Pre: %.03f", prestrafe[id]);
+                    }
+                    else if((jump_type[id] == Type_Drop_BhopLongJump) && showpre[id] == true && uq_drbj == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "Drop BJ Pre: %.03f", prestrafe[id]);
+                    }
+                    else if((jump_type[id] == Type_ladderBhop) && showpre[id] == true && uq_ldbj == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "Ladder Bhop Pre: %.03f", prestrafe[id]);
+                    }
+                    else if((jump_type[id] == Type_Drop_CountJump) && showpre[id] == true) {
+                      if(multidropcj[id] == 0 && uq_drcj == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Drop CJ Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(multidropcj[id] == 1 && uq_dropdcj == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Double Drop CJ Pre: %.03f", prestrafe[id]);
+                      }
+                      else if(multidropcj[id] == 2 && uq_dropmcj == 1) {
+                        set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                        show_hudmessage(i, "Multi Drop CJ Pre: %.03f", prestrafe[id]);
+                      }
+                    }
+                    else if((jump_type[id] == Type_StandUp_CountJump) && showpre[id] == true && uq_drsbj == 1) {
+                      if(dropaem[id]) {
+                        if(multiscj[id] == 0 && uq_dropscj == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Drop SCJ Pre: %.03f", prestrafe[id]);
+                        }
+                        else if(multiscj[id] == 1 && uq_dropdscj == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Drop Double SCJ Pre: %.03f", prestrafe[id]);
+                        }
+                        else if(multiscj[id] == 2 && uq_dropmscj == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Drop Multi SCJ Pre: %.03f", prestrafe[id]);
+                        }
+                      }
+                      else if(ddafterJump[id]) {
+                        if(multiscj[id] == 0) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "SCJ After Jump Pre: %.03f", prestrafe[id]);
+                        }
+                        else if(multiscj[id] == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Double SCJ After Jump Pre: %.03f", prestrafe[id]);
+                        }
+                        else if(multiscj[id] == 2) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Multi SCJ After Jump Pre: %.03f", prestrafe[id]);
+                        }
+                      }
+                      else {
+                        if(multiscj[id] == 0 && uq_drsbj == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "SCJ Pre: %.03f", prestrafe[id]);
+                        }
+                        else if(multiscj[id] == 1 && uq_dscj == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Double SCJ Pre: %.03f", prestrafe[id]);
+                        }
+                        else if(multiscj[id] == 2 && uq_mscj == 1) {
+                          set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                          show_hudmessage(i, "Multi SCJ Pre: %.03f", prestrafe[id]);
+                        }
+                      }
+                    }
+                    else if((jump_type[id] == Type_Real_ladder_Bhop) && showpre[id] == true && uq_realldbhop == 1) {
+                      set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                      show_hudmessage(i, "Real ladder Bhop Pre: %.03f", prestrafe[id]);
+                    }
+                  }
+                }
+                else if(showpre[id] == true) {
+                  set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 1.5, 0.1, 0.1, h_prest);
+                  show_hudmessage(i, "Your prestrafe %.03f is too high (%.01f)", prestrafe[id], Pmaxspeed * 1.2);
+                }
+              }
+            }
+          }
+        }
+        else if(slide_protec[id] == false
+            && ddafterJump[id] == false
+            && UpcjFail[id] == false
+            && bhopaem[id] == true
+            && button & IN_JUMP
+            && !(oldbuttons & IN_JUMP)
+            && flags & FL_ONGROUND) {
+          if(touch_ent[id])
+            JumpReset(id);
+          ddnum[id] = 0;
+          if(ddforcj[id] == true) {
+            ddforcj[id] = false;
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          pev(id, pev_origin, origin);
+          static bool:ducking;
+          ducking = is_user_ducking(id);
+          strafecounter_oldbuttons[id] = 0;
+        
+          strafe_num[id] = 0;
+          TempSpeed[id] = 0.0;
+          
+          pre_jumpoff_origin[id] = jumpoff_origin[id];
+          jumpoff_foot_height[id] = ducking ? origin[2] - 18.0 : origin[2] - 36.0;
+          
+          jumpoff_time[id] = get_gametime();
+          
+          jumpoff_origin[id] = origin;
+          if(is_user_ducking(id) == true)
+            jumpoff_origin[id][2] = origin[2] + 18.0;
+          else
+            jumpoff_origin[id][2] = origin[2];
+          pev(id, pev_velocity, velocity);
+          
+          first_frame[id] = true;
+          
+          prestrafe[id] = speed;
+          maxspeed[id] = speed;
+          
+          static i;
+          for(i = 0; i < NSTRAFES; i++) {
+            strafe_stat_speed[id][i][0] = 0.0;
+            strafe_stat_speed[id][i][1] = 0.0;
+            strafe_stat_sync[id][i][0] = 0;
+            strafe_stat_sync[id][i][1] = 0;
+            strafe_stat_time[id][i] = 0.0;
+            strafe_lost_frame[id][i] = 0;
+          }
+          for(i = 0; i < 2; i++) {
+            frame_origin[id][i][0] = 0.0;
+            frame_origin[id][i][1] = 0.0;
+            frame_origin[id][i][2] = 0.0;
+            frame_velocity[id][i][0] = 0.0;
+            frame_velocity[id][i][1] = 0.0;
+            frame_velocity[id][i][2] = 0.0;
+          }
+          in_air[id] = true;
+          g_Jumped[id] = true;
+          turning_right[id] = false;
+          turning_left[id] = false;
+          jump_type[id] = Type_Multi_Bhop;
+          formatex(Jtype[id], 32, "Multi Bhop");
+          formatex(Jtype1[id], 32, "mbj");
+        
+          bhop_num[id]++;
+          for(new i = 1; i < max_players; i++) {
+            if((i == id || is_spec_user[i])) {  
+              if(showpre[i] == true && multibhoppre[id] && speed > 50.0) {
+                if((Pmaxspeed * 1.2) > speed && (uq_bj == 1 || uq_sbj == 1)) {
+                  set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                  show_hudmessage(i, "Multi Bhop Pre: %.03f", speed);
+                }
+                else {
+                  if((uq_bj == 1 || uq_sbj == 1)) {
+                    set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 1.5, 0.1, 0.1, h_prest);
+                    show_hudmessage(i, "Your prestrafe %.01f is high(%.01f)", prestrafe[id], Pmaxspeed * 1.2);
+                  }
+                }
+              }
+            }
+          }
+        }
+        else if(slide_protec[id] == false
+            && ddafterJump[id] == false
+            && UpcjFail[id] == false
+            && !(button&IN_JUMP)
+            && oldbuttons&IN_JUMP
+            && flags & FL_ONGROUND
+            && nextbhop[id] == true
+            && cjjump[id] == false
+            && bhopaem[id] == false
+            && jump_type[id] != Type_Drop_BhopLongJump) {
+          if(touch_ent[id])
+            JumpReset(id);
+          ddnum[id] = 0;
+          if(ddforcj[id] == true) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          bhop_num[id] = 0;
+      
+          if(oldbuttons & IN_DUCK && button & IN_DUCK && duckbhop[id] == true && (jump_type[id] == Type_LongJump || jump_type[id] == Type_None)) {
+            jump_type[id] = Type_DuckBhop;
+            formatex(Jtype[id], 32, "DuckBhop");
+            formatex(Jtype1[id], 32, "dkbj");
+            duckbhop[id] = false;
+          }
+          else {
+            bhopaem[id] = true;
+            
+            static i;
+            for(i = 1; i < max_players; i++) {
+              if((i == id || is_spec_user[i])) {
+                if(showpre[id] == true && failearly[id] == true && (uq_bj == 1 || uq_sbj == 1)) {
+                  set_hudmessage(255, 0, 109, -1.0, 0.70, 0, 0.0, 0.5, 0.1, 0.1, h_stats);
+                  show_hudmessage(id, "You pressed jump too early");
+                }
+              }
+            }
+          }
+        }
+        else if((failed_jump[id] || flags&FL_ONGROUND) && in_air[id]) {
+          if(old_type_dropbj[id] != Type_Null && jump_type[id] == Type_Drop_BhopLongJump) {
+            jump_type[id] = old_type_dropbj[id];
+            formatex(Jtype[id], 32, Jtype_old_dropbj[id]);
+            formatex(Jtype1[id], 32, Jtype_old_dropbj1[id]);
+          }
+          if(bug_true[id]) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          if(prestrafe[id] > 200 && jump_type[id] == Type_DuckBhop) {
+            duckbhop_bug_pre[id] = true;
+            set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 1.5, 0.1, 0.1, h_prest);
+            show_hudmessage(id, "Your prestrafe %.01f probably bugged for DuckBhop", prestrafe[id]);
+          }
+          new summad,summws;
+          for(new i=0;i summad) {
+            if(backwards[id])
+              pre_type[id] = "[Backwards-Sideways]";
+            else
+              pre_type[id] = "[Sideways]";
+          }
+          else if(backwards[id])
+            pre_type[id] = "[Backwards]";
+          else
+            pre_type[id] = "";
+      
+          static bool:ducking;
+          
+          static type[33];
+          type[0] = '^0';
+          new bool:failed;
+          if(failed_jump[id] == true) {
+            formatex(type, 32, "");
+            failed = true;
+            origin = failed_origin[id];
+          }
+          else {
+            pev(id, pev_origin, origin);
+            ducking = is_user_ducking(id);
+            failed = false;
+          }
+          
+          if(donehook[id]) {
+            donehook[id] = false;
+            failed_jump[id] = true;
+            client_print(id, print_center, "Hook protection");    
+          }  
+          if(failed == false) {
+            height_difference[id] =  ducking ? jumpoff_origin[id][2] - origin[2] - 18.0 : jumpoff_origin[id][2] - origin[2];
+            if(jump_type[id] == Type_BhopLongJump || jump_type[id] == Type_StandupBhopLongJump || jump_type[id] == Type_Bhop_In_Duck) {
+              if(height_difference[id] < -22.0) {
+                JumpReset(id);
+                return FMRES_IGNORED;
+              }
+              if(height_difference[id] > -18.0) {
+                if(height_difference[id] <= -1.0) {
+                  JumpReset(id);
+                  return FMRES_IGNORED;
+                }  
+              }
+            }
+            else {
+              if(height_difference[id] < -1.0) {
+                JumpReset(id);
+                return FMRES_IGNORED;  
+              }  
+            }
+            if(jump_type[id]==Type_StandupBhopLongJump) {
+              if(height_difference[id] > 1.0)
+                failed_jump[id] = true; 
+            }
+            else if(height_difference[id] > 0.0 && jump_type[id] != Type_Drop_BhopLongJump) {
+              JumpReset(id);
+              return FMRES_IGNORED; 
+            }
+            else if(height_difference[id] > 0.02 && jump_type[id] == Type_Drop_BhopLongJump)
+              failed_jump[id] = true; 
+          }
+          
+          if(is_user_ducking(id))
+            origin[2] += 18.0;
+          
+          static Float:distance1;
+          if(jump_type[id] == Type_ladder)
+            distance1 = get_distance_f(jumpoff_origin[id], origin) + laddist[id];
+          else
+            distance1 = get_distance_f(jumpoff_origin[id], origin) + 32.0;
+          
+          if(is_user_ducking(id))
+            origin[2] -= 18.0;
+          
+          if(frame_velocity[id][1][0] < 0.0)
+            frame_velocity[id][1][0] *= -1.0;
+          if(frame_velocity[id][1][1] < 0.0)
+            frame_velocity[id][1][1] *= -1.0;
+          
+          static Float:land_origin[3];
+          
+          land_origin[2] = frame_velocity[id][0][2] * frame_velocity[id][0][2] + (2 * get_pcvar_float(sv_gravity) * (frame_origin[id][0][2] - origin[2]));
+          
+          rDistance[0] = (floatsqroot(land_origin[2]) * -1) - frame_velocity[id][1][2];
+          rDistance[1] = get_pcvar_float(sv_gravity)*-1;
+          
+          frame2time = floatdiv(rDistance[0], rDistance[1]);
+          if(frame_velocity[id][1][0] < 0)
+            frame_velocity[id][1][0] = frame_velocity[id][1][0] * -1;
+          rDistance[0] = frame2time * frame_velocity[id][1][0];
+            
+          if(frame_velocity[id][1][1] < 0)
+            frame_velocity[id][1][1] = frame_velocity[id][1][1] * -1;
+          rDistance[1] = frame2time * frame_velocity[id][1][1];
+      
+          if(frame_velocity[id][1][2] < 0)
+            frame_velocity[id][1][2] = frame_velocity[id][1][2] * -1;
+          rDistance[2] = frame2time * frame_velocity[id][1][2];
+          
+          if(frame_origin[id][1][0] < origin[0])
+            land_origin[0] = frame_origin[id][1][0] + rDistance[0];
+          else
+            land_origin[0] = frame_origin[id][1][0] - rDistance[0];
+          if(frame_origin[id][1][1] < origin[1])
+            land_origin[1] = frame_origin[id][1][1] + rDistance[1];
+          else
+            land_origin[1] = frame_origin[id][1][1] - rDistance[1];
+          
+          if(is_user_ducking(id)) {
+            origin[2] += 18.0;
+            duckstring[id] = true;
+          }
+      
+          land_origin[2] = origin[2];
+          
+          frame2time += (last_land_time[id] - jumpoff_time[id]);
+          
+          static Float:distance2;
+          if(jump_type[id] == Type_ladder)
+            distance2 = get_distance_f(jumpoff_origin[id], land_origin) + laddist[id];
+          else
+            distance2 = get_distance_f(jumpoff_origin[id], land_origin) + 32.0;
+          
+          if(failed == true) {
+            if(jump_type[id] == Type_ladder)
+              distance[id] = GetFailedDistance(laddist[id], failed_ducking[id], GRAVITY, jumpoff_origin[id], velocity, failed_origin[id], failed_velocity[id]);
+            else
+              distance[id] = GetFailedDistance(32.0, failed_ducking[id], GRAVITY, jumpoff_origin[id], velocity, failed_origin[id], failed_velocity[id]);
+          }
+          else
+            distance[id] = distance1 > distance2 ? distance2 : distance1;
+          
+          new Float:Landing,bool:land_bug;
+          
+          if(jump_type[id] != Type_ladder && distance[id] > 64.0) {
+            new Float:landing_orig[3];
+            
+            landing_orig = origin;
+            landing_orig[2] = landing_orig[2] - 36.1;
+            
+            Landing = LandingCalculate(id, landing_orig, jumpoff_origin[id]);
+            if(distance[id] < (jumpblock[id] + edgedist[id] + Landing)) {
+              landing_orig = land_origin;
+              landing_orig[2] = landing_orig[2] - 36.1;
+              Landing = LandingCalculate(id, landing_orig, jumpoff_origin[id]);
+              Landing = Landing - 0.06250;
+              land_bug = true;
+            }
+            else
+              land_bug = false;
+          }
+          
+          if(!uq_noslow && entity_get_float(id, EV_FL_fuser2) == 0.0 && jump_type[id] != Type_ladder)
+            failed_jump[id] = true;
+          if(fps_hight[id] && jump_type[id] != Type_ladder)
+            failed_jump[id] = true;
+          if(duckbhop_bug_pre[id])
+            failed_jump[id] = true;
+          
+          new tmp_dist,tmp_min_dist,tmp_maxdist,tmp_mindist_other;
+          if(Pmaxspeed != 250.0 && jump_type[id] != Type_ladder) {
+            tmp_dist = floatround((250.0 - Pmaxspeed) * 0.73, floatround_floor);
+            tmp_min_dist = min_distance - tmp_dist;
+          }
+          else
+            tmp_min_dist = min_distance;
+          
+          tmp_maxdist = max_distance;
+          tmp_mindist_other = min_distance_other;
+          
+          if(jump_type[id] != Type_Bhop_In_Duck
+              && jump_type[id] != Type_Up_Bhop_In_Duck
+              && jump_type[id] != Type_Up_Stand_Bhop
+              && jump_type[id] != Type_Up_Bhop
+              && jump_type[id] != Type_ladder
+              && jump_type[id] != Type_Multi_Bhop
+              && jump_type[id] != Type_DuckBhop
+              && jump_type[id] != Type_Real_ladder_Bhop) {
+            if(distance[id] < tmp_min_dist || tmp_maxdist < distance[id]) {
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+          }
+          else if(jump_type[id] == Type_ladder && (distance[id] > tmp_maxdist || distance[id] < tmp_mindist_other)) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if((jump_type[id] == Type_Multi_Bhop || jump_type[id] == Type_Real_ladder_Bhop) && (distance[id] > tmp_maxdist || distance[id] < tmp_mindist_other)) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if((jump_type[id] == Type_Bhop_In_Duck
+              || jump_type[id] == Type_Up_Bhop_In_Duck
+              || jump_type[id] == Type_Up_Stand_Bhop
+              || jump_type[id] == Type_Up_Bhop
+              || jump_type[id] == Type_Real_ladder_Bhop)
+              && (distance[id] > tmp_maxdist
+              || distance[id] < tmp_mindist_other)) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id] == Type_DuckBhop && (distance[id] > tmp_maxdist || distance[id] < tmp_min_dist - 150)) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          
+          if(jump_type[id] == Type_LongJump)
+            oldjump_type[id] = 1;
+          else
+            oldjump_type[id] = 0;
+          
+          if(jump_type[id] == Type_LongJump && detecthj[id] == 1)  {
+            jump_type[id] = Type_HighJump;
+            formatex(Jtype[id], 32, "HighJump");
+            formatex(Jtype1[id], 32, "hj");
+          }
+          if(touch_somthing[id])
+            failed_jump[id] = true;
+          
+          new wpn,weapon_name[21],clip,ammo;
+          
+          wpn = get_user_weapon(id, clip, ammo);
+          if(wpn) {
+            get_weaponname(wpn, weapon_name, 20);
+            replace(weapon_name, 20, "weapon_", "");
+          }
+          else
+            formatex(weapon_name, 20, "Unknown");
+  
+          new t_type;
+          t_type = 0;
+          
+          switch(jump_type[id]) {
+            case 0: t_type = 1;
+            case 1: t_type = 1;
+            case 2: t_type = 2;
+            case 9: t_type = 2;
+            case 11:t_type = 2;
+            case 6: t_type = 2;
+            case 7: t_type = 2;
+            case 15: t_type = 2;
+            case 17: t_type = 2;
+            case 18: t_type = 2;
+            case 19: t_type = 2;
+            case 3: t_type = 3;
+            case 5: t_type = 3;
+            case 21: t_type = 3;
+            case 22: t_type = 3;
+            case 13: t_type = 4;
+            case 23: t_type = 5;
+            case 24:t_type = 5;
+            case 12: t_type = 6;
+          }
+          
+          if(uq_bug == 1 && check_for_bug_distance(distance[id], t_type, Pmaxspeed)) {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          if(uq_bug == 1) {
+            new Float:b_check = 2.1;
+            
+            if(jump_type[id] == Type_ladder)
+              b_check=b_check - 0.1;
+            
+            if((maxspeed[id] + prestrafe[id]) / distance[id] < b_check) {
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+          }
+          new dom_dist,god_dist,leet_dist,holy_dist,pro_dist,good_dist;
+          new d_array[6];
+          
+          d_array = get_colorchat_by_distance(jump_type[id], Pmaxspeed, tmp_dist, dropaem[id], multiscj[id], aircj);
+          dom_dist = d_array[5];
+          god_dist = d_array[4];
+          leet_dist = d_array[3];
+          holy_dist = d_array[2];
+          pro_dist = d_array[1];
+          good_dist = d_array[0];
+          
+          sync_[id] = 0;
+          strMess[0] = '^0';
+          strMessBuf[0] = '^0';
+          strLen = 0;
+          badSyncTemp = 0;
+          goodSyncTemp = 0;
+          new Float:tmpstatspeed[NSTRAFES],Float:tmpstatpoteri[NSTRAFES];
+                
+          Fulltime = last_land_time[id] - jumpoff_time[id];
+          if(strafe_num[id] < NSTRAFES) {
+            strafe_stat_time[id][0] = jumpoff_time[id];
+            strafe_stat_time[id][strafe_num[id]] = last_land_time[id];
+            for(jj = 1;jj <= strafe_num[id]; jj++) {
+              time_ = ((strafe_stat_time[id][jj] - strafe_stat_time[id][jj-1])*100) / (Fulltime);
+              if((strafe_stat_sync[id][jj][0] + strafe_stat_sync[id][jj][1]) > 0)
+                sync_[id] = (strafe_stat_sync[id][jj][0] * 100) / (strafe_stat_sync[id][jj][0] + strafe_stat_sync[id][jj][1]);
+              else
+                sync_[id] = 0;
+              strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^t%2d^t%4.3f^t%4.3f^t%3.1f%%^t%3d%%^n", jj, strafe_stat_speed[id][jj][0], strafe_stat_speed[id][jj][1], time_, sync_[id]);
+              goodSyncTemp += strafe_stat_sync[id][jj][0];
+              badSyncTemp += strafe_stat_sync[id][jj][1];
+              tmpstatspeed[jj] = strafe_stat_speed[id][jj][0];
+              tmpstatpoteri[jj] = strafe_stat_speed[id][jj][1];
+              
+              if(tmpstatpoteri[jj] > 200) {
+                if(duckstring[id] == false)
+                duckstring[id] = true;
+              }
+              if(tmpstatpoteri[jj] > 200 && Checkframes[id]) {
+                Checkframes[id] = false;
+                failed_jump[id] = true;
+              }
+            }
+
+            if(strafe_num[id] != 0) {
+              if(jump_type[id] == Type_ladder && strafe_stat_speed[id][0][0] != 0)
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^t^tTurn speed: %4.3f",strafe_stat_speed[id][0][0]);
+              if(duckstring[id] == false)
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^t^tNo duck");
+              if(jump_type[id]==Type_StandupBhopLongJump || jump_type[id]==Type_Up_Stand_Bhop)
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^tStand-Up");
+              if(wpn!=29 && wpn!=17 && wpn!=16)
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tWeapon: %s",weapon_name);
+              if(Show_edge[id] && failed_jump[id]==false && jump_type[id]!=Type_ladder && jumpblock[id]user_block[id][1] && edgedist[id]<100.0 && edgedist[id]!=0.0 && (jumpblock[id]+edgedist[id])(distance[id]+10.0) || Landing<=0.0)
+                  strLen =strLen+format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tBlock -- %d^n^tJumpoff -- %f",jumpblock[id],edgedist[id]);
+                else if(land_bug)
+                  strLen =strLen+format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tBlock -- %d^n^tJumpoff -- %f^n^tLanding -- %f(bg)",jumpblock[id],edgedist[id],Landing);
+                else
+                  strLen =strLen+format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tBlock -- %d^n^tJumpoff -- %f^n^tLanding -- %f",jumpblock[id],edgedist[id],Landing);
+              }
+              else if(Show_edge[id] && failed_jump[id] && jump_type[id]!=Type_ladder && jumpblock[id]user_block[id][1] && edgedist[id]<100.0 && edgedist[id]!=0.0)
+                strLen =strLen+format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tBlock -- %d^n^tJumpoff -- %f",jumpblock[id],edgedist[id]);
+              else if(Show_edge_Fail[id] && failed_jump[id] && jump_type[id]!=Type_ladder && edgedist[id]<100.0 && edgedist[id]!=0.0)
+                strLen =strLen+format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tJumpoff -- %f",edgedist[id]);  
+              if(jump_type[id]==Type_Up_Bhop || jump_type[id]==Type_Up_Stand_Bhop || jump_type[id]==Type_Up_Bhop_In_Duck)
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tUp Height: %0.3f",upheight[id]);
+              if(fps_hight[id] && jump_type[id]!=Type_ladder)
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tYour Fps more 110 or Lags");
+              if(ladderbug[id]) {
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tProbably Ladder bug");
+                failed_jump[id]=true;
+              }
+              if(find_ladder[id] && jump_type[id]==Type_DuckBhop) {
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tDuckBhop doesn't work near Ladder");
+                failed_jump[id]=true;
+              }
+              if(touch_somthing[id])
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tProbably Touched something");
+              if(angles_arry[id]>60 && uq_script_detection && distance[id]>holy_dist) {
+                strLen += format(strMess[strLen],(40*NSTRAFES)-strLen-1, "^n^n^tProbably you use Script");
+                failed_jump[id]=true;
+              }
+            }
+          }
+
+          if(goodSyncTemp > 0)
+            sync_[id] = (goodSyncTemp * 100 / (goodSyncTemp + badSyncTemp));
+          else
+            sync_[id] = 0;
+          
+          switch(jump_type[id]) {
+            case 0: add(type, 32, "LJ", 25); //Lj
+            case 1: add(type, 32, "HJ", 25); //hj
+            case 2: {
+              if(CjafterJump[id]==1)
+                add(type, 32, "CJ After Jump", 25);
+              else
+                add(type, 32, "CJ", 25); //cj
+            }
+            case 3: add(type, 32, "BJ", 25); //bj
+            case 4: add(type, 32, "Slide", 25); //slidelj
+            case 5: add(type, 32, "SBJ", 25); //sbj
+            case 6: {
+              if(ddbeforwj[id] == false)
+                add(type, 32, "WJ", 25); //wj
+              else
+                add(type, 32, "DD+WJ", 25);
+            }
+            case 7: add(type, 32, "Drop BJ", 25);
+            case 9: {
+              if(CjafterJump[id]==2)
+                add(type, 32, "DCJ After Jump", 25);
+              else
+                add(type, 32, "DCJ", 25); //dcj
+            }
+            case 11: {
+              if(CjafterJump[id]==3)
+                add(type, 32, "MCJ After Jump", 25);
+              else
+                add(type, 32, "Multi CJ", 25);//mcj
+            }
+            case 12: add(type, 32, "Duck Bhop", 25);//nothing
+            case 13: add(type, 32, "Ladder", 25);//ld
+            case 15: add(type, 32, "Ladder Bhop", 25);
+            case 16: add(type, 32, "Drop SBJ", 25);
+            case 17: add(type, 32, "Real Ladder Bhop", 25);
+            case 18: {  
+              if(multidropcj[id]==0)
+                add(type, 32, "Drop CJ", 25);
+              else if(multidropcj[id]==1) {
+                add(type, 32, "Double Drop CJ", 25);
+                formatex(Jtype[id],32,"Double Drop CJ");
+              }
+              else if(multidropcj[id]==2) {
+                add(type, 32, "Multi Drop CJ", 25);
+                formatex(Jtype[id],32,"Multi Drop CJ");
+              }
+            }
+            case 19: {
+              if(dropaem[id]) {
+                if(multiscj[id]==0) {
+                  add( type, 32, "Drop SCJ", 25);
+                  formatex(Jtype[id],32,"Drop StandUp CountJump");
+                  formatex(Jtype1[id],32,"dropscj");
+                }
+                else if(multiscj[id]==1) {
+                  add( type, 32, "Drop Double SCJ", 25);
+                  formatex(Jtype[id],32,"Drop Double StandUp CountJump");
+                  formatex(Jtype1[id],32,"dropdscj");
+                }
+                else if(multiscj[id]==2) {
+                  add( type, 32, "Drop Multi SCJ", 25);
+                  formatex(Jtype[id],32,"Drop Multi StandUp CountJump");
+                  formatex(Jtype1[id],32,"dropmscj");
+                  
+                }
+              }
+              else if(ddafterJump[id]) {
+                if(multiscj[id]==0) {
+                  add( type, 32, "SCJ After Jump", 25 );
+                  formatex(Jtype[id],32,"StandUp CountJump After Jump");
+                  formatex(Jtype1[id],32,"scjaj");
+                }
+                else if(multiscj[id]==1) {
+                  add( type, 32, "Double SCJ After Jump", 25 );
+                  formatex(Jtype[id],32,"Double StandUp CountJump After Jump");
+                  formatex(Jtype1[id],32,"dscjaj");
+                }
+                else if(multiscj[id]==2) {
+                  add( type, 32, "Multi SCJ After Jump", 25 );
+                  formatex(Jtype[id],32,"Multi StandUp CountJump After Jump");
+                  formatex(Jtype1[id],32,"mscjaj");
+                }
+              }
+              else {
+                if(multiscj[id]==0)
+                  add( type, 32, "SCJ", 25 );
+                else if(multiscj[id]==1) {
+                  add( type, 32, "Double SCJ", 25 );
+                  formatex(Jtype[id],32,"Double StandUp CountJump");
+                  formatex(Jtype1[id],32,"dscj");
+                }
+                else if(multiscj[id]==2) {
+                  add( type, 32, "Multi SCJ", 25 );
+                  formatex(Jtype[id],32,"Multi StandUp CountJump");
+                  formatex(Jtype1[id],32,"mscj");
+                }
+              }
+            }
+            case 20:add( type, 32, "Multi Bhop", 25 );
+            case 21:add( type, 32, "Up Bhop", 25 );
+            case 22:add( type, 32, "Up StandUp Bhop", 25 );
+            case 23:add( type, 32, "Up Bhop In Duck", 25);
+            case 24:add( type, 32, "Bhop In Duck", 25);
+          }
+          
+          new Float:gain[33];
+          gain[id] = floatsub( maxspeed[id], prestrafe[id] );
+      
+          if(jump_type[id]==Type_StandUp_CountJump && dropaem[id]==false && multiscj[id]==0 && uq_drsbj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id]==false && multiscj[id]==1 && uq_dscj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id]==false && multiscj[id]==2 && uq_mscj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id] && multiscj[id]==0 && uq_dropscj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id] && multiscj[id]==1 && uq_dropdscj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id] && multiscj[id]==2 && uq_dropmscj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Double_CountJump&& uq_dcj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Multi_CountJump && uq_mcj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_CountJump && uq_cj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if((jump_type[id]==Type_LongJump || jump_type[id]==Type_HighJump) && uq_lj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_ladder && uq_ladder==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Bhop_In_Duck && (uq_bhopinduck==0 )) 
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_DuckBhop && (uq_duckbhop==0 )) 
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Up_Bhop && (uq_upbj==0) ) 
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Up_Bhop_In_Duck && (uq_upbhopinduck==0 )) 
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_BhopLongJump && uq_bj==0) 
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_ladderBhop && uq_ldbj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Real_ladder_Bhop && uq_realldbhop==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_WeirdLongJump && uq_wj==0) 
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Drop_CountJump && multidropcj[id]==0 && uq_drcj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Drop_CountJump && multidropcj[id]==1 && uq_dropdcj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Drop_CountJump && multidropcj[id]==2 && uq_dropmcj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Drop_BhopLongJump && uq_drbj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_StandupBhopLongJump && uq_sbj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Up_Stand_Bhop && uq_upsbj==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          else if(jump_type[id]==Type_Multi_Bhop && uq_multibhop==0)
+          {
+            JumpReset(id);
+            return FMRES_IGNORED;
+          }
+          
+          for(new i=1;i40 && jump_type[id]!=Type_ladder && jump_type[id]!=Type_Real_ladder_Bhop && jump_type[id]!=Type_Slide)
+            {
+              JumpReset(id);
+              return FMRES_IGNORED;
+            }
+          }
+          
+          if(jump_type[id]==Type_Multi_Bhop && multibhoppre[id]==false)
+          {
+            g_reset[id]=true;
+            return FMRES_IGNORED;
+          }
+          if(!failed_jump[id])
+          {
+            new tmp_type_num;
+                        
+            if(jump_type[id]==Type_Double_CountJump  && uq_dcj==1) 
+            {
+              formatex(sql_JumpType[id],25,"doublecj_top");
+              tmp_type_num=10;
+            }
+            else if(jump_type[id]==Type_Multi_CountJump  && uq_mcj==1) 
+            {
+                formatex(sql_JumpType[id],25,"multicj_top");
+                tmp_type_num=21;
+            }
+            else if(jump_type[id]==Type_CountJump  && uq_cj==1) 
+            {
+                formatex(sql_JumpType[id],25,"cj_top");
+                tmp_type_num=2;
+            }
+            else if((jump_type[id]==Type_LongJump || jump_type[id]==Type_HighJump)  && uq_lj==1) 
+            {
+              formatex(sql_JumpType[id],25,"lj_top");
+              tmp_type_num=0;
+            }
+            else if(jump_type[id]==Type_ladder  && uq_ladder==1) 
+            {
+              formatex(sql_JumpType[id],25,"ladder_top");
+              tmp_type_num=6;
+            }
+            else if(jump_type[id]==Type_BhopLongJump  && uq_bj==1) 
+            {
+              formatex(sql_JumpType[id],25,"bj_top");
+              tmp_type_num=4;
+            }
+            else if(jump_type[id]==Type_ladderBhop  && uq_ldbj==1) 
+            {
+              formatex(sql_JumpType[id],25,"ladderbhop_top");
+              tmp_type_num=7;
+            }
+            else if(jump_type[id]==Type_WeirdLongJump  && uq_wj==1) 
+            {
+              formatex(sql_JumpType[id],25,"wj_top");
+              tmp_type_num=3;
+            }
+            else if(jump_type[id]==Type_Drop_BhopLongJump  && uq_drbj==1) 
+            {
+              formatex(sql_JumpType[id],25,"dropbj_top");
+              tmp_type_num=9;
+            }
+            else if(jump_type[id]==Type_StandupBhopLongJump  && uq_sbj==1) 
+            {
+              formatex(sql_JumpType[id],25,"sbj_top");
+              tmp_type_num=5;
+            }
+            else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id]==false && multiscj[id]==0  && uq_drsbj==1)
+            {
+              formatex(sql_JumpType[id],25,"scj_top");
+              tmp_type_num=1;
+            }
+            else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id]==false && multiscj[id]==1   && uq_dscj==1) 
+            {
+              formatex(sql_JumpType[id],25,"doublescj_top");
+              tmp_type_num=11;
+            }
+            else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id]==false && multiscj[id]==2   && uq_mscj==1) 
+            {
+              formatex(sql_JumpType[id],25,"multiscj_top");
+              tmp_type_num=22;
+            }
+            else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id] && multiscj[id]==0   && uq_dropscj==1) 
+            {
+              formatex(sql_JumpType[id],25,"dropscj_top");
+              tmp_type_num=12;
+            }
+            else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id] && multiscj[id]==1   && uq_dropdscj==1) 
+            {
+              formatex(sql_JumpType[id],25,"dropdoublescj_top");
+              tmp_type_num=13;
+            }
+            else if(jump_type[id]==Type_StandUp_CountJump && dropaem[id] && multiscj[id]==2   && uq_dropmscj==1) 
+            {
+              formatex(sql_JumpType[id],25,"dropmultiscj_top");
+              tmp_type_num=23;
+            }
+            else if(jump_type[id]==Type_DuckBhop   && uq_duckbhop==1) 
+            {
+              formatex(sql_JumpType[id],25,"duckbhop_top");
+              tmp_type_num=14;
+            }
+            else if(jump_type[id]==Type_Bhop_In_Duck   && uq_bhopinduck==1) 
+            {
+              formatex(sql_JumpType[id],25,"bhopinduck_top");
+              tmp_type_num=15;
+            }
+            else if(jump_type[id]==Type_Real_ladder_Bhop   && uq_realldbhop==1) 
+            {
+              formatex(sql_JumpType[id],25,"realladderbhop_top");
+              tmp_type_num=16;
+            }
+            else if(jump_type[id]==Type_Up_Bhop   && uq_upbj==1) 
+            {
+              formatex(sql_JumpType[id],25,"upbj_top");
+              tmp_type_num=17;
+            }
+            else if(jump_type[id]==Type_Up_Bhop_In_Duck   && uq_upbhopinduck==1) 
+            {
+              formatex(sql_JumpType[id],25,"upbhopinduck_top");
+              tmp_type_num=19;
+            }
+            else if(jump_type[id]==Type_Up_Stand_Bhop   && uq_upsbj==1) 
+            {
+              formatex(sql_JumpType[id],25,"upsbj_top");
+              tmp_type_num=18;
+            }
+            else if(jump_type[id]==Type_Multi_Bhop   && uq_multibhop==1) 
+            {
+              formatex(sql_JumpType[id],25,"multibhop_top");
+              tmp_type_num=24;
+            }
+            else if(jump_type[id]==Type_Drop_CountJump && multidropcj[id]==2   && uq_dropmcj==1) 
+            {
+              formatex(sql_JumpType[id],25,"multidropcj_top");
+              tmp_type_num=25;
+            }
+            else if(jump_type[id]==Type_Drop_CountJump && multidropcj[id]==1   && uq_dropdcj==1) 
+            {
+              formatex(sql_JumpType[id],25,"doubledropcj_top");
+              tmp_type_num=20;
+            }
+            else if(jump_type[id]==Type_Drop_CountJump && multidropcj[id]==0  && uq_drcj==1) 
+            {
+              formatex(sql_JumpType[id],25,"dropcj_top");
+              tmp_type_num=8;
+            }
+            
+          
+            if(jump_type[id]!=Type_None && jump_type[id]!=Type_Null && jump_type[id]!=Type_Nothing && jump_type[id]!=Type_Nothing2) 
+            {
+              if(jumpblock[id]>100 && edgedist[id]!=0.0 && (jumpblock[id]+edgedist[id])=good_dist)
+                  PlayerSaveData_to_SQL_block(id, cData);
+              }
+              
+              new cData[9];
+              cData[0] = floatround(distance[id]*1000000);
+              cData[1] = floatround(maxspeed[id]*1000000);
+              cData[2] = floatround(prestrafe[id]*1000000);
+              cData[3] = strafe_num[id];
+              cData[4] = sync_[id];
+              
+              
+              if(jump_type[id]==Type_Multi_Bhop)
+              {
+                cData[5]=bhop_num[id];
+              }
+              else cData[5] = ducks[id];
+              
+              cData[6] = tmp_type_num;
+              cData[7] = Pmaxspeed;
+              cData[8] = wpn;
+              // Добавляются только lj за 240
+              if (distance[id] >=good_dist)
+                PlayerSaveData_to_SQL(id, cData);
+            }
+          }
+          
+      
+          if(kz_stats_pre[id]==true)//ducks stat for mcj
+          {
+            strM[0] = '^0'; 
+            strMBuf[0] = '^0'; 
+            strL = 0;
+            for(jj = 2;jj <= ducks[id]; jj++)
+            {
+              strL += format(strM[strL],(40*NSTRAFES)-strL-1, "^t%2d^tduck: (%0.3f)^n", jj-1,statsduckspeed[id][jj]);
+            }
+            copy(strMBuf,strL,strM);//dlya stat ducks
+          }
+          if(uq_istrafe)
+          {
+            new st1[NSTRAFES],st2[NSTRAFES];
+            for(new i = 1;i <= strafe_num[id]; i++)
+            {
+              st1[i]=strafe_stat_sync[id][i][0];
+              st2[i]=strafe_stat_sync[id][i][1];
+            }
+            
+            for( new i = 1; i < max_players; i++ )
+            {
+              if( (i == id || is_spec_user[i]))
+              {
+                if(ingame_strafe[i])
+                {
+                  new Float:or[3];
+                  pev(id,pev_origin,or);
+                  
+                  remove_beam_ent(i);
+                  
+                  epta(i,or,direct_for_strafe[id],line_lost[id],FullJumpFrames[id],is_user_ducking(id),strafe_num[id],st1,st2,strafe_lost_frame[id]);
+                }
+              }
+            }
+          }
+          for( new i = 1; i < max_players; i++ )
+          {
+            if( (i == id || is_spec_user[i]) && g_lj_stats[i]==true)
+            {  
+              copy(strMessBuf,strLen,strMess);
+              //stats
+              if(jump_type[id]==Type_Multi_Bhop &&!failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats  );  
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: %f^nStrafes: %d^nSync: %d%%^nBhop Jump's: %d", type, distance[id], maxspeed[id], gain[id], prestrafe[id],strafe_num[id], sync_[id],bhop_num[id]);
+              }
+              else if((jump_type[id]==Type_Double_CountJump || (multiscj[id]==1 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==1 && jump_type[id] == Type_Drop_CountJump)) &&!failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );  
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: (%.01f) (%.01f) %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prest1[id],prest[id], prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_ladderBhop || jump_type[id]==Type_ladder || jump_type[id]==Type_Drop_BhopLongJump || jump_type[id]==Type_WeirdLongJump || jump_type[id]==Type_LongJump || jump_type[id]==Type_HighJump) &&!failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats  );  
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_CountJump || (multiscj[id]==0 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==0 && jump_type[id] == Type_Drop_CountJump)) && !failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats);
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: (%.03f) %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prest1[id],prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_Bhop_In_Duck || jump_type[id]==Type_Up_Bhop_In_Duck || jump_type[id]==Type_Up_Stand_Bhop || jump_type[id]==Type_Up_Bhop || jump_type[id]==Type_Real_ladder_Bhop || jump_type[id]==Type_DuckBhop || jump_type[id] == Type_BhopLongJump || jump_type[id] == Type_StandupBhopLongJump ) && !failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats);
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id],prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id] == Type_Drop_CountJump)) && !failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: (%.03f) %f^nDucks: %d%^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prest1[id],prestrafe[id],ducks[id], strafe_num[id], sync_[id]);
+              }
+              
+              if(jump_type[id] != Type_Slide && streifstat[id]==true && jump_type[id]!=Type_None && !failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, strafe_x, strafe_y, 0, 6.0, 2.5, 0.1, 0.3, h_streif);
+                show_hudmessage(i,"%s",strMessBuf); //stata streifof
+              }
+              
+              if(kz_stats_pre[id]==true && (jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id] == Type_Drop_CountJump)) && !failed_jump[id])
+              {
+                set_hudmessage(stats_r, stats_g, stats_b, duck_x,duck_y, 0, 6.0, 2.5, 0.1, 0.3, h_duck);  
+                show_hudmessage(i, "%s",strMBuf);//stata duckov
+              }
+              
+              //failstats
+              if(jump_type[id]==Type_Multi_Bhop  && (failed_jump[id]))
+              {
+                set_hudmessage( f_stats_r, f_stats_g, f_stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: %f^nStrafes: %d^nSync: %d%%^nBhop Jump's: %d", type, distance[id], maxspeed[id], gain[id], prestrafe[id],strafe_num[id], sync_[id],bhop_num[id]);
+              }
+              else if((jump_type[id]==Type_ladderBhop || jump_type[id]==Type_ladder || jump_type[id]==Type_Drop_BhopLongJump || jump_type[id]==Type_WeirdLongJump || jump_type[id]==Type_LongJump || jump_type[id]==Type_HighJump)  && (failed_jump[id]))
+              {
+                set_hudmessage( f_stats_r, f_stats_g, f_stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_CountJump || (multiscj[id]==0 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==0 && jump_type[id] == Type_Drop_CountJump)) && (failed_jump[id]))
+              {
+                set_hudmessage(f_stats_r, f_stats_g, f_stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: (%.03f) %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prest1[id],prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_Bhop_In_Duck || jump_type[id]==Type_Up_Bhop_In_Duck || jump_type[id]==Type_Up_Stand_Bhop || jump_type[id]==Type_Up_Bhop || jump_type[id]==Type_Real_ladder_Bhop || jump_type[id]==Type_DuckBhop || jump_type[id] == Type_BhopLongJump || jump_type[id] == Type_StandupBhopLongJump ) && (failed_jump[id]))
+              {
+                set_hudmessage(f_stats_r, f_stats_g, f_stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: %f^nStrafes: %d^nSynca: %d%%^n", type, distance[id], maxspeed[id], gain[id], prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_Double_CountJump || (multiscj[id]==1 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==1 && jump_type[id] == Type_Drop_CountJump)) && (failed_jump[id]))
+              {
+                set_hudmessage( f_stats_r, f_stats_g, f_stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: (%.01f) (%.01f) %f^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prest1[id],prest[id], prestrafe[id],strafe_num[id], sync_[id]);
+              }
+              else if((jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id] == Type_Drop_CountJump)) && (failed_jump[id]))
+              {
+                set_hudmessage(f_stats_r, f_stats_g, f_stats_b, stats_x, stats_y, 0, 6.0, 2.5, 0.1, 0.3, h_stats );
+                show_hudmessage( i, "%s Distance: %f^nMaxspeed: %f (%.03f)^nPrestrafe: (%.03f) %f^nDucks: %d%^nStrafes: %d^nSync: %d%%^n", type, distance[id], maxspeed[id], gain[id], prest1[id],prestrafe[id],ducks[id],strafe_num[id], sync_[id]);
+              }
+                          
+              if(jump_type[id] != Type_Slide && streifstat[id]==true && jump_type[id]!=Type_None && (failed_jump[id]))
+              {
+                set_hudmessage(f_stats_r, f_stats_g, f_stats_b, strafe_x, strafe_y, 0, 6.0, 2.5, 0.1, 0.3, h_streif );
+                show_hudmessage(i,"%s",strMessBuf);  //stata streifof fail
+              }
+              
+              if(kz_stats_pre[id]==true && (jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id] == Type_Drop_CountJump)) && (failed_jump[id]))
+              {
+                set_hudmessage(f_stats_r, f_stats_g, f_stats_b, duck_x,duck_y, 0, 6.0, 2.5, 0.1, 0.3, h_duck);  
+                show_hudmessage(i, "%s",strMBuf); //stata duckov fail
+              }          
+            }
+          }
+          
+          //console prints
+          for( new i = 1; i < max_players; i++ )
+          {
+            if( (i == id || is_spec_user[i]) && g_lj_stats[i]==true)
+            {
+              copy(strMessBuf,strLen,strMess);
+              if((jump_type[id]==Type_ladderBhop || jump_type[id]==Type_ladder || jump_type[id]==Type_Drop_BhopLongJump || jump_type[id]==Type_WeirdLongJump || jump_type[id]==Type_LongJump || jump_type[id]==Type_HighJump) )
+              {
+                client_print( i, print_console, " ");
+                client_print( i, print_console, "%s Distance: %f Maxspeed: %f (%.03f) Prestrafe: %f Strafes: %d Sync: %d%%", type, distance[id], maxspeed[id], gain[id], prestrafe[id], strafe_num[id],sync_[id] );
+              }
+              else if(jump_type[id]==Type_Multi_Bhop )
+              {
+                client_print( i, print_console, " ");
+                client_print( i, print_console, "%s Distance: %f Maxspeed: %f (%.03f) Prestrafe: %f Strafes: %d Sync: %d Bhop Jump's: %d", type, distance[id], maxspeed[id], gain[id], prestrafe[id], strafe_num[id],sync_[id] ,bhop_num[id]);
+              
+              }
+              else if(jump_type[id]==Type_CountJump || (multiscj[id]==0 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==0 && jump_type[id] == Type_Drop_CountJump))
+              {
+                client_print( i, print_console, " ");
+                client_print( i, print_console, "%s Distance: %f Maxspeed: %f (%.03f) Prestrafe: (%.03f) %f Strafes: %d Sync: %d%%", type, distance[id], maxspeed[id], gain[id], prest1[id], prestrafe[id], strafe_num[id],sync_[id] );
+              }
+              else if(jump_type[id]==Type_Bhop_In_Duck || jump_type[id]==Type_Up_Bhop_In_Duck || jump_type[id]==Type_Up_Stand_Bhop || jump_type[id]==Type_Up_Bhop || jump_type[id]==Type_Real_ladder_Bhop || jump_type[id]==Type_DuckBhop || jump_type[id] == Type_BhopLongJump || jump_type[id] == Type_StandupBhopLongJump)
+              {
+                client_print( i, print_console, " ");
+                client_print( i, print_console, "%s Distance: %f Maxspeed: %f (%.03f) Prestrafe: %f Strafes: %d Sync: %d%%", type, distance[id], maxspeed[id], gain[id], prestrafe[id], strafe_num[id],sync_[id] );
+              }
+              else if(jump_type[id]==Type_Double_CountJump || (multiscj[id]==1 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==1 && jump_type[id] == Type_Drop_CountJump))
+              {
+                client_print( i, print_console, " ");
+                client_print( i, print_console, "%s Distance: %f Maxspeed: %f (%.03f) Prestrafe: (%.01f) (%.01f) %f Strafes: %d Sync: %d%%", type, distance[id], maxspeed[id], gain[id], prest1[id],prest[id], prestrafe[id], strafe_num[id],sync_[id] );
+              }
+              else if(jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id] == Type_Drop_CountJump))
+              {
+                client_print( i, print_console, " ");
+                client_print( i, print_console, "%s Distance: %f Maxspeed: %f (%.03f) Prestrafe: (%.03f) %f Ducks: %d% Strafes: %d Sync: %d%%", type, distance[id], maxspeed[id], gain[id], prest1[id],prestrafe[id],ducks[id],strafe_num[id], sync_[id]);
+              }
+              
+              if(jump_type[id]!=Type_None)
+              {
+                static strMessHalf[40];
+                for(jj=1; (jj <= strafe_num[id]) && (jj < NSTRAFES);jj++)
+                {
+                    strtok(strMessBuf,strMessHalf,40,strMessBuf,40*NSTRAFES,'^n');
+                    replace(strMessHalf,40,"^n","");
+                    client_print(i, print_console, "%s", strMessHalf);
+                }
+              }
+              
+              if(jump_type[id]==Type_ladder && strafe_stat_speed[id][0][0]!=0)
+              {
+                client_print(i, print_console, "Turn speed: %.03f", strafe_stat_speed[id][0][0]);
+              }
+              else if(jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id] == Type_Drop_CountJump))
+              {
+                client_print( i, print_console, "..................................................");
+                client_print( i, print_console, "Prestrafe before ducking: %.03f",prest1[id]);
+                for(new ss=2;ss<=ducks[id];ss++)
+                client_print( i, print_console, "Prestrafe after #%d duck: %.03f",ss-1,statsduckspeed[id][ss]);
+                client_print( i, print_console, "Prestrafe before jumping: %.03f",prestrafe[id]);
+                client_print( i, print_console, "..................................................");
+              }
+              else if(jump_type[id]==Type_Double_CountJump || (multiscj[id]==1 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==1 && jump_type[id] == Type_Drop_CountJump))
+              {
+                client_print( i, print_console, "..................................................");
+                client_print( i, print_console, "Prestrafe before ducking: %.03f",prest1[id]);
+                client_print( i, print_console, "Prestrafe after 1st duck: %.03f",prest[id]);
+                client_print( i, print_console, "Prestrafe before jumping: %.03f",prestrafe[id]);
+                client_print( i, print_console, "..................................................");
+              }
+              else if(jump_type[id]==Type_Up_Bhop || jump_type[id]==Type_Up_Stand_Bhop || jump_type[id]==Type_Up_Bhop_In_Duck)
+              {
+                client_print( i, print_console,"Up Height: %0.3f",upheight[id]);
+              }
+              if(wpn!=29 && wpn!=17 && wpn!=16)
+              {
+                client_print( i, print_console,"Weapon: %s",weapon_name);
+              }
+              if(fps_hight[id] && jump_type[id]!=Type_ladder)
+              {
+                client_print( i, print_console,"Your Fps more 110 or Lags");
+                fps_hight[id]=false;
+              }
+              if(ladderbug[id])
+              {
+                client_print( i, print_console,"Probably Ladder bug");
+                ladderbug[id]=false;
+              }
+              if(find_ladder[id] && jump_type[id]==Type_DuckBhop)
+              {
+                client_print( i, print_console,"DuckBhop doesn't work near Ladder");
+                find_ladder[id]=false;
+              }
+              if(touch_somthing[id])
+              {
+                client_print( i, print_console,"Probably Touched something");
+              }
+              if(Show_edge[id] && failed_jump[id]==false && jump_type[id]!=Type_ladder && jumpblock[id]user_block[id][1] && edgedist[id]<100.0 && edgedist[id]!=0.0 && (jumpblock[id]+edgedist[id])(distance[id]+10.0) || Landing<=0.0)
+                {
+                  client_print( i, print_console,"Block -- %d! Jumpoff -- %f!",jumpblock[id],edgedist[id]);
+                }
+                else if(land_bug )
+                {
+                  client_print( i, print_console,"Block -- %d! Jumpoff -- %f! Landing -- %f(bg)!",jumpblock[id],edgedist[id],Landing);
+                }
+                else client_print( i, print_console,"Block -- %d! Jumpoff -- %f! Landing -- %f!",jumpblock[id],edgedist[id],Landing);
+              }
+              else if(Show_edge[id] && failed_jump[id] && jump_type[id]!=Type_ladder && jumpblock[id]user_block[id][1] && edgedist[id]<100.0 && edgedist[id]!=0.0 && (jumpblock[id]+edgedist[id])60 && uq_script_detection && distance[id]>holy_dist)
+              {
+                client_print( i, print_console,"Probably you use Script");
+                
+              }
+            }
+          }
+          
+          if(wpn==29 || wpn==17 || wpn==16 || wpn==4 || wpn==9 || wpn==25)
+          {
+            formatex(weapon_name,20,"");
+          }
+          else
+          {
+            new tmp_str[21];
+            
+            formatex(tmp_str,20,"[");
+            add(weapon_name, 20, "]");
+            add(tmp_str, 20, weapon_name);
+            formatex(weapon_name,20,tmp_str);
+          }
+          
+          new block_colorchat_dist=god_dist;
+          new uq_block_chat_min = 1;
+          switch(uq_block_chat_min)
+          {
+            case 0:
+              block_colorchat_dist=good_dist;
+            case 1:
+              block_colorchat_dist=pro_dist;
+            case 2:
+              block_colorchat_dist=holy_dist;
+            case 3:
+              block_colorchat_dist=leet_dist;
+            case 4:
+              block_colorchat_dist=god_dist;
+            case 5:
+              block_colorchat_dist=dom_dist;
+          }
+          
+          
+          new block_str[20];
+          
+          if(jumpblock[id]>=block_colorchat_dist && jumpblock[id]user_block[id][1] && edgedist[id]<100.0 && edgedist[id]!=0.0 && (jumpblock[id]+edgedist[id])= dom_dist ) {
+                    if( uq_sounds && enable_sound[ids]==true )
+                    {
+                      client_cmd(ids, "speak misc/dominatingkz");
+                    }
+                    ColorChat(ids, RED, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%% ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],weapon_name, block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= god_dist ) {
+                    if( uq_sounds && enable_sound[ids]==true )
+                    {
+                      client_cmd(ids, "speak misc/mod_godlike");
+                    }
+                    ColorChat(ids, RED, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%% ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],weapon_name, block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= leet_dist  ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/mod_wickedsick");
+                  
+                    ColorChat(ids, RED, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%% ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],weapon_name, block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= holy_dist ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/holyshit");
+                  
+                    ColorChat(ids, BLUE, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%% ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],weapon_name, block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= pro_dist ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/perfect");
+                  
+                    ColorChat(ids, GREEN, "%s ^x01%s  ^x04%s ^x01= ^x01 Distance: ^x04%.3f ^x01Prestrafe: ^x04%.01f ^x01Strafes: ^x04%d ^x01Sync: ^x04%d%% ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],weapon_name, block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >=good_dist ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/impressive");
+                  
+                    ColorChat(ids, GREY, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%% ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],weapon_name, block_str,pre_type[id],airacel[id]);
+                  }
+                }
+                else if(jump_type[id]==Type_Multi_CountJump || (multiscj[id]==2 && jump_type[id]==Type_StandUp_CountJump) || (multidropcj[id]==2 && jump_type[id]==Type_Drop_CountJump))
+                {
+                  if ( distance[id] >= dom_dist ) {
+                    if( uq_sounds && enable_sound[ids]==true )
+                    {
+                      client_cmd(ids, "speak misc/dominatingkz");
+                    }
+                    ColorChat(ids, RED, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%%^x01 Ducks: ^x03%d ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],ducks[id],weapon_name,block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= god_dist ) {
+                    if( uq_sounds && enable_sound[ids]==true )
+                    {
+                      client_cmd(ids, "speak misc/mod_godlike");
+                    }
+                    ColorChat(ids, RED, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%%^x01 Ducks: ^x03%d ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],ducks[id],weapon_name,block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= leet_dist  ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/mod_wickedsick");
+                  
+                    ColorChat(ids, RED, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%%^x01 Ducks: ^x03%d ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],ducks[id],weapon_name,block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= holy_dist ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/holyshit");
+                  
+                    ColorChat(ids, BLUE, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%%^x01 Ducks: ^x03%d ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],ducks[id],weapon_name,block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >= pro_dist ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/perfect");
+                  
+                    ColorChat(ids, GREEN, "%s ^x01%s  ^x04%s ^x01= ^x01 Distance: ^x04%.3f ^x01Prestrafe: ^x04%.01f ^x01Strafes: ^x04%d ^x01Sync: ^x04%d%%^x01 Ducks: ^x04%d ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],ducks[id],weapon_name,block_str,pre_type[id],airacel[id]);
+                  }
+                  else if ( distance[id] >=good_dist ) {
+                    if( uq_sounds && enable_sound[id]==true ) client_cmd(id, "speak misc/impressive");
+                  
+                    ColorChat(ids, GREY, "%s ^x01%s  ^x03%s ^x01= ^x01 Distance: ^x03%.3f ^x01Prestrafe: ^x03%.01f ^x01Strafes: ^x03%d ^x01Sync: ^x03%d%%^x01 Ducks: ^x03%d ^x01%s ^x01%s ^x03%s",prefix, g_playername[id],Jtype[id],distance[id],prestrafe[id],strafe_num[id],sync_[id],ducks[id],weapon_name,block_str,pre_type[id],airacel[id]);
+                  }
+                }
+              }  
+            }
+          }
+          
+          // UberBeam start
+          if( kz_beam[id]==true)
+            {
+            for( new i = 0; i < 100; i++ ) {
+              if( gBeam_points[id][i][0] == 0.0
+              && gBeam_points[id][i][1] == 0.0
+              && gBeam_points[id][i][2] == 0.0 ) {
+                continue;
+              }
+            
+              message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0, 0, 0}, id);
+              write_byte ( TE_BEAMPOINTS );
+              if( i == 100 ) {
+                write_coord(floatround(gBeam_points[id][i][0]));
+                write_coord(floatround(gBeam_points[id][i][1]));
+                write_coord(floatround(jumpoff_origin[id][2]-34.0));
+                write_coord(floatround(land_origin[0]));
+                write_coord(floatround(land_origin[1]));
+                write_coord(floatround(jumpoff_origin[id][2]-34.0));
+              } else {
+                if ( i > 2 ) {
+                  write_coord(floatround(gBeam_points[id][i-1][0]));
+                  write_coord(floatround(gBeam_points[id][i-1][1]));
+                  write_coord(floatround(jumpoff_origin[id][2]-34.0));
+                } else {
+                  write_coord(floatround(jumpoff_origin[id][0]));
+                  write_coord(floatround(jumpoff_origin[id][1]));
+                  write_coord(floatround(jumpoff_origin[id][2]-34.0));
+                }
+                write_coord(floatround(gBeam_points[id][i][0]));
+                write_coord(floatround(gBeam_points[id][i][1]));
+                write_coord(floatround(jumpoff_origin[id][2]-34.0));
+              }
+              write_short(gBeam);
+              write_byte(1);
+              write_byte(5);
+              write_byte(30);
+              write_byte(20);
+              write_byte(0);
+              if(gBeam_duck[id][i])
+              {
+                
+                write_byte(255);
+                write_byte(0);
+                write_byte(0);
+              }
+              else if(beam_type[id]==2 && gBeam_button[id][i])
+              {
+                if(gBeam_button_what[id][i]==1)
+                {
+                  write_byte(0);
+                  write_byte(255);
+                  write_byte(0);
+                }
+                else if(gBeam_button_what[id][i]==2)
+                {
+                  write_byte(0);
+                  write_byte(0);
+                  write_byte(255);
+                }
+              }
+              else 
+              {
+                write_byte(255);
+                write_byte(255);
+                write_byte(0);
+              }
+              write_byte(200);
+              write_byte(200);
+              message_end();
+              
+            }
+          }
+          
+          JumpReset(id);
+      
+        }
+        new bool:posible_dropcj;
+        if(button & IN_DUCK && !(oldbuttons &IN_DUCK) && (jump_type[id]==Type_Drop_BhopLongJump || jump_type[id]==Type_WeirdLongJump))
+        {
+          new Float:tmpdropcj_start[3],Float:tmpdropcj_end[3],Float:tmpdropcj_frame[3];
+          pev(id, pev_origin, origin);
+          
+          tmpdropcj_start=origin;
+          tmpdropcj_start[2]=tmpdropcj_start[2]-36.0;
+          
+          tmpdropcj_end=tmpdropcj_start;
+          tmpdropcj_end[2]=tmpdropcj_end[2]-20;
+          
+          engfunc(EngFunc_TraceLine,origin,tmpdropcj_end, IGNORE_GLASS, id, 0); 
+          get_tr2( 0, TR_vecEndPos, tmpdropcj_frame);
+          
+          if(tmpdropcj_start[2]-tmpdropcj_frame[2]<=18.0)
+          {
+            posible_dropcj=true;
+            in_duck[id]=false;
+          }
+          else posible_dropcj=false;
+          
+        }
+        
+        if(!in_air[id] && button & IN_DUCK && !(oldbuttons &IN_DUCK) && (flags & FL_ONGROUND || posible_dropcj) && !in_duck[id] && UpcjFail[id]==false)
+        {  
+          if( get_gametime( ) - duckoff_time[id] < 0.3 )
+          {
+            started_multicj_pre[id] = true;
+            prest[id]= speed; 
+            ducks[id]++;
+            statsduckspeed[id][ducks[id]]=speed;
+            new Float:tmporg_z;
+            if(is_user_ducking(id))
+            {
+              tmporg_z=origin[2]+18.0;
+            }
+            else tmporg_z=origin[2];
+            
+            if(tmporg_z-first_duck_z[id]>4.0)
+            {
+              JumpReset(id);
+              if(dropbhop[id])
+                dropbhop[id]=false;
+              if(in_ladder[id])
+                in_ladder[id]=false;
+                
+              dropupcj[id]=true;
+              
+              return FMRES_IGNORED;
+            }
+            
+            for( new i = 1; i < max_players; i++ )
+            {
+              if( (i == id || is_spec_user[i]))
+              {
+                if(showpre[id]==true && showduck[id]==true)
+                {
+                  set_hudmessage(prest_r,prest_g, prest_b, prest_x, prest_y, 0, 0.0, 0.7, 0.1, 0.1, h_prest);
+                  show_hudmessage(i, "Duck Pre: %.03f",speed);
+                }
+              }
+            }
+          }
+          else
+          {
+            pev(id, pev_origin, origin);
+            
+            ducks[id]=0;
+            prest1[id]= speed; //ground pre
+            ducks[id]++;//schetchik duckov
+            duckstartz[id]=origin[2];
+            statsduckspeed[id][ducks[id]]=speed;//dlya vivoda stati po ducka
+            
+            started_cj_pre[id] = true;
+            nextbhop[id]=false;
+            bhopaem[id]=false;
+            
+            if(first_duck_z[id] && (origin[2]-first_duck_z[id])>4)
+            {
+              dropupcj[id]=true;
+              
+              JumpReset(id);
+              if(dropbhop[id])
+                dropbhop[id]=false;
+              if(in_ladder[id])
+                in_ladder[id]=false;
+                
+              return FMRES_IGNORED;
+            }
+            if(ducks[id]==1) 
+            {
+              if(is_user_ducking(id))
+              {
+                first_duck_z[id]=origin[2]+18.0;
+              }
+              else first_duck_z[id]=origin[2];
+            }
+            if(dropupcj[id]==false && get_gametime()-FallTime[id]<0.3 && (in_ladder[id] || jump_type[id]==Type_ladderBhop || jump_type[id]==Type_Drop_BhopLongJump || jump_type[id]==Type_WeirdLongJump || dropbhop[id]))
+            {
+              in_ladder[id]=false;
+              jump_type[id] = Type_Drop_CountJump;
+              formatex(Jtype[id],32,"Drop CJ");
+              formatex(Jtype1[id],32,"drcj");
+              multidropcj[id]=0;
+              dropaem[id]=true;
+              
+              if(dropbhop[id])
+                dropbhop[id]=false;
+              if(in_ladder[id])
+                in_ladder[id]=false;
+            }
+          }
+          
+          in_duck[id] = true;
+        }
+        else if( !in_air[id] && oldbuttons & IN_DUCK && (flags & FL_ONGROUND || posible_dropcj) && UpcjFail[id]==false)
+        {
+          if( !is_user_ducking( id ) )
+          {  
+            in_duck[id] = false;
+            if( started_cj_pre[id] )
+            {
+              started_cj_pre[id] = false;
+              
+              duckoff_time[id] = get_gametime( );
+              duckoff_origin[id] = origin;
+              FallTime1[id]=get_gametime();
+            
+              strafe_num[id] = 0;
+              TempSpeed[id] = 0.0;
+              
+              if(jump_type[id] != Type_Drop_CountJump)
+              {
+                jump_type[id] = Type_CountJump;
+                jump_typeOld[id]=1;      
+                if(nextbhop[id] || bhopaem[id])
+                {
+                  formatex(Jtype[id],32,"CountJump After Jump");
+                  formatex(Jtype1[id],32,"cjaj");
+                  
+                  CjafterJump[id]=1;
+      
+                  ddafterJump[id]=true;
+                }
+                else
+                {
+                  formatex(Jtype[id],32,"CountJump");
+                  formatex(Jtype1[id],32,"cj");
+                  
+                  CjafterJump[id]=0;
+                  ddafterJump[id]=false;
+                }
+                
+              }
+              else 
+              {
+                FallTime[id]=get_gametime();
+                multidropcj[id]=0;
+                jump_typeOld[id]=1;
+              }
+            }
+            else if( started_multicj_pre[id] )
+            {
+              started_multicj_pre[id] = false;
+              
+              duckoff_time[id] = get_gametime( );
+              duckoff_origin[id] = origin;
+              FallTime1[id]=get_gametime();
+              
+              strafe_num[id] = 0;
+              TempSpeed[id] = 0.0;
+              
+              if(jump_type[id] != Type_Drop_CountJump)
+              {
+                jump_type[id] = Type_Double_CountJump;
+                jump_typeOld[id]=2;
+                if(nextbhop[id] || bhopaem[id])
+                {
+                  formatex(Jtype[id],32,"Double CountJump After Jump");
+                  formatex(Jtype1[id],32,"dcjaj");
+                  
+                  CjafterJump[id]=2;
+                  ddafterJump[id]=true;
+                }
+                else
+                {
+                  formatex(Jtype[id],32,"Double CountJump");
+                  formatex(Jtype1[id],32,"dcj");
+                  
+                  CjafterJump[id]=0;
+                  ddafterJump[id]=false;
+                }
+              }
+              else 
+              {  
+                multidropcj[id]=1;
+                FallTime[id]=get_gametime();
+                jump_typeOld[id]=2;
+              }
+            }
+            if(ducks[id]>2)
+            {  
+              if(jump_type[id] != Type_Drop_CountJump)
+              {
+                jump_type[id] = Type_Multi_CountJump; //detect mcj
+                jump_typeOld[id]=3;
+                if(nextbhop[id] || bhopaem[id])
+                {
+                  formatex(Jtype[id],32,"Multi CountJump After Jump");
+                  formatex(Jtype1[id],32,"mcjaj");
+                  
+                  CjafterJump[id]=3;
+                  ddafterJump[id]=true;
+                }
+                else
+                {
+                  formatex(Jtype[id],32,"Multi CountJump");
+                  formatex(Jtype1[id],32,"mcj");
+                  
+                  CjafterJump[id]=0;
+                  ddafterJump[id]=false;
+                }
+              }
+              else 
+              {  
+                multidropcj[id]=2;
+                FallTime[id]=get_gametime();
+                jump_typeOld[id]=3;
+              }  
+            }
+          }
+        }
+        
+        
+        if(flags&FL_ONGROUND && g_Jumped[id]==false && jofon[id] && movetype[id] != MOVETYPE_FLY)
+        {
+          new Float:new_origin[3],Float:tmpOrigin[3], Float:tmpOrigin2[3];
+            
+          pev(id,pev_origin,new_origin);
+          new_origin[2]=new_origin[2]-36.1;
+          
+          pev(id, pev_velocity, velocity);
+          
+          for(new i=0,j=-18;i<3;i++,j=j+18)
+          {
+            tmpOrigin=new_origin;
+            tmpOrigin2=new_origin;
+            
+            if(velocity[1]>0 && floatabs(velocity[1])>floatabs(velocity[0]))
+            {
+              tmpOrigin[1]=new_origin[1]+200;
+              tmpOrigin2[1]=new_origin[1]-16;
+              
+              tmpOrigin[0]=tmpOrigin[0]+j;
+              tmpOrigin2[0]=tmpOrigin2[0]+j;
+              
+            }
+            else if(velocity[1]<0 && floatabs(velocity[1])>floatabs(velocity[0]))
+            {
+              tmpOrigin[1]=new_origin[1]-200;
+              tmpOrigin2[1]=new_origin[1]+16;
+              
+              tmpOrigin[0]=tmpOrigin[0]+j;
+              tmpOrigin2[0]=tmpOrigin2[0]+j;
+            }
+            else if(velocity[0]>0 && floatabs(velocity[0])>floatabs(velocity[1]))
+            {
+              tmpOrigin[0]=new_origin[0]+200;
+              tmpOrigin2[0]=new_origin[0]-16;
+              
+              tmpOrigin[1]=tmpOrigin[1]+j;
+              tmpOrigin2[1]=tmpOrigin2[1]+j;
+            }
+            else if(velocity[0]<0 && floatabs(velocity[0])>floatabs(velocity[1]))
+            {
+              tmpOrigin[0]=new_origin[0]-200;
+              tmpOrigin2[0]=new_origin[0]+16;
+              
+              tmpOrigin[1]=tmpOrigin[1]+j;
+              tmpOrigin2[1]=tmpOrigin2[1]+j;
+            }
+            
+            new Float:tmpEdgeOrigin[3];
+            
+            engfunc(EngFunc_TraceLine,tmpOrigin,tmpOrigin2, IGNORE_GLASS, id, 0); 
+            get_tr2( 0, TR_vecEndPos, tmpEdgeOrigin);
+          
+            if(get_distance_f(tmpEdgeOrigin,tmpOrigin2)!=0.0)
+            {
+              jof[id]=get_distance_f(tmpEdgeOrigin,tmpOrigin2)-0.031250;
+            }
+          }
+        }
+        else if(!(flags&FL_ONGROUND) && g_Jumped[id] && edgedone[id]==false && movetype[id] != MOVETYPE_FLY)
+        {
+          new onbhopblock,bhop_block[1];
+          
+          find_sphere_class(id,"func_door", 48.0, bhop_block, 1, Float:{0.0, 0.0, 0.0} );
+          
+          if(bhop_block[0])
+          {
+            onbhopblock=true;
+          }
+          else
+          {
+            onbhopblock=false;
+          }
+          
+          
+          new Float:tmpblock[3],tmpjblock[3],Float:new_origin[3],Float:tmpOrigin[3], Float:tmpOrigin2[3];
+            
+          new_origin=jumpoff_origin[id];
+          if(onbhopblock)
+          {
+            new_origin[2]=new_origin[2]-40.0;
+          }
+          else new_origin[2]=new_origin[2]-36.1;
+          
+          pev(id, pev_velocity, velocity);
+          
+          for(new i=0,j=-18;i<3;i++,j=j+18)
+          {
+            tmpOrigin=new_origin;
+            tmpOrigin2=new_origin;
+            tmpblock=new_origin;
+            if(velocity[1]>0 && floatabs(velocity[1])>floatabs(velocity[0]))
+            {
+              tmpOrigin[1]=new_origin[1]+100;
+              tmpOrigin2[1]=new_origin[1]-16;
+              
+              tmpOrigin[0]=tmpOrigin[0]+j;
+              tmpOrigin2[0]=tmpOrigin2[0]+j;
+              
+              tmpblock[1]=new_origin[1]+uq_maxedge+1;
+              tmpblock[0]=tmpblock[0]+j;
+            }
+            else if(velocity[1]<0 && floatabs(velocity[1])>floatabs(velocity[0]))
+            {
+              tmpOrigin[1]=new_origin[1]-100;
+              tmpOrigin2[1]=new_origin[1]+16;
+              
+              tmpOrigin[0]=tmpOrigin[0]+j;
+              tmpOrigin2[0]=tmpOrigin2[0]+j;
+              
+              tmpblock[1]=new_origin[1]-uq_maxedge+1;
+              tmpblock[0]=tmpblock[0]+j;
+            }
+            else if(velocity[0]>0 && floatabs(velocity[0])>floatabs(velocity[1]))
+            {
+              tmpOrigin[0]=new_origin[0]+100;
+              tmpOrigin2[0]=new_origin[0]-16;
+              
+              tmpOrigin[1]=tmpOrigin[1]+j;
+              tmpOrigin2[1]=tmpOrigin2[1]+j;
+              
+              tmpblock[0]=new_origin[0]+uq_maxedge+1;
+              tmpblock[1]=tmpblock[1]+j;
+            }
+            else if(velocity[0]<0 && floatabs(velocity[0])>floatabs(velocity[1]))
+            {
+              tmpOrigin[0]=new_origin[0]-100;
+              tmpOrigin2[0]=new_origin[0]+16;
+              
+              tmpOrigin[1]=tmpOrigin[1]+j;
+              tmpOrigin2[1]=tmpOrigin2[1]+j;
+              
+              tmpblock[0]=new_origin[0]-uq_maxedge+1;
+              tmpblock[1]=tmpblock[1]+j;
+            }
+            
+            new Float:tmpEdgeOrigin[3];
+            
+            engfunc(EngFunc_TraceLine,tmpOrigin,tmpOrigin2, IGNORE_GLASS, id, 0); 
+            get_tr2( 0, TR_vecEndPos, tmpEdgeOrigin);
+                
+            if(get_distance_f(tmpEdgeOrigin,tmpOrigin2)!=0.0)
+            {
+              edgedist[id]=get_distance_f(tmpEdgeOrigin,tmpOrigin2)-0.031250;
+            }
+            
+            new Float:tmpblockOrigin[3];
+            
+            engfunc(EngFunc_TraceLine,tmpEdgeOrigin,tmpblock, IGNORE_GLASS, id, 0); 
+            get_tr2( 0, TR_vecEndPos, tmpblockOrigin);
+            
+            if(get_distance_f(tmpblockOrigin,tmpEdgeOrigin)!=0.0)
+            {
+              tmpjblock[i]=floatround(get_distance_f(tmpblockOrigin,tmpEdgeOrigin),floatround_floor)+1;
+            }
+            
+            /*new Float:checkblock1[3],Float:checkblock2[3];
+            tmpblockOrigin[2]=tmpblockOrigin[2]-1.0;
+                        
+            if(velocity[1]>0 && floatabs(velocity[1])>floatabs(velocity[0]))
+            {
+              checkblock1[1]=checkblock1[1]+2.0;
+            }
+            else if(velocity[1]<0 && floatabs(velocity[1])>floatabs(velocity[0]))
+            {
+              checkblock1[1]=checkblock1[1]-2.0;
+            }
+            else if(velocity[0]>0 && floatabs(velocity[0])>floatabs(velocity[1]))
+            {
+              checkblock1[0]=checkblock1[0]+2.0;
+            }
+            else if(velocity[0]<0 && floatabs(velocity[0])>floatabs(velocity[1]))
+            {
+              checkblock1[0]=checkblock1[0]-2.0;
+            }
+            
+            checkblock2=checkblock1;
+            checkblock2[2]=checkblock2[2]+18.0;
+            
+            new Float:tmpcheckblock[3];
+            engfunc(EngFunc_TraceLine,checkblock2,checkblock1, IGNORE_GLASS, id, 0); 
+            get_tr2( 0, TR_vecEndPos, tmpcheckblock);
+            
+            if(floatabs(tmpblockOrigin[2]-tmpcheckblock[2])==0.0)
+            {
+              tmpjblock[i]=0;
+            }*/
+            
+            edgedone[id]=true;
+          }
+          
+          if(tmpjblock[0]!=0 && tmpjblock[0]<=tmpjblock[1] && tmpjblock[0]<=tmpjblock[2])
+          {
+            jumpblock[id]=tmpjblock[0];
+          }
+          else if(tmpjblock[1]!=0 && tmpjblock[1]<=tmpjblock[2] && tmpjblock[0]<=tmpjblock[0])
+          {
+            jumpblock[id]=tmpjblock[1];
+          }
+          else if(tmpjblock[2]!=0 && tmpjblock[2]<=tmpjblock[1] && tmpjblock[0]<=tmpjblock[0])
+          {
+            jumpblock[id]=tmpjblock[2];
+          }
+          else jumpblock[id]=0;
+          
+          if(equali(mapname,"prochallenge_longjump"))
+          {
+            jumpblock[id]=jumpblock[id]-1;
+          }
+          
+          new h_jof;
+          
+          if(jofon[id])
+          {
+            h_jof=h_speed;
+          }
+          else h_jof=4;
+          
+          for( new i = 1; i < max_players; i++ )
+          {
+            if( (i == id || is_spec_user[i]))
+            {  
+              if(edgedist[i]!=0.0 && (showjofon[i] || jofon[id])) 
+              {
+                if(edgedist[i]>5.0)
+                {
+                  set_hudmessage(255, 255, 255, -1.0, 0.6, 0, 0.0, 0.7, 0.0, 0.0, h_jof);
+                }
+                else
+                {
+                  set_hudmessage(255, 0, 0, -1.0, 0.6, 0, 0.0, 0.7, 0.0, 0.0, h_jof);
+                }
+                show_hudmessage(i, "JumpOff: %f", edgedist[id]);
+              }
+            }
+          }
+        }
+        
+        new Float:checkfall;
+        if(jump_type[id]==Type_Drop_CountJump)
+        {
+          checkfall=0.5;
+        }
+        else checkfall=0.4;
+        
+        if(flags&FL_ONGROUND && firstfall_ground[id]==true && get_gametime()-FallTime1[id]>checkfall)
+        {
+          touch_ent[id]=false;    
+          JumpReset(id);
+          dropbhop[id]=false;
+          ddnum[id]=0;
+          x_jump[id]=false;
+          firstfall_ground[id]=false;
+          in_ladder[id]=false;
+          nextbhop[id]=false;
+          bhopaem[id]=false;
+          UpcjFail[id]=false;
+          slide_protec[id]=false;
+          backwards[id]=false;
+          ladderbug[id]=false;
+          find_ladder[id]=false;
+          touch_somthing[id]=false;
+          duckbhop[id]=false;
+          dropupcj[id]=false;
+          //if(donehook[id]) ColorChat(id, RED, "reset ground %d %f",jump_type[id],get_gametime()-FallTime1[id]);
+          return FMRES_IGNORED;
+        }
+        
+        if(flags&FL_ONGROUND && firstfall_ground[id]==false)
+        {
+          FallTime1[id]=get_gametime();
+          firstfall_ground[id]=true;
+        }
+        else if(!(flags&FL_ONGROUND) && firstfall_ground[id]==true)
+        {
+          firstfall_ground[id]=false;
+        }
+        
+        if(flags&FL_ONGROUND && donehook[id] && hookcheck[id]==false)
+        {
+          timeonground[id]=get_gametime();
+          hookcheck[id]=true;
+        }
+        else if(!(flags&FL_ONGROUND) && donehook[id] && hookcheck[id])
+        {
+          timeonground[id]=get_gametime()-timeonground[id];
+          hookcheck[id]=false;
+          
+          if(timeonground[id]>0.4)
+          donehook[id]=false;
+        }
+      }
+    }
+  }
+  return FMRES_IGNORED;
+}
+
+public HamTouch( id, entity )
+{
+  if ( g_alive[id] )
+  {
+    static Float:Vvelocity[3];
+    pev(id, pev_velocity, Vvelocity);
+    if(!equali(mapname,"slide_gs_longjumps") && !equali(mapname,"b2j_slide_longjumps"))
+    {
+      if(g_Jumped[id] && !(pev(id, pev_flags)&FL_ONGROUND) && floatround(Vvelocity[2], floatround_floor) < 0)
+      {
+        touch_somthing[id]=true;
+      }
+    }
+  }
+}
+public fwdTouch(ent, id)
+{
+  static ClassName[32];
+  if( pev_valid(ent) )
+  {
+    pev(ent, pev_classname, ClassName, 31);
+  }
+  
+  static ClassName2[32];
+  if( valid_id(id) )
+  {
+    pev(id, pev_classname, ClassName2, 31);
+  }
+  if( equali(ClassName2, "player") )
+  {
+    if( equali(ClassName, "func_train")
+      || equali(ClassName, "func_conveyor") 
+      || equali(ClassName, "trigger_push") || equali(ClassName, "trigger_gravity"))
+    {
+      if(valid_id(id))
+      {
+        touch_ent[id]=true;
+        JumpReset(id);
+        set_task(0.4,"JumpReset", id);
+      }
+    }
+  }
+}
+
+public fwdPostThink( id ) 
+{
+  if( g_alive[id] && g_userConnected[id])
+  {
+    if( g_Jumped[id] ) 
+    {
+      
+      FullJumpFrames[id]++;
+      
+      static buttonsNew;
+      
+      static buttons;
+      static Float:angle[3];
+  
+      buttonsNew = pev(id, pev_button);
+      buttons = pev(id, pev_button);
+      pev(id, pev_angles, angle);
+      pev(id, pev_velocity, velocity);
+      velocity[2] = 0.0;
+      
+      fSpeed = vector_length(velocity);
+      
+      
+      if( old_angle1[id] > angle[1] ) {
+        turning_left[id] = false;
+        turning_right[id] = true;
+      }
+      else if( old_angle1[id] < angle[1] ) {
+        turning_left[id] = true;
+        turning_right[id] = false;
+      } else {
+        turning_left[id] = false;
+        turning_right[id] = false;
+      }
+      //schetchik streifof
+      if( !(strafecounter_oldbuttons[id]&IN_MOVELEFT) && buttonsNew&IN_MOVELEFT
+      && !(buttonsNew&IN_MOVERIGHT) && !(buttonsNew&IN_BACK) && !(buttonsNew&IN_FORWARD)
+      && (turning_left[id] || turning_right[id]) )
+      {
+        preessbutton[id]=true;
+        button_what[id]=1;
+        
+        if(strafe_num[id] < NSTRAFES)
+          strafe_stat_time[id][strafe_num[id]] = get_gametime();
+        strafe_num[id] += 1;
+        
+        if(strafe_num[id]>0 && strafe_num[id]<100) type_button_what[id][strafe_num[id]]=1;
+      }
+      else if( !(strafecounter_oldbuttons[id]&IN_MOVERIGHT) && buttonsNew&IN_MOVERIGHT
+      && !(buttonsNew&IN_MOVELEFT) && !(buttonsNew&IN_BACK) && !(buttonsNew&IN_FORWARD)
+      && (turning_left[id] || turning_right[id]) )
+      {
+        preessbutton[id]=true;
+        button_what[id]=2;
+        
+        if(strafe_num[id] < NSTRAFES)
+          strafe_stat_time[id][strafe_num[id]] = get_gametime();
+        strafe_num[id] += 1;
+        
+        if(strafe_num[id]>0 && strafe_num[id]<100) type_button_what[id][strafe_num[id]]=1;
+      }
+      else if( !(strafecounter_oldbuttons[id]&IN_BACK) && buttonsNew&IN_BACK
+      && !(buttonsNew&IN_MOVELEFT) && !(buttonsNew&IN_MOVERIGHT) && !(buttonsNew&IN_FORWARD)
+      && (turning_left[id] || turning_right[id]) )
+      {
+        preessbutton[id]=true;
+        button_what[id]=1;
+        
+        if(strafe_num[id] < NSTRAFES)
+          strafe_stat_time[id][strafe_num[id]] = get_gametime();
+        strafe_num[id] += 1;
+        
+        if(strafe_num[id]>0 && strafe_num[id]<100) type_button_what[id][strafe_num[id]]=2;
+      }
+      else if( !(strafecounter_oldbuttons[id]&IN_FORWARD) && buttonsNew&IN_FORWARD
+      && !(buttonsNew&IN_MOVELEFT) && !(buttonsNew&IN_MOVERIGHT) && !(buttonsNew&IN_BACK)
+      && (turning_left[id] || turning_right[id]) )
+      {
+        preessbutton[id]=true;
+        button_what[id]=2;
+    
+        if(strafe_num[id] < NSTRAFES)
+          strafe_stat_time[id][strafe_num[id]] = get_gametime();
+        strafe_num[id] += 1;
+        
+        if(strafe_num[id]>0 && strafe_num[id]<100) type_button_what[id][strafe_num[id]]=2;
+      }
+      
+      if( buttonsNew&IN_MOVERIGHT
+      || buttonsNew&IN_MOVELEFT
+      || buttonsNew&IN_FORWARD
+      || buttonsNew&IN_BACK )
+      {  
+        //tskFps(id);
+        if(strafe_num[id] < NSTRAFES)
+        {
+          if( fSpeed > speed)
+          {
+            strafe_stat_sync[id][strafe_num[id]][0] += 1; 
+          }
+          else
+          {
+            strafe_stat_sync[id][strafe_num[id]][1] += 1;
+            if(uq_istrafe)
+              line_lost[id][strafe_num[id]][lost_frame_count[id][strafe_num[id]]]=1;
+          }
+          
+          if(uq_istrafe)
+          {
+            line_erase[id][strafe_num[id]]=lost_frame_count[id][strafe_num[id]];
+            line_erase_strnum[id]=strafe_num[id];
+          
+            lost_frame_count[id][strafe_num[id]]++;
+          }
+        }
+        
+      }
+      else if(uq_istrafe)
+        strafe_lost_frame[id][strafe_num[id]] += 1;
+      
+      if( buttons&IN_MOVERIGHT && (buttons&IN_MOVELEFT || buttons&IN_FORWARD || buttons&IN_BACK) )
+        strafecounter_oldbuttons[id] = 0;
+      else if( buttons&IN_MOVELEFT && (buttons&IN_FORWARD || buttons&IN_BACK || buttons&IN_MOVERIGHT) )
+        strafecounter_oldbuttons[id] = 0;
+      else if( buttons&IN_FORWARD && (buttons&IN_BACK || buttons&IN_MOVERIGHT || buttons&IN_MOVELEFT) )
+        strafecounter_oldbuttons[id] = 0;
+      else if( buttons&IN_BACK && (buttons&IN_MOVERIGHT || buttons&IN_MOVELEFT || buttons&IN_FORWARD) )
+        strafecounter_oldbuttons[id] = 0;
+      else if( turning_left[id] || turning_right[id] )
+        strafecounter_oldbuttons[id] = buttons;
+    }
+  }
+}
+public get_colorchat_by_distance(JumpType:type_jump,mSpeed,t_dist,bool:drop_a,multiscj_a,aircj)
+{
+  new dist_array[6];
+  
+  dist_array[2]=280;
+    
+  if(type_jump==Type_Double_CountJump || type_jump==Type_Multi_CountJump )
+  {
+    dist_array[5]=270;
+    dist_array[4]=268;
+    dist_array[3]=265;
+    dist_array[2]=260;
+    dist_array[1]=255;
+    dist_array[0]=250;
+  }
+  else if(type_jump==Type_LongJump || type_jump==Type_HighJump)
+  {  
+    dist_array[5]=255;
+    dist_array[4]=254;
+    dist_array[3]=252;
+    dist_array[2]=250;
+    dist_array[1]=245;
+    dist_array[0]=240;
+  }
+  else if(type_jump==Type_ladder)
+  {  
+    dist_array[5]=190;
+    dist_array[4]=185;
+    dist_array[3]=180;
+    dist_array[2]=170;
+    dist_array[1]=160;
+    dist_array[0]=150;
+  }
+  else if(type_jump==Type_WeirdLongJump || type_jump==Type_Drop_CountJump || type_jump==Type_ladderBhop)
+  {  
+    dist_array[5]=270;
+    dist_array[4]=268;
+    dist_array[3]=265;
+    dist_array[2]=260;
+    dist_array[1]=255;
+    dist_array[0]=250;
+  }
+  else if(type_jump==Type_BhopLongJump || type_jump==Type_StandupBhopLongJump)
+  {  
+    dist_array[5]=247;
+    dist_array[4]=245;
+    dist_array[3]=243;
+    dist_array[2]=240;
+    dist_array[1]=235;
+    dist_array[0]=230;
+  }
+  else if(type_jump==Type_CountJump)
+  {  
+    dist_array[5]=267;
+    dist_array[4]=265;
+    dist_array[3]=263;
+    dist_array[2]=260;
+    dist_array[1]=255;
+    dist_array[0]=250;
+  }
+  else if(type_jump==Type_Drop_BhopLongJump)
+  {  
+    dist_array[5]=267;
+    dist_array[4]=265;
+    dist_array[3]=263;
+    dist_array[2]=260;
+    dist_array[1]=250;
+    dist_array[0]=240;
+  }
+  else if(type_jump==Type_StandUp_CountJump && drop_a==false)
+  {  
+    if(multiscj_a==0)
+    {
+      dist_array[5]=262+aircj;
+      dist_array[4]=260+aircj;
+      dist_array[3]=257+aircj;
+      dist_array[2]=255+aircj;
+      dist_array[1]=250+aircj;
+      dist_array[0]=245+aircj;
+    }
+    else if(multiscj_a==1 || multiscj_a==2)
+    {
+      dist_array[5]=262+aircj+10;
+      dist_array[4]=260+aircj+10;
+      dist_array[3]=257+aircj+10;
+      dist_array[2]=255+aircj+10;
+      dist_array[1]=250+aircj+10;
+      dist_array[0]=245+aircj+10;
+    }
+  }
+  else if(type_jump==Type_StandUp_CountJump && drop_a)
+  {  
+    dist_array[5]=267;
+    dist_array[4]=265;
+    dist_array[3]=263;
+    dist_array[2]=260;
+    dist_array[1]=255;
+    dist_array[0]=250;
+  }
+  else if(type_jump==Type_Bhop_In_Duck || type_jump==Type_Up_Bhop_In_Duck)
+  {  
+    dist_array[5]=220;
+    dist_array[4]=217;
+    dist_array[3]=215;
+    dist_array[2]=212;
+    dist_array[1]=210;
+    dist_array[0]=205;
+  }
+  else if(type_jump==Type_Up_Bhop)
+  {  
+    dist_array[5]=245;
+    dist_array[4]=242;
+    dist_array[3]=240;
+    dist_array[2]=235;
+    dist_array[1]=230;
+    dist_array[0]=225;
+  }
+  else if(type_jump==Type_Up_Stand_Bhop)
+  {  
+    dist_array[5]=245;
+    dist_array[4]=242;
+    dist_array[3]=240;
+    dist_array[2]=235;
+    dist_array[1]=230;
+    dist_array[0]=225;
+  }
+  else if(type_jump==Type_Real_ladder_Bhop)
+  {  
+    dist_array[5]=267;
+    dist_array[4]=265;
+    dist_array[3]=260;
+    dist_array[2]=255;
+    dist_array[1]=250;
+    dist_array[0]=240;
+  }
+  else if(type_jump==Type_DuckBhop)
+  {  
+    dist_array[5]=162;
+    dist_array[4]=160;
+    dist_array[3]=150;
+    dist_array[2]=140;
+    dist_array[1]=130;
+    dist_array[0]=120;
+  }
+  
+  if(mSpeed != 250.0 && type_jump!=Type_ladder)
+  {
+    dist_array[5]=dist_array[5]-t_dist;
+    dist_array[4]=dist_array[4]-t_dist;
+    dist_array[3]=dist_array[3]-t_dist;
+    dist_array[2]=dist_array[2]-t_dist;
+    dist_array[1]=dist_array[1]-t_dist;
+    dist_array[0]=dist_array[0]-t_dist;
+  }
+  return dist_array;
+}
+public fnSaveBeamPos( client ) {
+  if( g_Jumped[client] ) {
+    new Float:vOrigin[3];
+    pev(client, pev_origin, vOrigin);
+    
+    if( gBeam_count[client] < 100 ) {
+      gBeam_points[client][gBeam_count[client]][0] = vOrigin[0];
+      gBeam_points[client][gBeam_count[client]][1] = vOrigin[1];
+      gBeam_points[client][gBeam_count[client]][2] = vOrigin[2];
+      
+      if(preessbutton[client])
+      {
+        gBeam_button[client][gBeam_count[client]]=true;
+        
+        if(button_what[client]==1)
+        {
+          gBeam_button_what[client][gBeam_count[client]]=1;
+        }
+        else if(button_what[client]==2)
+        {
+          gBeam_button_what[client][gBeam_count[client]]=2;
+        }
+      }
+      
+      if(is_user_ducking( client ))
+        gBeam_duck[client][gBeam_count[client]] = true;
+      
+      gBeam_count[client]++;
+    }
+  }
+}
+public JumpReset(id)
+{
+  g_reset[id] = true;
+}
+
+public ddReset(id)
+{
+  id=id-2311;
+  JumpReset(id);
+  //ColorChat(id, GREEN, "reset dd");
+}
+
+public cmdColorChat(id)
+{  
+  if( !gHasColorChat[id] )
+  {
+    gHasColorChat[id] = true;
+    ColorChat(id, GREEN, "^x04%s^x01 ColorChat enabled. To disable, type /colorchat.", prefix);
+  }
+  else 
+  {
+    gHasColorChat[id] = false;
+    ColorChat(id, GREEN, "^x04%s^x01 ColorChat disabled. To enable, type /colorchat.", prefix);
+  }
+  
+  return PLUGIN_CONTINUE;
+}
+public cmdljStats( id ) {
+  
+  if(g_lj_stats[id]==true) 
+  {
+    ColorChat(id, RED, "^x04%s^x01 Stats:^x03 disabled",prefix);
+    g_lj_stats[id]=false;
+    
+    if(showpre[id]==true)
+    {
+      showpre[id]=false;
+      oldpre[id]=1;
+    }
+    if(failearly[id]==true)
+    {
+      failearly[id]=false;
+      oldfail[id]=1;
+    }
+    if(ljpre[id]==true)
+    {
+      ljpre[id]=false;
+      oldljpre[id]=1;
+    }
+  }
+  else 
+  {
+    if(oldpre[id]==1)
+    {
+      showpre[id]=true;
+      oldpre[id]=0;
+    }
+    if(oldfail[id]==1)
+    {
+      failearly[id]=true;
+      oldfail[id]=0;
+    }
+    if(oldljpre[id]==1)
+    {
+      ljpre[id]=true;
+      oldljpre[id]=0;
+    }
+    g_lj_stats[id]=true;
+    ColorChat(id, BLUE, "^x04%s^x01 Stats:^x03 enabled",prefix);
+  }
+  
+}
+
+public pre_stats(id)
+{  
+  if(kz_stats_pre[id]==true) 
+  {
+    ColorChat(id, RED, "^x04%s^x01 Prestrafe stats:^x03 disabled",prefix);
+    kz_stats_pre[id]=false;
+  }
+  else 
+  {
+    kz_stats_pre[id]=true;
+    ColorChat(id, BLUE, "^x04%s^x01 Prestrafe stats:^x03 enabled",prefix);
+  }
+}
+public streif_stats(id)
+{  
+  if(streifstat[id]==true) 
+  {
+    ColorChat(id, RED, "^x04%s^x01 Strafe's stats:^x03 disabled",prefix);
+    streifstat[id]=false;
+  }
+  else 
+  {
+    streifstat[id]=true;
+    ColorChat(id, BLUE, "^x04%s^x01 Strafe's stats:^x03 enabled",prefix);
+  }
+}
+public cmdljbeam(id)
+{
+  if(kz_beam[id]==true) 
+  {
+    ColorChat(id, RED, "^x04%s^x01 Beam:^x03 disabled",prefix);
+    kz_beam[id]=false;
+  }
+  else 
+  {
+    kz_beam[id]=true;
+    ColorChat(id, BLUE, "^x04%s^x01 Beam:^x03 enabled",prefix);
+  }
+}
+public show_pre(id)
+{
+  if(showpre[id]==true) 
+  {
+    ColorChat(id, RED, "^x04%s^x01 ShowPre:^x03 disabled",prefix);
+    showpre[id]=false;
+  }
+  else 
+  {
+    showpre[id]=true;
+    ColorChat(id, BLUE, "^x04%s^x01 ShowPre:^x03 enabled",prefix);
+  }
+}
+public show_speed(id)
+{
+  if(jofon[id])
+  {
+    ColorChat(id,RED,"^x04%s^x03 You need Turn off /joftr",prefix);
+  }
+    else
+    {
+      if(speedon[id]==false) 
+      {
+        ColorChat(id, BLUE, "^x04%s^x01 Speed:^x03 enabled",prefix);
+        speedon[id]=true;
+        
+        set_task(0.1, "DoSpeed", id+212299, "", 0, "b", 0);
+      }
+      else 
+      {
+        speedon[id]=false;
+        
+        if( task_exists(id+212299, 0) )
+          remove_task(id+212299, 0);
+          
+        ColorChat(id, RED, "^x04%s^x01 Speed:^x03 disabled",prefix);
+      }
+    }
+}
+public trainer_jof(id)
+{
+    if(speedon[id])
+    {
+      ColorChat(id,RED,"^x04%s^x03 You need Turn off /speed",prefix);
+    }
+    else
+    {
+      if(jofon[id]==false) 
+      {
+        ColorChat(id, BLUE, "^x04%s^x01 JumpOff Trainer:^x03 enabled",prefix);
+        jofon[id]=true;
+        jof[id]=0.0;
+        set_task(0.1, "Dojof", id+212398, "", 0, "b", 0);
+      }
+      else 
+      {
+        jofon[id]=false;
+        
+        if( task_exists(id+212398, 0) )
+          remove_task(id+212398, 0);
+          
+        ColorChat(id, RED, "^x04%s^x01 JumpOff Trainer:^x03 disabled",prefix);
+      }
+    }
+}
+
+public show_jheight(id)
+{
+  if(jheight_show[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Show Jump Height:^x03 enabled",prefix);
+    jheight_show[id]=true;
+  }
+  else 
+  {
+    jheight_show[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Show Jump Height:^x03 disabled",prefix);
+  }
+}
+public show_jof(id)
+{
+  if(showjofon[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Show JumpOff:^x03 enabled",prefix);
+    showjofon[id]=true;
+  }
+  else 
+  {
+    showjofon[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Show JumpOff:^x03 disabled",prefix);
+  }
+}
+public show_early(id)
+{
+  if(failearly[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Bhop fail warn:^x03 enabled",prefix);
+    failearly[id]=true;
+  }
+  else 
+  {
+    failearly[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Bhop fail warn:^x03 disabled",prefix);
+  }
+}
+public multi_bhop(id)
+{
+  if(multibhoppre[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Multi Bhop Prestrafe:^x03 enabled",prefix);
+    multibhoppre[id]=true;
+  }
+  else 
+  {
+    multibhoppre[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Multi Bhop Prestrafe:^x03 disabled",prefix);
+  }
+}
+public duck_show(id)
+{
+  if(showduck[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Ducks Prestrafe:^x03 enabled",prefix);
+    showduck[id]=true;
+  }
+  else 
+  {
+    showduck[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Ducks Prestrafe:^x03 disabled",prefix);
+  }
+}
+public lj_show(id)
+{
+  if(ljpre[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 LJ Prestrafe:^x03 enabled",prefix);
+    ljpre[id]=true;
+  }
+  else 
+  {
+    ljpre[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 LJ Prestrafe:^x03 disabled",prefix);
+  }
+}
+public enable_sounds(id)
+{
+  if(uq_sounds)
+  {
+    if(enable_sound[id]==false) 
+    {
+      ColorChat(id, BLUE, "^x04%s^x01 Sound's:^x03 enabled",prefix);
+      enable_sound[id]=true;
+    }
+    else 
+    {
+      enable_sound[id]=false;
+      ColorChat(id, RED, "^x04%s^x01 Sound's:^x03 disabled",prefix);
+    }
+  }
+  else ColorChat(id, RED, "^x04%s^x01 Sounds^x03 disabled^x01 by Server",prefix);
+}
+public ShowedgeFail(id)
+{
+  if(Show_edge_Fail[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Show edge when failed:^x03 enabled",prefix);
+    Show_edge_Fail[id]=true;
+  }
+  else 
+  {
+    Show_edge_Fail[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Show edge when failed:^x03 disabled",prefix);
+  }
+}
+public Showedge(id)
+{
+  if(Show_edge[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Show edge:^x03 enabled",prefix);
+    Show_edge[id]=true;
+  }
+  else 
+  {
+    Show_edge[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Show edge:^x03 disabled",prefix);
+  }
+}
+public heightshow(id)
+{
+  if(height_show[id]==false) 
+  {
+    ColorChat(id, BLUE, "^x04%s^x01 Show Fall/Height distance:^x03 enabled",prefix);
+    height_show[id]=true;
+  }
+  else 
+  {
+    height_show[id]=false;
+    ColorChat(id, RED, "^x04%s^x01 Show Fall/Height distance:^x03 disabled",prefix);
+  }
+}
+public ingame_st_stats(id)
+{
+  if(uq_istrafe)
+  {
+    if(ingame_strafe[id]==false) 
+    {
+      ColorChat(id, BLUE, "^x04%s^x01 Show InGame Strafe Stats:^x03 enabled",prefix);
+      ingame_strafe[id]=true;
+    }
+    else 
+    {
+      ingame_strafe[id]=false;
+      ColorChat(id, RED, "^x04%s^x01 Show InGame Strafe Stats:^x03 disabled",prefix);
+    }
+  }
+  else ColorChat(id, RED, "^x04%s^x03 Show InGame Strafe Stats disabled by Server",prefix);
+  
+}
+
+public client_connect( id )
+{
+  oldljpre[id]=0;
+  oldpre[id]=0;
+  oldfail[id]=0;
+  g_userConnected[id]=true;
+  
+  static connectt[30];
+  get_pcvar_string(kz_uq_connect, connectt, 30);
+  
+  format(connectt, 30, "_%s", connectt);
+
+  if( contain(connectt, "a") > 0 )
+    gHasColorChat[id] =true;
+  else
+    gHasColorChat[id] = false;
+  if( contain(connectt, "b") > 0 )
+    g_lj_stats[id] = true;
+  else
+    g_lj_stats[id] = false;
+  if( contain(connectt, "c") > 0 )
+    speedon[id]=true;
+  else 
+    speedon[id]=false;
+  if( contain(connectt, "d") > 0 )
+    showpre[id]=true;
+  else
+    showpre[id]=false;
+  if( contain(connectt, "e") > 0 )
+    streifstat[id]=true;
+  else
+    streifstat[id]=false;
+  if( contain(connectt, "f") > 0 )
+    kz_beam[id]=true;
+  else
+    kz_beam[id]=false;
+  if( contain(connectt, "g") > 0 )
+    kz_stats_pre[id]=true;
+  else
+    kz_stats_pre[id]=false;
+  if( contain(connectt, "h") > 0 )
+    failearly[id]=true;
+  else
+    failearly[id]=false;
+  if( contain(connectt, "i") > 0 )
+    multibhoppre[id]=true;
+  else
+    multibhoppre[id]=false;
+  if( contain(connectt, "j") > 0 )
+    showduck[id]=true;
+  else
+    showduck[id]=false;
+  if( contain(connectt, "k") > 0 )
+    ljpre[id]=true;
+  else
+    ljpre[id]=false;
+  if( contain(connectt, "l") > 0 )
+    Show_edge[id]=true;
+  else
+    Show_edge[id]=false;
+  if( contain(connectt, "m") > 0 )
+    Show_edge_Fail[id]=true;
+  else
+    Show_edge_Fail[id]=false;
+  if( contain(connectt, "n") > 0 )
+    enable_sound[id]=true;
+  else
+    enable_sound[id]=false;
+  if( contain(connectt, "o") > 0 )
+    ingame_strafe[id]=true;
+  else
+    ingame_strafe[id]=false;
+  
+  //for beta
+  //ingame_strafe[id]=true;
+  
+  user_block[id][0]=uq_maxedge;
+  user_block[id][1]=uq_minedge;
+  min_prestrafe[id]=uq_min_pre;
+  beam_type[id]=1;
+  edgeshow[id]=true;  
+  first_ground_bhopaem[id]=false;
+  donehook[id]=false;
+  OnGround[id]=false;
+  serf_reset[id]=false;
+  first_onground[id]=false;
+  duckstring[id]=false;
+  firstshow[id]=false;
+  height_show[id]=false;
+  Checkframes[id]=false;
+  firstfall_ground[id]=false;
+  h_jumped[id]=false;
+  touch_ent[id]=false;
+  ddafterJump[id]=false;
+  UpcjFail[id]=false;
+  slide_protec[id]=false;
+  posibleScj[id]=false;
+  x_jump[id]=false;
+  ddforcj[id]=false;
+  dropbhop[id]=false;
+  ddnum[id]=0;
+  hookcheck[id]=false;
+  backwards[id]=false;
+  ladderbug[id]=false;
+  touch_somthing[id]=false;
+  record_start[id]=0;
+  duckbhop_bug_pre[id]=false;
+  showtime_st_stats[id]=40;
+  showjofon[id]=true;
+
+}
+
+
+public client_infochanged(id) {
+  new name[65];
+  
+  get_user_info(id, "name", name,64); 
+  
+  if(!equali(name, g_playername[id]))
+    copy(g_playername[id], 64, name);
+}
+
+public ResetHUD(id)
+{
+  if(is_user_alive(id) && !is_user_hltv(id) )
+  {
+    if(firstshow[id]==false)
+    {
+      firstshow[id]=true;
+      
+      if(equali(mapname,"slide_gs_longjumps") || equali(mapname,"b2j_slide_longjumps"))
+      {
+        ColorChat(id, RED, "^x01%s^x03 Slide stats:^x04 Enable",prefix);
+      }
+    }
+    
+    firstfall_ground[id]=false;
+    h_jumped[id]=false;
+    
+    ddafterJump[id]=false;
+    UpcjFail[id]=false;
+    slide_protec[id]=false;
+    posibleScj[id]=false;
+    x_jump[id]=false;
+    ddforcj[id]=false;
+    dropbhop[id]=false;
+    ddnum[id]=0;
+    donehook[id]=false;
+    hookcheck[id]=false;
+    backwards[id]=false;
+    Checkframes[id]=false;
+    first_ground_bhopaem[id]=false;
+    touch_ent[id]=false;
+    ladderbug[id]=false;
+    touch_somthing[id]=false;
+  }
+  
+}
+public FwdPlayerSpawn(id)
+{
+  if( is_user_alive(id) && !is_user_bot(id) && !is_user_hltv(id))
+  {
+    if( !task_exists(id+434490, 0) )
+      set_task(1.0, "tskFps", id+434490, "", 0, "b", 0);
+      
+    g_alive[id] = true;
+    strafe_num[id]=0;
+  }
+}
+
+public FwdPlayerDeath(id)
+{
+  if( task_exists(id, 0) )
+    remove_task(id, 0);
+    
+  if( task_exists(id+434490, 0) )
+    remove_task(id+434490, 0);
+    
+  if( task_exists(id, 0) )
+    remove_task(id, 0);
+  
+  if( task_exists(id+89012, 0) )
+    remove_task(id+89012, 0);
+  
+  if( task_exists(id+3313, 0) )
+    remove_task(id+3313, 0);
+  
+  if( task_exists(id+3214, 0) )
+    remove_task(id+3214, 0);
+    
+  if( task_exists(id+15237, 0) )
+    remove_task(id+15237, 0);
+  
+  if( task_exists(id+212398, 0) )
+    remove_task(id+212398, 0);
+    
+  g_alive[id] = false;
+}
+
+public client_disconnected(id)
+{
+  new tmp_str[3];
+  num_to_str(g_sql_pid[id], tmp_str, 2);
+
+  if(TrieKeyExists(JumpPlayers, tmp_str))
+    TrieDeleteKey(JumpPlayers, tmp_str);
+  
+  remove_beam_ent(id);
+  
+  login[id]=false;
+  g_userConnected[id]=false;
+  OnGround[id]=false;
+  g_alive[id]=false;
+  
+  
+  if( task_exists(id, 0) )
+    remove_task(id);
+  
+  firstshow[id]=false;
+  if( task_exists(id+434490, 0) )
+    remove_task(id+434490, 0);
+    
+  if( task_exists(id, 0) )
+    remove_task(id, 0);
+  
+  if( task_exists(id+89012, 0) )
+    remove_task(id+89012, 0);
+
+  if( task_exists(id+3313, 0) )
+    remove_task(id+3313, 0);
+  
+  if( task_exists(id+3214, 0) )
+    remove_task(id+3214, 0);
+    
+  if( task_exists(id+15237, 0) )
+    remove_task(id+15237, 0);
+    
+  if( task_exists(id+212299, 0) )
+    remove_task(id+212299, 0);
+    
+  if( task_exists(id+212398, 0) )
+    remove_task(id+212398, 0);
+    
+  if( task_exists(id, 0) )
+    remove_task(id, 0);
+}
+
+public Option(id)
+{  
+  new MenuBody[512], len, keys;
+  len = format(MenuBody, 511, "\yOptions Menu 1/3 ^n");
+  
+  if(g_lj_stats[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r1. \yShowStats: \wEnable");
+    keys |= (1<<0);
+  }
+  else
+  {
+    keys |= (1<<0);
+    len += format(MenuBody[len], 511-len, "^n\r1. \yShowStats: \dDisable");
+  }
+  
+  if(gHasColorChat[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r2. \yColorchat: \wEnable");
+    keys |= (1<<1);
+  }
+  else
+  {
+    keys |= (1<<1);
+    len += format(MenuBody[len], 511-len, "^n\r2. \yColorchat: \dDisable");
+  }
+  
+  if(speedon[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r3. \yShow speed: \wEnable");
+    keys |= (1<<2);
+  }
+  else
+  {
+    keys |= (1<<2);
+    len += format(MenuBody[len], 511-len, "^n\r3. \yShow speed: \dDisable");
+  }
+  
+  if(showpre[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r4. \yShow prestrafe: \wEnable");
+    keys |= (1<<3);
+  }
+  else
+  {
+    keys |= (1<<3);
+    len += format(MenuBody[len], 511-len, "^n\r4. \yShow prestrafe: \dDisable");
+  }
+  
+  if(streifstat[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r5. \yShow strafes stats: \wEnable");
+    keys |= (1<<4);
+  }
+  else
+  {
+    keys |= (1<<4);
+    len += format(MenuBody[len], 511-len, "^n\r5. \yShow strafes stats: \dDisable");
+  }
+  
+  if(kz_beam[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r6. \yShow beam after jump: \wEnable");
+    keys |= (1<<5);
+  }
+  else
+  {
+    keys |= (1<<5);
+    len += format(MenuBody[len], 511-len, "^n\r6. \yShow beam after jump: \dDisable");
+  }
+  
+  if(showduck[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r7. \yShow ducks Prestrafe: \wEnable");
+    keys |= (1<<6);
+  }
+  else
+  {
+    keys |= (1<<6);
+    len += format(MenuBody[len], 511-len, "^n\r7. \yShow ducks Prestrafe: \dDisable");
+  }
+  if(failearly[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r8. \yBhop fail warn: \wEnable");
+    keys |= (1<<7);
+  }
+  else
+  {
+    keys |= (1<<7);
+    len += format(MenuBody[len], 511-len, "^n\r8. \yBhop fail warn: \dDisable");
+  }
+
+  len += format(MenuBody[len], 511-len, "^n^n\r9. \wGo to the Next page");
+  keys |= (1<<8);
+    
+  len += format(MenuBody[len], 511-len, "^n^n\r0. \wExit");
+  keys |= (1<<9);
+  
+  show_menu(id, keys, MenuBody, -1, "StatsOptionMenu1");  
+}
+
+public OptionMenu1(id, key)
+{
+  switch((key+1))
+  {
+    case 1:
+    {
+      cmdljStats(id);
+      Option(id);
+      
+    }
+    case 2:
+    {
+      cmdColorChat(id);
+      Option(id);
+    }
+    case 3:
+    {
+      show_speed(id);
+      Option(id);
+    }
+    case 4:
+    {
+      show_pre(id);
+      Option(id);
+    }
+    case 5:
+    {
+      streif_stats(id);
+      Option(id);
+    }
+    case 6:
+    {
+      cmdljbeam(id);
+      Option(id);
+    }
+    case 7:
+    {
+      duck_show(id);
+      Option(id);
+    }
+    case 8:
+    {
+      show_early(id);
+      Option(id);
+    }
+    case 9:
+    {
+      Option2(id);
+    }
+
+  }
+  return PLUGIN_HANDLED;
+}
+public Option2(id)
+{  
+  new MenuBody[512], len, keys;
+  len = format(MenuBody, 511, "\yOptions Menu 2/3 ^n");
+  
+  if(multibhoppre[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r1. \yMulti Bhop Prestrafe: \wEnable");
+    keys |= (1<<0);
+  }
+  else
+  {
+    keys |= (1<<0);
+    len += format(MenuBody[len], 511-len, "^n\r1. \yMulti Bhop Prestrafe: \dDisable");
+  }
+  if(Show_edge[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r2. \yShow Edge: \wEnable");
+    keys |= (1<<1);
+  }
+  else
+  {
+    keys |= (1<<1);
+    len += format(MenuBody[len], 511-len, "^n\r2. \yShow Edge: \dDisable");
+  }
+  if(Show_edge_Fail[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r3. \yShow Edge when Failed \d(without block)\y: \wEnable");
+    keys |= (1<<2);
+  }
+  else
+  {
+    keys |= (1<<2);
+    len += format(MenuBody[len], 511-len, "^n\r3. \yShow Edge when Failed \d(without block)\y: \dDisable");
+  }
+  
+  len += format(MenuBody[len], 511-len, "^n\r4. \yMin Block for Edge: \w%d",user_block[id][1]);
+  keys |= (1<<3);
+  len += format(MenuBody[len], 511-len, "^n\r5. \yMax Block for Edge: \w%d",user_block[id][0]);
+  keys |= (1<<4);
+  len += format(MenuBody[len], 511-len, "^n\r6. \yMinimum Prestrafe to Show: \w%d",min_prestrafe[id]);
+  keys |= (1<<5);
+  
+  if(beam_type[id]==1)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r7. \yBeam Type: \w1");
+    keys |= (1<<6);
+  }
+  else if(beam_type[id]==2)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r7. \yBeam Type: \w2");
+    keys |= (1<<6);
+  }
+  
+  
+  len += format(MenuBody[len], 511-len, "^n^n\r8. \wBack to the First Page");
+  keys |= (1<<7);
+  len += format(MenuBody[len], 511-len, "^n\r9. \wGo to the Next Page");
+  keys |= (1<<8);  
+  len += format(MenuBody[len], 511-len, "^n^n\r0. \wExit");
+  keys |= (1<<9);
+  
+  show_menu(id, keys, MenuBody, -1, "StatsOptionMenu2");
+    
+}
+
+public OptionMenu2(id, key)
+{
+  switch((key+1))
+  {
+    case 1:
+    {
+      multi_bhop(id);
+      Option2(id);  
+    }
+    case 2:
+    {
+      Showedge(id);
+      Option2(id);  
+    }
+    case 3:
+    {
+      ShowedgeFail(id);
+      Option2(id);  
+    }
+    case 4:
+    {
+      user_block[id][1]=user_block[id][1]+10;
+      if(user_block[id][1]>=user_block[id][0])
+      {
+        user_block[id][1]=uq_minedge;
+      }
+      Option2(id);  
+    }
+    case 5:
+    {
+      if(user_block[id][0]==uq_maxedge)
+      {
+        user_block[id][0]=user_block[id][1];
+        client_print(id,print_center,"Reached a maximum value (%d)",uq_maxedge);
+      }
+      user_block[id][0]=user_block[id][0]+10;
+      Option2(id);  
+    }
+    case 6:
+    {
+      if(min_prestrafe[id]>=320)
+      {
+        min_prestrafe[id]=0;
+        client_print(id,print_center,"Reached a maximum value (320)");
+      }
+      min_prestrafe[id]=min_prestrafe[id]+20;
+      Option2(id);  
+    }
+    case 7:
+    {
+      if(beam_type[id]==1)
+      {
+        beam_type[id]=2;
+        client_print(id,print_center,"Beam With Showing Strafes");
+      }
+      else
+      {
+        beam_type[id]=1;
+        client_print(id,print_center,"Standart Beam");
+      }
+      Option2(id);  
+    }
+    case 8:
+    {
+      Option(id);  
+    }
+    case 9:
+    {
+      Option3(id);  
+    }
+  }
+  return PLUGIN_HANDLED;
+}
+public Option3(id)
+{  
+  new MenuBody[512], len, keys;
+  len = format(MenuBody, 511, "\yOptions Menu 3/3 ^n");
+  
+  if(enable_sound[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r1. \ySounds: \wEnable");
+    keys |= (1<<0);
+  }
+  else
+  {
+    keys |= (1<<0);
+    len += format(MenuBody[len], 511-len, "^n\r1. \ySounds: \dDisable");
+  }
+  if(showjofon[id]==true)
+  {
+    len += format(MenuBody[len], 511-len, "^n\r2. \yShow JumpOff: \wEnable");
+    keys |= (1<<1);
+  }
+  else
+  {
+    keys |= (1<<1);
+    len += format(MenuBody[len], 511-len, "^n\r2. \yShow JumpOff: \dDisable");
+  }
+  if(height_show[id])
+  {
+    len += format(MenuBody[len], 511-len, "^n\r3. \yShow Jump Height: \wEnable");
+    keys |= (1<<2);
+  }
+  else
+  {
+    len += format(MenuBody[len], 511-len, "^n\r3. \yShow Jump Height: \dDisable");
+    keys |= (1<<2);
+  }
+  if(jofon[id])
+  {
+    len += format(MenuBody[len], 511-len, "^n\r4. \yJumpOff Trainer: \wEnable");
+    keys |= (1<<3);
+  }
+  else
+  {
+    len += format(MenuBody[len], 511-len, "^n\r4. \yJumpOff Trainer: \dDisable");
+    keys |= (1<<3);
+  }
+  if(jheight_show[id])
+  {
+    len += format(MenuBody[len], 511-len, "^n\r5. \yJump Height: \wEnable");
+    keys |= (1<<4);
+  }
+  else
+  {
+    len += format(MenuBody[len], 511-len, "^n\r5. \yJump Height: \dDisable");
+    keys |= (1<<4);
+  }
+  if(uq_istrafe)
+  {
+    if(ingame_strafe[id])
+    {
+      len += format(MenuBody[len], 511-len, "^n\r6. \yInGame Strafe Stats: \wEnable");
+      keys |= (1<<5);
+    }
+    else
+    {
+      len += format(MenuBody[len], 511-len, "^n\r6. \yInGame Strafe Stats: \dDisable");
+      keys |= (1<<5);
+    }
+  }
+  else len += format(MenuBody[len], 511-len, "^n\r6. \dInGame Strafe Stats disabled by Server");
+  
+  len += format(MenuBody[len], 511-len, "^n\r7. \yInGame Strafe Stats Showing Time: \w%ds",showtime_st_stats[id]/10);
+  keys |= (1<<6);
+    
+  len += format(MenuBody[len], 511-len, "^n^n\r9. \wBack to the Previous Page");
+  keys |= (1<<8);
+    
+  len += format(MenuBody[len], 511-len, "^n^n\r0. \wExit");
+  keys |= (1<<9);
+  
+  show_menu(id, keys, MenuBody, -1, "StatsOptionMenu3");
+    
+}
+public OptionMenu3(id, key)
+{
+  switch((key+1))
+  {
+    case 1:
+    {
+      enable_sounds(id);
+      Option3(id);  
+    }
+    case 2:
+    {
+      show_jof(id);
+      Option3(id);  
+    }
+    case 3:
+    {
+      heightshow(id);
+      Option3(id);  
+    }
+    case 4:
+    {
+      trainer_jof(id);
+      Option3(id);
+    }
+    case 5:
+    {
+      show_jheight(id);
+      Option3(id);
+    }
+    case 6:
+    {
+      ingame_st_stats(id);
+      Option3(id);
+    }
+    case 7:
+    {
+      if(showtime_st_stats[id]==200)
+      {
+        client_print(id,print_center,"Maximum 20 seconds");
+        showtime_st_stats[id]=0;
+      }
+      showtime_st_stats[id]=showtime_st_stats[id]+10;
+
+      Option3(id);
+    }
+  
+    case 9:
+    {
+      Option2(id);  
+    }
+  }
+  return PLUGIN_HANDLED;
+}
+
+public plugin_end() 
+{ 
+  if(DB_TUPLE)
+    SQL_FreeHandle(DB_TUPLE);
+  if(SqlConnection)
+    SQL_FreeHandle(SqlConnection);
+    
+  TrieDestroy(JumpPlayers);
+}
\ No newline at end of file
diff --git a/amxmodx/scripting/uq_jumpstats_tops.sma b/amxmodx/scripting/uq_jumpstats_tops.sma
new file mode 100644
index 0000000..e486610
--- /dev/null
+++ b/amxmodx/scripting/uq_jumpstats_tops.sma
@@ -0,0 +1,781 @@
+/*
+v2.39 = Borjomi edited
+v1.00 = Переделаны пункты меню, убраны лишние.
+v1.01 = Добавлены Block Top / Weapon Top
+v1.02 = Вырезано, Map top, my top
+v1.03 = Вырезано, все связанное с kz_sql = 0
+v1.04 = Уничтожены все квары
+v1.05 = Координальное переделывание главного меню и побочного (иммитирование 2 страницы), но на самом деле, отдельное меню, нового типа
+v1.06 = Чтобы не писать для каждого пункта меню кнопку, создан отсек default
+v1.07 = Чтобы везде было одинаково, создан Cosy_TypeList в _const.inc
+v1.08 = Все лишние вырезано, все, что возможно, было оптимизировано.
+*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PLUGIN "UQJT"
+#define VERSION "1.10"
+#define AUTHOR "MichaelKheel"
+
+#define NTOP 20 //Num of places in dat tops
+#define NSHOW 9 //Num of places to show in top
+
+new sz_Menu_Weapon[33], bool:sz_Menu_Block[33];
+new Trie:JumpData,Trie:JumpData_Block;
+new bool:loading_tops[33];
+new sv_airaccelerate;
+
+new Cosy_TypeList[24][] = {
+	"lj",
+	"cj",
+	"dcj",
+	"mcj",
+	"bj",
+	"sbj",
+	"wj",
+	"bhopinduck",
+	"ladder",
+	"ldbhop",
+	"realldbhop",
+	"scj",
+	"dscj",
+	"mscj",
+	"dropcj",
+	"dropdcj",
+	"dropmcj",
+	"dropbj",
+	"dropscj",
+	"dropdscj",
+	"dropmscj",
+	"upbj",
+	"upsbj",
+	"upbhopinduck"
+};
+
+public plugin_init()
+{
+	register_plugin(PLUGIN, VERSION, AUTHOR);
+
+	register_menucmd(register_menuid("StatsTopMenu1"), 1023, "TopMenu1");
+	register_clcmd( "say /ljtop",	"LjTopMenu" );
+
+	sv_airaccelerate = get_cvar_pointer("sv_airaccelerate");
+	set_task(0.3, "stats_sql");
+}
+
+public plugin_cfg()
+{
+	JumpData = TrieCreate();
+	JumpData_Block = TrieCreate();
+}
+
+public client_connect(id)
+{
+	loading_tops[id]=false;
+}
+
+public read_tops(id, type[], type_num, show_mode, wpn_rank, bool:block)
+{
+	new sql_query[512],cData[25];
+	formatex(cData,17,type);
+	cData[19]=id;
+	cData[20]=show_mode;
+
+	if(weapon_maxspeed(wpn_rank) == 250)
+		cData[21]=0;
+	else
+		cData[21]=1;
+
+	cData[22]=weapon_maxspeed(wpn_rank);
+	
+	if(block)
+		cData[23]=1;
+	else
+		cData[23]=0;
+
+	formatex(sql_query, 511, "SELECT pid FROM `%s%s` WHERE type='%s' and pspeed=%d LIMIT 10", block ? "uq_block_tops" : "uq_jumps", get_pcvar_num(sv_airaccelerate) == 100 ? "_100aa" : "", type, weapon_maxspeed(wpn_rank));
+	SQL_ThreadQuery(DB_TUPLE,"QueryHandle_type_place", sql_query, cData, 24);
+}
+
+public QueryHandle_type_place(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime)
+{
+	
+	if(iFailState != TQUERY_SUCCESS)
+	{
+		log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError);
+		return PLUGIN_HANDLED;
+	}
+	
+	new id=cData[19];
+	new mode=cData[20];
+	new pspeed=cData[22];
+	new block=cData[23];
+	
+	formatex(cData,17,cData);
+	
+	new i=0;
+	while(SQL_MoreResults(hQuery))
+	{
+		i++;
+		SQL_NextRow(hQuery);
+	}
+	
+	SQL_FreeHandle(hQuery);
+	
+	new sql_query[512],bData[26];
+	formatex(bData,17,cData);
+	bData[19]=id;
+	bData[20]=i;
+	bData[21]=mode;
+	bData[23]=pspeed;
+	if(block)
+		bData[24]=1;
+	else
+		bData[24]=0;
+	
+	set_hudmessage(255, 0, 109, 0.05, 0.5, 0, 6.0, 0.3);
+	show_hudmessage(id, "Loading %s %s for Weapon with maxspeed: %d - 0%%", cData, block ? "Block Top" : "Top", pspeed);
+	
+	formatex(sql_query, 511, "SELECT * FROM %s%s WHERE type='%s' and pspeed=%d ORDER BY %sdistance DESC LIMIT 10", block ? "uq_block_tops" : "uq_jumps", get_pcvar_num(sv_airaccelerate) == 100 ? "_100aa" : "", cData,pspeed, block ? "block DESC," : "", NSHOW);
+	SQL_ThreadQuery(DB_TUPLE,"QueryHandle_LoadTops", sql_query, bData, 25);
+	
+	return PLUGIN_CONTINUE;
+}
+
+public QueryHandle_LoadTops(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime)
+{
+	if(iFailState != TQUERY_SUCCESS)
+	{
+		log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError);
+		return PLUGIN_HANDLED;
+	}
+	
+	new id=cData[19];
+	new max_place=cData[20];
+	new mode=cData[21];
+	new pspeed=cData[23];
+	new block_bool=cData[24];
+	
+	formatex(cData,17,cData);
+	
+	new t_pspeed[NSHOW+1],pid[NSHOW+1], distance[NSHOW+1], maxspeed[NSHOW+1], prestrafe[NSHOW+1], strafes[NSHOW+1], sync[NSHOW+1], ddbh[NSHOW+1],wpn[NSHOW+1][15], jumpoff[NSHOW+1], block[NSHOW+1];
+	new tmp_type;
+	
+	for(new i = 0; i < 24 ;i++)
+	{
+		if(equali(cData,Cosy_TypeList[i]))
+		{
+			tmp_type=i;
+		}
+	}
+
+	new i=0;
+	while(SQL_MoreResults(hQuery))
+	{
+		pid[i] = SQL_ReadResult(hQuery,0);
+		distance[i] = SQL_ReadResult(hQuery,2);
+		if(block_bool == 0)
+		{
+			maxspeed[i] = SQL_ReadResult(hQuery,3);
+			prestrafe[i] = SQL_ReadResult(hQuery,4);
+			strafes[i] = SQL_ReadResult(hQuery,5);
+			sync[i] = SQL_ReadResult(hQuery,6);
+			ddbh[i] = SQL_ReadResult(hQuery,7);
+			t_pspeed[i] = SQL_ReadResult(hQuery,8);
+			SQL_ReadResult(hQuery,9,wpn[i],24);
+			pid_in_name(mode,max_place,i,id,cData,t_pspeed[i],tmp_type,pid[i], distance[i], maxspeed[i], prestrafe[i], strafes[i], sync[i], ddbh[i],wpn[i]);
+		}
+		else
+		{
+			jumpoff[i] = SQL_ReadResult(hQuery,3);
+			block[i] = SQL_ReadResult(hQuery,4);
+			t_pspeed[i] = SQL_ReadResult(hQuery,5);
+			SQL_ReadResult(hQuery,6,wpn[i],24);
+			pid_in_name_block(mode,max_place,i,id,cData,t_pspeed[i],tmp_type,pid[i], distance[i], jumpoff[i], block[i],wpn[i]);
+		}
+		i++;
+		SQL_NextRow(hQuery);
+	}
+	
+	if(i==0)
+	{
+		if(block_bool == 0)
+			tmp_show_tops_weapon(id,cData,tmp_type,weapon_rank(pspeed));
+		else
+			show_tops_block_weapon_tmp(id,cData,tmp_type, weapon_rank(pspeed));
+
+		switch(mode)
+		{
+			case 0:
+				uqTopmenu1(id,weapon_rank(pspeed), sz_Menu_Block[id]);
+			case 1:
+				uqTopmenu2(id,weapon_rank(pspeed), sz_Menu_Block[id]);
+		}
+		loading_tops[id]=false;	
+	}
+	SQL_FreeHandle(hQuery);
+		
+	return PLUGIN_CONTINUE;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MENU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+public LjTopMenu(id)
+{
+	uqTopmenu1(id, 0, false);
+}
+
+public uqTopmenu1(id, weapon, bool:block)
+{
+	if(weapon > 0)
+		sz_Menu_Weapon[id] = weapon;
+	else
+		sz_Menu_Weapon[id] = 0;
+
+	if(block)
+		sz_Menu_Block[id] = true;
+	else
+		sz_Menu_Block[id] = false;
+
+	new MenuBody[512], len, keys;
+
+	len = format(MenuBody, 511, "\yLongJump Stats ^n");
+	len += format(MenuBody[len], 511, "\dType \w/ljsmenu \dto see option menu^n");
+
+	len += format(MenuBody[len], 511-len, "^n\d[\r1\d]\w \wLongJump Top");
+	keys |= (1<<0);
+	len += format(MenuBody[len], 511-len, "^n\d[\r2\d]\w \wCountJump Top");
+	keys |= (1<<1);
+	len += format(MenuBody[len], 511-len, "^n\d[\r3\d]\w \wDouble CountJump Top");
+	keys |= (1<<2);	
+	len += format(MenuBody[len], 511-len, "^n\d[\r4\d]\w \wMulti CountJump Top");
+	keys |= (1<<3);		
+	len += format(MenuBody[len], 511-len, "^n\d[\r5\d]\w \wBhopJump Top");
+	keys |= (1<<4);
+	len += format(MenuBody[len], 511-len, "^n\d[\r6\d]\w \wStandUp BhopJump Top");
+	keys |= (1<<5);
+	if(block)
+		len += format(MenuBody[len], 511-len, "^n^n\d[\r7\d]\w \rBlock ON");
+	else
+		len += format(MenuBody[len], 511-len, "^n^n\d[\r7\d]\w \yBlock OFF");
+	keys |= (1<<6);
+	if(weapon > 0)
+		len += format(MenuBody[len], 511-len, "^n\d[\r8\d]\w \rWeapon %d", weapon_maxspeed(sz_Menu_Weapon[id]));
+	else
+		len += format(MenuBody[len], 511-len, "^n\d[\r8\d]\w \yWeapon Top");
+	keys |= (1<<7);
+	len += format(MenuBody[len], 511-len, "^n^n\d[\r9\d]\w \wNext Page");
+	keys |= (1<<8);
+	len += format(MenuBody[len], 511-len, "^n^n\d[\r0\d]\w \wExit");
+	keys |= (1<<9);
+	show_menu(id, keys, MenuBody, -1, "StatsTopMenu1");		
+
+	return PLUGIN_HANDLED;
+}
+public TopMenu1(id, key)
+{
+	switch((key+1))
+	{
+		case 7:
+		{
+			if(sz_Menu_Block[id])
+				uqTopmenu1(id, sz_Menu_Weapon[id], false);
+			else
+				uqTopmenu1(id, sz_Menu_Weapon[id], true);
+		}
+		case 8:
+		{
+			uqMainWpnMenu(id);
+		}
+		case 9:
+		{
+			uqTopmenu2(id, sz_Menu_Weapon[id], sz_Menu_Block[id]); // next page
+		}
+		case 10:
+		{
+			return PLUGIN_HANDLED;
+		}
+		default:
+		{
+			read_tops(id,Cosy_TypeList[key], key, 0, sz_Menu_Weapon[id], sz_Menu_Block[id]);
+		}
+	}
+	return PLUGIN_HANDLED;
+}
+
+public uqTopmenu2(id, weapon, bool:block)
+{
+	if(weapon > 0)
+		sz_Menu_Weapon[id] = weapon;
+	else
+		sz_Menu_Weapon[id] = 0;
+
+	if(block)
+		sz_Menu_Block[id] = true;
+	else
+		sz_Menu_Block[id] = false;
+
+	new txt[64];
+	formatex(txt, 63, "Weapon: \r%d\w^nBlock: \r%s\w^n^nLongJump Stats ->", weapon_maxspeed(sz_Menu_Weapon[id]), sz_Menu_Block[id] ? "True" : "False");
+	new menu = menu_create(txt, "uqTopmenu2Handler");
+	
+
+	menu_additem( menu, "WeirdJump Top", "1" );
+	menu_additem( menu, "Bhop In Duck Top", "2");
+	menu_additem( menu, "LadderJump Top", "3" );
+	menu_additem( menu, "Ladder BhopJump Top", "4" );
+	menu_additem( menu, "Real Ladder Bhop Top", "5" );
+	menu_additem( menu, "StandUp CountJump Top", "6" );
+	menu_additem( menu, "Double StandUp CountJump Top", "7" );
+	menu_additem( menu, "Multi StandUp CountJump Top", "8");
+	menu_additem( menu, "Drop CountJump Top", "10" );
+	menu_additem( menu, "Double Drop CountJump Top", "11");
+	menu_additem( menu, "Multi Drop CountJump Top", "12");
+	menu_additem( menu, "Drop BhopJump Top", "13" );
+	menu_additem( menu, "Drop StandUp CountJump Top", "14");
+	menu_additem( menu, "Drop Double StandUp CountJump Top", "15");
+	menu_additem( menu, "Drop Multi StandUp CountJump Top", "16");
+	menu_additem( menu, "Up Bhop Top", "17");
+	menu_additem( menu, "Up StandBhop Top", "18");
+	menu_additem( menu, "Up Bhop In Duck Top", "19");
+
+	menu_setprop(menu, MPROP_NEXTNAME, "Next");
+	menu_setprop(menu, MPROP_BACKNAME, "Back");
+	menu_setprop(menu, MPROP_EXITNAME, "Exit");
+
+	menu_display(id, menu, 0);
+}
+
+public uqTopmenu2Handler(id, menu, item)
+{
+	if( item == MENU_EXIT )
+	{
+		uqTopmenu1(id, sz_Menu_Weapon[id], sz_Menu_Block[id]);
+		return PLUGIN_HANDLED;
+	}
+	switch(item)
+	{
+		default: 
+		{
+			read_tops(id,Cosy_TypeList[item+6], item+6, 1, sz_Menu_Weapon[id], sz_Menu_Block[id]);
+		} 
+	}
+	return PLUGIN_HANDLED;
+}
+
+public uqMainWpnMenu(id)
+{
+	new menu = menu_create("\yStats Top Menu\w", "uqMainWpnMenuHandler");
+	
+	menu_additem( menu, "Weapon maxspeed - 250", "1" );
+	menu_additem( menu, "Weapon maxspeed - 210", "2" );
+	menu_additem( menu, "Weapon maxspeed - 220", "3" );
+	menu_additem( menu, "Weapon maxspeed - 221", "4" );
+	menu_additem( menu, "Weapon maxspeed - 230", "5" );
+	menu_additem( menu, "Weapon maxspeed - 235", "6" );
+	menu_additem( menu, "Weapon maxspeed - 240", "7" );
+	menu_additem( menu, "Weapon maxspeed - 245", "8" );
+
+	menu_setprop(menu, MPROP_PERPAGE, 0);
+	menu_display(id, menu, 0);
+}
+
+public uqMainWpnMenuHandler(id, menu, item)
+{
+	if( item == MENU_EXIT )
+	{
+		return PLUGIN_HANDLED;
+	}
+
+	switch(item)
+	{
+		default:	
+		{
+			uqTopmenu1(id, item, sz_Menu_Block[id]);
+		}
+	}
+	return PLUGIN_HANDLED;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Подсчет людей ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+public pid_in_name(mode,max_place,num,id,type[],pspeed,type_num,pid, distance, maxspeed, prestrafe, strafes, sync, ddbh,wpn[])
+{
+	new sql_query[512],cData[44];
+	formatex(cData,17,type);	
+	cData[18]=id;
+	cData[19]=num;
+	cData[20]=pspeed;
+	cData[21]=type_num;
+	cData[22]=distance;
+	cData[23]=maxspeed;
+	cData[24]=prestrafe;
+	cData[25]=strafes;
+	cData[26]=sync;
+	cData[27]=ddbh;
+	cData[28]=max_place;
+	cData[29]=mode;
+	
+	for(new i=0;i<14;i++)
+	{
+		formatex(cData[30+i],1,wpn[i]);		
+	}
+	
+	formatex(sql_query, 511, "SELECT name FROM uq_players WHERE id=%d",pid);
+	SQL_ThreadQuery(DB_TUPLE,"QueryHandle_pidName", sql_query, cData, 45);
+	
+}
+public QueryHandle_pidName(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime)
+{
+	if(iFailState != TQUERY_SUCCESS)
+	{
+		log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError);
+		return PLUGIN_HANDLED;
+	}
+	
+	new mode,num,type[18],id,type_num,pspeed,max_place,wpn[14];
+	new name[33],distance, maxspeed, prestrafe, strafes, sync, ddbh;
+
+	formatex(type,17,cData);
+	type_num=cData[21];
+	pspeed=cData[20];
+	num=cData[19];
+	id=cData[18];
+	distance=cData[22];
+	maxspeed=cData[23];
+	prestrafe=cData[24];
+	strafes=cData[25];
+	sync=cData[26];
+	ddbh=cData[27];
+	max_place=cData[28];
+	mode=cData[29];
+	new block;
+	for(new i=0;i<14;i++)
+	{
+		formatex(wpn[i],1,cData[30+i]);
+	}
+	
+	if (!SQL_NumResults(hQuery))
+	{
+		log_amx("Bug with id=0");
+		
+		name="unknow";
+	}
+	else
+	{
+		SQL_ReadResult(hQuery,0,name,33);
+	}
+
+	new Trie:JumpStat;
+	JumpStat = TrieCreate();
+	
+	TrieSetString(JumpStat, "name", name);
+	TrieSetCell(JumpStat, "distance", distance);
+	TrieSetCell(JumpStat, "maxspeed", maxspeed);
+	TrieSetCell(JumpStat, "prestrafe", prestrafe);
+	TrieSetCell(JumpStat, "strafes", strafes);
+	TrieSetCell(JumpStat, "sync", sync);
+	TrieSetCell(JumpStat, "ddbh", ddbh);
+	TrieSetCell(JumpStat, "pspeed", pspeed);
+	TrieSetString(JumpStat, "wpn", wpn);
+	
+	new tmp_type[33];
+	formatex(tmp_type,32,"%s_%d_%d",type,num,pspeed);
+	
+	TrieSetCell(JumpData, tmp_type, JumpStat);
+	
+	SQL_FreeHandle(hQuery);
+	
+	if(num==max_place-1) 
+	{
+		tmp_show_tops_weapon(id,type,type_num,weapon_rank(pspeed));
+		switch(mode)
+		{
+			case 0:
+				uqTopmenu1(id, weapon_rank(pspeed), sz_Menu_Block[id]);
+			case 1:
+				uqTopmenu2(id, weapon_rank(pspeed), sz_Menu_Block[id]);
+		}
+		loading_tops[id]=false;
+	}
+	else
+	{
+		new load=100/max_place;
+		
+		set_hudmessage(255, 0, 109, 0.05, 0.5, 0, 6.0, 0.3);
+		show_hudmessage(id, "Loading %s %s for Weapon with maxspeed: %d - %d%%", cData, block ? "Block Top" : "Top", pspeed, (num+2)*load);
+	}
+	
+	return PLUGIN_CONTINUE;
+}
+
+public pid_in_name_block(mode,max_place,num,id,type[],pspeed,type_num,pid, distance, jumpoff, block,wpn[])
+{
+	new sql_query[512],cData[44];
+	formatex(cData,17,type);	
+	cData[18]=id;
+	cData[19]=num;
+	cData[20]=pspeed;
+	cData[21]=type_num;
+	cData[22]=distance;
+	cData[23]=jumpoff;
+	cData[24]=block;
+	cData[25]=max_place;
+	cData[26]=mode;
+	
+	for(new i=0;i<14;i++)
+	{
+		formatex(cData[27+i],1,wpn[i]);
+	}
+	
+	formatex(sql_query, 511, "SELECT name FROM uq_players WHERE id=%d",pid);
+	SQL_ThreadQuery(DB_TUPLE,"QueryHandle_pidName_block", sql_query, cData, 45);
+	
+}
+public QueryHandle_pidName_block(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime)
+{
+	if(iFailState != TQUERY_SUCCESS)
+	{
+		log_amx("uq_jumpstats: SQL Error #%d - %s", iErrnum, szError);
+		return PLUGIN_HANDLED;
+	}
+	
+	new block,mode,num,type[18],id,type_num,pspeed,max_place,wpn[14];
+	new name[33],distance, Float:jumpoff;
+
+	formatex(type,17,cData);
+	type_num=cData[21];
+	pspeed=cData[20];
+	num=cData[19];
+	id=cData[18];
+	distance=cData[22];
+	jumpoff=cData[23]/1000000.0;
+	block=cData[24];
+	max_place=cData[25];
+	mode=cData[26];
+	
+	for(new i=0;i<14;i++)
+	{
+		formatex(wpn[i],1,cData[27+i]);
+	}
+	
+	SQL_ReadResult(hQuery,0,name,33);
+	
+	new Trie:JumpStat;
+	JumpStat = TrieCreate();
+	
+	TrieSetString(JumpStat, "name", name);
+	TrieSetCell(JumpStat, "distance", distance);
+	TrieSetCell(JumpStat, "jumpoff", jumpoff);
+	TrieSetCell(JumpStat, "block", block);
+	TrieSetCell(JumpStat, "pspeed", pspeed);
+	TrieSetString(JumpStat, "wpn", wpn);
+	
+	new tmp_type[33];
+	formatex(tmp_type,32,"block_%s_%d_%d",type,num,pspeed);
+	
+	TrieSetCell(JumpData_Block, tmp_type, JumpStat);
+	
+	SQL_FreeHandle(hQuery);
+	
+	if(num==max_place-1) 
+	{
+		show_tops_block_weapon_tmp(id,type,type_num,weapon_rank(pspeed));
+		switch(mode)
+		{
+			case 0:
+				uqTopmenu1(id,weapon_rank(pspeed), sz_Menu_Block[id]);
+			case 1:
+				uqTopmenu2(id,weapon_rank(pspeed), sz_Menu_Block[id]);
+		}
+		loading_tops[id]=false;
+	}
+	else
+	{
+		new load=100/max_place;
+		set_hudmessage(255, 0, 109, 0.05, 0.5, 0, 6.0, 0.3);
+		show_hudmessage(id, "Loading %s BlockTop for Weapon with maxspeed: %d - %d%%",type,pspeed,(num+2)*load);
+	}
+		
+	return PLUGIN_CONTINUE;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MOTD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+public show_tops_block_weapon_tmp(id,type[],type_num,wpn_rank)
+{	
+	static buffer[2368], name[128], len, i;
+	new oldblock,Float:find_jumpoff[NTOP+1];
+	
+	new tmp_oldtype[33];
+	new Trie:JS_old, block_for_old;
+	
+	for( i = 0; i < NSHOW; i++ )
+	{
+		format(tmp_oldtype, 32, "block_%s_%d_%d", type,i,weapon_maxspeed(wpn_rank));
+			
+		if(TrieKeyExists(JumpData_Block, tmp_oldtype))
+		{	
+			TrieGetCell(JumpData_Block, tmp_oldtype, JS_old);
+			
+			if(i==0) TrieGetCell(JS_old, "block", block_for_old);
+			
+			TrieGetCell(JS_old, "jumpoff", find_jumpoff[i]);
+		}
+	}
+	
+	new Float:minjof=find_min_jumpoff(find_jumpoff);
+	oldblock=block_for_old;
+	
+	len = format(buffer[len], 2367-len,"");
+	len += format(buffer[len], 2367-len, "");
+			
+			if((jj%2)==0)
+			{
+				jj=oldjj;
+			}
+		}
+		if( block == 0)
+		{
+			len += format(buffer[len], 2367-len, "
# Name Block Distance Jumpoff Weapon"); + + new oldjj,jj; + for( i = 0,jj=1; i < NSHOW; i++ ) + { + new Trie:JS; + new tmp_names[33],tmp_weap_names[33],distance,Float:jumpoff,block; + new tmp_type[33]; + + format(tmp_type, 32, "block_%s_%d_%d", type, i,weapon_maxspeed(wpn_rank)); + + if(TrieKeyExists(JumpData_Block, tmp_type)) + { + TrieGetCell(JumpData_Block, tmp_type, JS); + + TrieGetCell(JS, "distance", distance); + TrieGetCell(JS, "jumpoff", jumpoff); + TrieGetCell(JS, "block", block); + TrieGetString(JS,"name",tmp_names,32); + TrieGetString(JS,"wpn",tmp_weap_names,32); + } + + if(oldblock!=block) + { + len += format(buffer[len], 2367-len, "

%d %s %s %s %s %s", ((i%2)==0) ? "" : " bgcolor=#2f3030", (i+1), "-", "-", "-", "-", "-"); + i=NSHOW; + } + else + { + name = tmp_names; + while( containi(name, "<") != -1 ) + replace(name, 127, "<", "<"); + while( containi(name, ">") != -1 ) + replace(name, 127, ">", ">"); + if(minjof==jumpoff) + { + len += format(buffer[len], 2367-len, "
%d %s %d %d.%01d %f %s", ((jj%2)==0) ? "" : " bgcolor=#2f3030", (i+1), name,block, (distance/1000000), (distance%1000000/100000), jumpoff,tmp_weap_names); + } + else len += format(buffer[len], 2367-len, "
%d %s %d %d.%01d %0.4f %s", ((jj%2)==0) ? "" : " bgcolor=#2f3030", (i+1), name,block, (distance/1000000), (distance%1000000/100000), jumpoff,tmp_weap_names); + } + + oldblock=block; + oldjj=jj; + jj++; + } + len += format(buffer[len], 2367-len, "
"); + static strin[34]; + + if(type_num==9) + { + format(strin,33, "Block Top %d hj (maxspeed - %d)",NSHOW,weapon_maxspeed(wpn_rank)); + } + else format(strin,33, "Block Top %d %s (maxspeed - %d)", NSHOW,type,weapon_maxspeed(wpn_rank)); + + show_motd(id, buffer, strin); +} + +public tmp_show_tops_weapon(id,type[],type_num,wpn_rank) +{ + static buffer[2368], name[128], len, i; + + len = format(buffer[len], 2367-len,""); + len += format(buffer[len], 2367-len, "
# Name Distance MaxSpeed PreStrafe Strafes Sync Weapon"); + + for( i = 0; i < (NSHOW); i++ ) + { + new Trie:JS; + new tmp_names[33],tmp_weap_names[33],distance,maxspeed,prestrafe,strafes,sync; + new tmp_type[33]; + + format(tmp_type, 32, "%s_%d_%d", type, i,weapon_maxspeed(wpn_rank)); + + if(TrieKeyExists(JumpData, tmp_type)) + { + TrieGetCell(JumpData, tmp_type, JS); + + TrieGetCell(JS, "distance", distance); + TrieGetCell(JS, "maxspeed", maxspeed); + TrieGetCell(JS, "prestrafe", prestrafe); + TrieGetCell(JS, "strafes", strafes); + TrieGetCell(JS, "sync", sync); + TrieGetString(JS,"name",tmp_names,32); + TrieGetString(JS,"wpn",tmp_weap_names,32); + //TrieGetCell(JS, "ddbh", ddbh); + } + + + if( distance == 0) + { + len += format(buffer[len], 2367-len, "
%d %s %s %s %s %s %s %s", ((i%2)==0) ? "" : " bgcolor=#2f3030", (i+1), "-", "-", "-", "-", "-", "-", "-"); + i=NSHOW; + } + else + { + name = tmp_names; + while( containi(name, "<") != -1 ) + replace(name, 127, "<", "<"); + while( containi(name, ">") != -1 ) + replace(name, 127, ">", ">"); + + len += format(buffer[len], 2367-len, "
%d %s %d.%01d %d.%01d %d.%01d %d %d %s", ((i%2)==0) ? "" : " bgcolor=#2f3030", (i+1), name,(distance/1000000), (distance%1000000/100000), (maxspeed/1000000), (maxspeed%1000000/100000), (prestrafe/1000000), (prestrafe%1000000/100000), strafes,sync,tmp_weap_names); + } + } + len += format(buffer[len], 2367-len, "
"); + + static strin[64]; + format(strin,63, "Top %d %s (maxspeed - %d)",NSHOW,Cosy_TypeList[type_num],weapon_maxspeed(wpn_rank)); + + show_motd(id, buffer, strin); +} + +public Float:find_min_jumpoff(Float:TmpArray[NTOP+1]) +{ + new num_min; + num_min=0; + for (new i = 0; i < NSHOW; i++) + { + if(TmpArray[num_min]>TmpArray[i] && TmpArray[i]!=0.0) + { + num_min=i; + } + } + return TmpArray[num_min]; +} + +public plugin_end() +{ + if(DB_TUPLE) + SQL_FreeHandle(DB_TUPLE); + if(SqlConnection) + SQL_FreeHandle(SqlConnection); +} \ No newline at end of file diff --git a/metamod/dlls/amxxarch_amxx_i386.so b/metamod/dlls/amxxarch_amxx_i386.so new file mode 100644 index 0000000..c389cd7 Binary files /dev/null and b/metamod/dlls/amxxarch_amxx_i386.so differ diff --git a/metamod/dlls/config.ini b/metamod/dlls/config.ini new file mode 100644 index 0000000..24d6780 --- /dev/null +++ b/metamod/dlls/config.ini @@ -0,0 +1,74 @@ +// vim: set ft=c : +// +// Format is as follows: +// +// +// Fields are whitespace delimited (tabs/spaces). +// +// Comments are either c++ style ("//") or unix shell style ("#"), and +// can appear ONLY at the beginning of a line. +// +// The following provide a list of recognized options, their defaults, and +// examples of usage. +// +// debuglevel +// gamedll +// exec_cfg +// clientmeta +// dynalign_list + + +// debuglevel +// where is an integer, 0 and up. +// Sets the initial debugging level for metamod (same as cvar "meta_debug"). +// Default is normally 0. If hlds is run with "-dev", default is 3. +// Overridden by: +localinfo mm_debug +// Examples: +// +// debuglevel 0 +// debuglevel 42 +debuglevel 0 + +// gamedll +// where is an absolute path, or a path relative to the gamedir. +// Overrides the auto-detected gamedll, in particular for bots. +// Default is empty, with gamedll being auto-recognized based on the +// gamedir. +// Overridden by: +localinfo mm_gamedll +// Examples: +// +// gamedll dlls/hl.dll +// gamedll ../podbot/podbot.dll +// gamedll /home/bots/dlls/mybot.dll + + +// exec_cfg +// where is a path relative to the gamedir. Note! This CANNOT be +// an absolute path, as hlds will not "exec" absolute pathnames. +// Overrides the default filename containing hlds commands to run just +// after loading Metamod. +// Default is "addons/metamod/exec.cfg". +// Overridden by: +localinfo mm_execcfg +// Examples: +// +// exec_cfg configs/debugging.cfg +// exec_cfg ../clan/match.cfg + + +// clientmeta +// Setting to disable or enable Metamod's client commands ('meta list' and +// 'meta version') +// Extra setting for Metamod+All-Mod-Support Patch. +// Default is "yes". +// Overridden by: +localinfo mm_clientmeta +// Examples: +// +// clientmeta yes +// clientmeta no +clientmeta no + + +// dynalign_list +// Setting to disable or enable plugins list dynamic alignment into output +// NOTE: This option affect's on incorrect parse from HLSW on Tab 'Metamod Plugins' +dynalign_list yes diff --git a/metamod/dlls/metamod.so b/metamod/dlls/metamod.so new file mode 100644 index 0000000..06055c3 Binary files /dev/null and b/metamod/dlls/metamod.so differ diff --git a/metamod/plugins.ini b/metamod/plugins.ini new file mode 100644 index 0000000..7a1a7dd --- /dev/null +++ b/metamod/plugins.ini @@ -0,0 +1,3 @@ +linux addons/soloader/libsoloader_i386.so +linux addons/metamod/dlls/amxxarch_amxx_i386.so +linux addons/amxmodx/dlls/amxmodx_mm_i386.so diff --git a/soloader/libraries.cfg b/soloader/libraries.cfg new file mode 100644 index 0000000..f0d6c57 --- /dev/null +++ b/soloader/libraries.cfg @@ -0,0 +1,3 @@ +libcurl.so.4.7.0 +libcrypto.so.1.1 +libssl.so.1.1 diff --git a/soloader/libraries/libcrypto.so.1.1 b/soloader/libraries/libcrypto.so.1.1 new file mode 100755 index 0000000..817f43b Binary files /dev/null and b/soloader/libraries/libcrypto.so.1.1 differ diff --git a/soloader/libraries/libcurl.so.4.7.0 b/soloader/libraries/libcurl.so.4.7.0 new file mode 100755 index 0000000..bfea6e3 Binary files /dev/null and b/soloader/libraries/libcurl.so.4.7.0 differ diff --git a/soloader/libraries/libssl.so.1.1 b/soloader/libraries/libssl.so.1.1 new file mode 100755 index 0000000..5046079 Binary files /dev/null and b/soloader/libraries/libssl.so.1.1 differ diff --git a/soloader/libsoloader_i386.so b/soloader/libsoloader_i386.so new file mode 100644 index 0000000..8ad49ca Binary files /dev/null and b/soloader/libsoloader_i386.so differ