diff --git a/.gitignore b/.gitignore index 805c783a4..5698779e8 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ x64/ x86/ log/ logs/ +vcpkg/ + +.idea/* \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 9eda6fca6..faed5b846 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,32 +1,27 @@ language: cpp compiler: gcc -sudo: false -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - - libmysqlclient-dev - - libperl-dev - - libboost-dev - - liblua5.1-0-dev - - zlib1g-dev - - uuid-dev - - libssl-dev +dist: trusty + +before_install: + - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + - sudo apt-get update -qq + - mkdir $HOME/usr + - export PATH="$HOME/usr/bin:$PATH" + - wget https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.sh + - chmod +x cmake-3.11.2-Linux-x86_64.sh + - ./cmake-3.11.2-Linux-x86_64.sh --prefix=$HOME/usr --exclude-subdir --skip-license + install: - - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi + - sudo apt-get install -qq g++-7 + - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90 + - sudo apt-get install libmysqlclient-dev + - sudo apt-get install libperl-dev + - sudo apt-get install libboost-dev + - sudo apt-get install liblua5.1-0-dev + - sudo apt-get install zlib1g-dev + - sudo apt-get install uuid-dev + - sudo apt-get install libssl-dev script: - cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON - make -j2 - ./bin/tests -branches: - only: - - master - - stable -notifications: - email: false - irc: - channels: "irc.eqemulator.net#eqemucoders" -os: linux \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ce1a3bc9b..817af542c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,6 @@ #EQEMU_USE_MAP_MMFS #EQEMU_MAP_DIR -#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones -#Can change this if you really want but you should upgrade! CMAKE_MINIMUM_REQUIRED(VERSION 2.8) #FindMySQL is located here so lets make it so CMake can find it @@ -42,6 +40,8 @@ IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) +SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}") + #Add our various windows definitions IF(MSVC OR MINGW) ADD_DEFINITIONS(-D_WINDOWS) @@ -53,7 +53,6 @@ IF(MSVC OR MINGW) ENDIF(MSVC OR MINGW) IF(MSVC) - #Set our default locations for zlib/mysql based on x86/x64 IF(CMAKE_CL_64) SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x64") SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x64") @@ -100,23 +99,6 @@ IF(MSVC) ADD_DEFINITIONS(-DCRASH_LOGGING) ENDIF(EQEMU_ENABLE_CRASH_LOGGING) - #Disable safe SEH or not? - OPTION(EQEMU_DISABLE_SAFESEH "Disable Safe SEH (Needed for Strawberry Perl)" OFF) - IF(EQEMU_DISABLE_SAFESEH) - SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO") - SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO") - SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /SAFESEH:NO") - SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO") - SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /SAFESEH:NO") - SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO") - SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /SAFESEH:NO") - SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO") - SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /SAFESEH:NO") - SET(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO") - SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /SAFESEH:NO") - SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO") - ENDIF(EQEMU_DISABLE_SAFESEH) - OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON) IF(EQEMU_BUILD_MSVC_MP) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") @@ -309,7 +291,7 @@ IF(EQEMU_BUILD_PERL) INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}") ENDIF(EQEMU_BUILD_PERL) -SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt) +SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt recast_navigation) FIND_PACKAGE(Sodium REQUIRED) IF(SODIUM_FOUND) @@ -342,7 +324,7 @@ IF(EQEMU_BUILD_LUA) FIND_PACKAGE(Boost REQUIRED) INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}") - INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/luabind") + INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind") OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON) IF(EQEMU_SANITIZE_LUA_LIBS) @@ -357,6 +339,8 @@ INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/cereal") INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/include" ) INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/src") INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/format") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/recast/detour/include") +INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/recast/recast/include") IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC) ADD_SUBDIRECTORY(common) diff --git a/LICENSE b/LICENSE index 65c5ca88a..f288702d2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,165 +1,674 @@ - GNU LESSER GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + 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 - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. - 0. Additional Definitions. + 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. - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. + 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. - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. + 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. - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. + 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. - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". + 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. - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. + 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. - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. + 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. - 1. Exception to Section 3 of the GNU GPL. + 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. - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. + The precise terms and conditions for copying, distribution and +modification follow. - 2. Conveying Modified Versions. + TERMS AND CONDITIONS - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: + 0. Definitions. - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or + "This License" refers to version 3 of the GNU General Public License. - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. - 3. Object Code Incorporating Material from Library Header Files. + "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. - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: + 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) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. + A "covered work" means either the unmodified Program or a work based +on the Program. - b) Accompany the object code with a copy of the GNU GPL and this license - document. + 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. - 4. Combined Works. + 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. - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: + 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. - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. + 1. Source Code. - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. + 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. - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. + 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. - d) Do one of the following: + 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. - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. + 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. - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) + The Corresponding Source for a work in source code form is that +same work. - 5. Combined Libraries. + 2. Basic Permissions. - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: + 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. - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. + 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. - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. - 6. Revised Versions of the GNU Lesser General Public License. + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser 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. + 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. - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. + 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. - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. + 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/README.md b/README.md index 47b835788..e1126241c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # EQEmulator Core Server -|Travis CI (Linux)|Appveyor (Windows) | -|:---:|:---:| -|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) | +|Travis CI (Linux)|Appveyor w/ Bots (Windows) |Appveyor w/o Bots (Windows) | +|:---:|:---:|:---:| +|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Build status](https://ci.appveyor.com/api/projects/status/scr25kmntx36c1ub/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[![Build status](https://ci.appveyor.com/api/projects/status/mdwbr4o9l6mxqofj/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server-w0pq2/branch/master) | *** diff --git a/appveyor-bots.yml b/appveyor-bots.yml new file mode 100644 index 000000000..9edb00593 --- /dev/null +++ b/appveyor-bots.yml @@ -0,0 +1,21 @@ +version: 1.0.{build} +branches: + only: + - master +image: Visual Studio 2017 +configuration: RelWithDebInfo +clone_folder: c:\projects\eqemu +init: +- ps: git config --global core.autocrlf input +cache: c:\tools\vcpkg\installed\ +before_build: +- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .." +build: + project: C:\projects\eqemu\build\EQEmu.sln + parallel: true + verbosity: minimal +after_build: +- cmd: >- + 7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb + + appveyor PushArtifact build_x64-bots.zip \ No newline at end of file diff --git a/appveyor-no-bots.yml b/appveyor-no-bots.yml new file mode 100644 index 000000000..7aea00332 --- /dev/null +++ b/appveyor-no-bots.yml @@ -0,0 +1,21 @@ +version: 1.0.{build} +branches: + only: + - master +image: Visual Studio 2017 +configuration: RelWithDebInfo +clone_folder: c:\projects\eqemu +init: +- ps: git config --global core.autocrlf input +cache: c:\tools\vcpkg\installed\ +before_build: +- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=OFF -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .." +build: + project: C:\projects\eqemu\build\EQEmu.sln + parallel: true + verbosity: minimal +after_build: +- cmd: >- + 7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb + + appveyor PushArtifact build_x64-no-bots.zip \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 33848c7d8..7ba6c61c9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,61 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 07/10/2018 == +Akkadius: Adjusted DataBuckets to use other acceptable time formats + Example: quest::set_data('key', 'value', '1d'); + - Acceptable inputs: + - 15s = 15 seconds + - s15 = 15 seconds + - 60m = 60 minutes + - 7d = 7 days + - 1y = 1 year + - 600 = 600 seconds + +== 07/09/2018 == +mackal: Rework of Task System, Shared Tasks still unsupported + - The tables now have better named columns, which hopefully won't need to be explained + - Text1 is now target_name, Text2 is now item_list, Text3 is now description_override + - Tasks can now reward faction hits, this is just normal NPC Faction ID entries because I was lazy + - The "Task" type tasks are now supported, a player can only be doing one of these at a time + - Activity IDs for use spell on and use skill on have been identified but not implemented + - Identified "duration code" for unlimited duration tasks (None = 0, Short = 1, Medium = 2, Long = 3) + - Activities can now have multiple zones separated by ';' + - tasks.startzone removed since it actually just uses first activity + - skill_list and spell_list are both IDs that can be separated by ';' (still unimplemented though) + +== 07/07/2018 == +Akkadius: Implemented a much better replacement for qglobals called 'DataBuckets' + - A much more detailed example can be found at: https://github.com/EQEmu/Server/wiki/Data-Buckets + +== 07/05/2018 == +Uleat: Reintegration of inventory-based EQDictionary references + - Standardized 'CONSTANT_DECLARATION' and 'enumerationValue' tokens for most of the affected references + - Added 'BEGIN' and 'END' constants to many inventory-based ranges to help eliminate '< SIZE'-type comparisons + - Eliminated multiple, duplicated reference points of the same value context (bye, bye namespace legacy!) + - Most server values are now linked to the implementation client directly through a 'using ##' directive + +== 05/28/2018 == +Akkadius: Fixed an issue where size 0 NPC's hop in and out of the ground at idle +Akkadius: NPC's now open doors within proximity given the door doesn't have locked requirements +Akkadius: #reloadallrules will now display zones that have had their rules reloaded to GM's +Akkadius: Zones should now respect "shutdowndelay" in the zones table at all times +Akkadius: Fixed an issue where boats would snap to the bed of the body of water +Akkadius: Added rule Aggro:NPCAggroMaxDistanceEnabled - defaults to true +Akkadius: Changed map directory load structure + - maps/base/*.map + - maps/nav/*.nav + - maps/water/*.wtr + - maps/path/*.path + +KLS: Implemented navigation mesh + - All up to date maps and navs can be found https://github.com/Akkadius/EQEmuMaps + - To update maps either check out the maps found in the above repository or use the maintenance command: + perl eqemu_server.pl maps + == 03/28/2018 == Kayen: SE_CastOnFadeEffect, SE_CastOnFadeEffectNPC, SE_CastOnFadeEffectAlway triggered spell will now hit the correct targets. - == 03/07/2018 == Uleat: Added command '#ucs' to force a reconnect to UCS server. - Works in place of client auto-reconnect packet in zones where feature is unsupported diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d65efd183..b953815e6 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -3,6 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(common_sources base_packet.cpp classes.cpp + compression.cpp condition.cpp crash.cpp crc16.cpp @@ -13,7 +14,6 @@ SET(common_sources dbcore.cpp deity.cpp emu_constants.cpp - emu_legacy.cpp emu_limits.cpp emu_opcodes.cpp emu_versions.cpp @@ -60,6 +60,7 @@ SET(common_sources rdtsc.cpp rulesys.cpp say_link.cpp + serialize_buffer.cpp serverinfo.cpp shareddb.cpp skills.cpp @@ -113,6 +114,7 @@ SET(common_headers base_data.h bodytypes.h classes.h + compression.h condition.h crash.h crc16.h @@ -122,7 +124,6 @@ SET(common_headers dbcore.h deity.h emu_constants.h - emu_legacy.h emu_limits.h emu_opcodes.h emu_oplist.h @@ -190,6 +191,7 @@ SET(common_headers ruletypes.h say_link.h seperator.h + serialize_buffer.h serverinfo.h servertalk.h shareddb.h diff --git a/common/base_packet.cpp b/common/base_packet.cpp index ce6afe978..50f9b84f9 100644 --- a/common/base_packet.cpp +++ b/common/base_packet.cpp @@ -39,6 +39,18 @@ BasePacket::BasePacket(const unsigned char *buf, uint32 len) } } +BasePacket::BasePacket(SerializeBuffer &buf) +{ + pBuffer = buf.m_buffer; + buf.m_buffer = nullptr; + size = buf.m_pos; + buf.m_pos = 0; + buf.m_capacity = 0; + _wpos = 0; + _rpos = 0; + timestamp.tv_sec = 0; +} + BasePacket::~BasePacket() { if (pBuffer) diff --git a/common/base_packet.h b/common/base_packet.h index bdd774aa2..4f47c919a 100644 --- a/common/base_packet.h +++ b/common/base_packet.h @@ -19,6 +19,7 @@ #define BASEPACKET_H_ #include "types.h" +#include "serialize_buffer.h" #include #include @@ -63,6 +64,8 @@ public: void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); } void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); } void WriteString(const char * str) { uint32 len = static_cast(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; } + // this is used in task system a lot, it is NOT null-termed + void WriteLengthString(uint32 len, const char *str) { *(uint32 *)(pBuffer + _wpos) = len; _wpos += sizeof(uint32); memcpy(pBuffer + _wpos, str, len); _wpos += len; } void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; } uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; } @@ -83,6 +86,7 @@ protected: virtual ~BasePacket(); BasePacket() { pBuffer=nullptr; size=0; _wpos = 0; _rpos = 0; } BasePacket(const unsigned char *buf, const uint32 len); + BasePacket(SerializeBuffer &buf); }; extern void DumpPacketHex(const BasePacket* app); diff --git a/common/compression.cpp b/common/compression.cpp new file mode 100644 index 000000000..c56d9bf6a --- /dev/null +++ b/common/compression.cpp @@ -0,0 +1,82 @@ +#include "global_define.h" +#include "types.h" +#include +#include + +namespace EQEmu +{ + uint32 EstimateDeflateBuffer(uint32 len) { + z_stream zstream; + memset(&zstream, 0, sizeof(zstream)); + + zstream.zalloc = Z_NULL; + zstream.zfree = Z_NULL; + zstream.opaque = Z_NULL; + if (deflateInit(&zstream, Z_FINISH) != Z_OK) + return 0; + + return deflateBound(&zstream, len); + } + + uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max) { + z_stream zstream; + memset(&zstream, 0, sizeof(zstream)); + int zerror; + + zstream.next_in = const_cast(reinterpret_cast(buffer)); + zstream.avail_in = len; + zstream.zalloc = Z_NULL; + zstream.zfree = Z_NULL; + zstream.opaque = Z_NULL; + deflateInit(&zstream, Z_FINISH); + + zstream.next_out = reinterpret_cast(out_buffer); + zstream.avail_out = out_len_max; + zerror = deflate(&zstream, Z_FINISH); + + if (zerror == Z_STREAM_END) + { + deflateEnd(&zstream); + return (uint32)zstream.total_out; + } + else + { + zerror = deflateEnd(&zstream); + return 0; + } + } + + uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) { + z_stream zstream; + int zerror = 0; + int i; + + zstream.next_in = const_cast(reinterpret_cast(buffer)); + zstream.avail_in = len; + zstream.next_out = reinterpret_cast(out_buffer);; + zstream.avail_out = out_len_max; + zstream.zalloc = Z_NULL; + zstream.zfree = Z_NULL; + zstream.opaque = Z_NULL; + + i = inflateInit2(&zstream, 15); + if (i != Z_OK) { + return 0; + } + + zerror = inflate(&zstream, Z_FINISH); + if (zerror == Z_STREAM_END) { + inflateEnd(&zstream); + return zstream.total_out; + } + else { + if (zerror == -4 && zstream.msg == 0) + { + return 0; + } + + zerror = inflateEnd(&zstream); + return 0; + } + } +} diff --git a/common/compression.h b/common/compression.h new file mode 100644 index 000000000..cc2fac264 --- /dev/null +++ b/common/compression.h @@ -0,0 +1,8 @@ +#pragma once + +namespace EQEmu +{ + uint32 EstimateDeflateBuffer(uint32 len); + uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max); + uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max); +} diff --git a/common/database.cpp b/common/database.cpp index 62a8453d1..447037ae7 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -708,7 +708,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu /* Insert starting inventory... */ std::string invquery; - for (int16 i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::BANK_BAGS_END;) { + for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invbag::BANK_BAGS_END;) { const EQEmu::ItemInstance* newinv = inv->GetItem(i); if (newinv) { invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)", @@ -717,16 +717,16 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu auto results = QueryDatabase(invquery); } - if (i == EQEmu::inventory::slotCursor) { - i = EQEmu::legacy::GENERAL_BAGS_BEGIN; + if (i == EQEmu::invslot::slotCursor) { + i = EQEmu::invbag::GENERAL_BAGS_BEGIN; continue; } - else if (i == EQEmu::legacy::CURSOR_BAG_END) { - i = EQEmu::legacy::BANK_BEGIN; + else if (i == EQEmu::invbag::CURSOR_BAG_END) { + i = EQEmu::invslot::BANK_BEGIN; continue; } - else if (i == EQEmu::legacy::BANK_END) { - i = EQEmu::legacy::BANK_BAGS_BEGIN; + else if (i == EQEmu::invslot::BANK_END) { + i = EQEmu::invbag::BANK_BAGS_BEGIN; continue; } i++; @@ -1752,6 +1752,15 @@ void Database::ClearRaidDetails(uint32 rid) { std::cout << "Unable to clear raid details: " << results.ErrorMessage() << std::endl; } +void Database::PurgeAllDeletedDataBuckets() { + std::string query = StringFormat( + "DELETE FROM `data_buckets` WHERE (`expires` < %lld AND `expires` > 0)", + (long long) std::time(nullptr) + ); + + QueryDatabase(query); +} + // returns 0 on error or no raid for that character, or // the raid id that the character is a member of. uint32 Database::GetRaidID(const char* name) diff --git a/common/database.h b/common/database.h index 6f3fd0642..c6d90e422 100644 --- a/common/database.h +++ b/common/database.h @@ -221,6 +221,8 @@ public: void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr); void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid); + void PurgeAllDeletedDataBuckets(); + /* Database Conversions 'database_conversions.cpp' */ bool CheckDatabaseConversions(); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index f04e9a93b..0e6c40a6f 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -41,6 +41,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #pragma pack(1) +// all const/macro reference values should really be converted to a magic number for this +// process to ensure that the struct sizes and offsets match up to the corresponding blob + /* Conversion Structs */ namespace Convert { @@ -330,7 +333,7 @@ namespace Convert { /*7212*/ uint32 tribute_points; /*7216*/ uint32 unknown7252; /*7220*/ uint32 tribute_active; //1=active - /*7224*/ Convert::Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE]; + /*7224*/ Convert::Tribute_Struct tributes[5]; /*7264*/ Convert::Disciplines_Struct disciplines; /*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use) /*7744*/ char unknown7780[160]; @@ -1405,7 +1408,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){ if (rquery != ""){ results = QueryDatabase(rquery); } /* Run Tribute Convert */ first_entry = 0; rquery = ""; - for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++){ + for (i = 0; i < 5; i++){ if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){ if (first_entry != 1){ rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); diff --git a/common/emu_constants.cpp b/common/emu_constants.cpp index e5e9ae841..e229b7d6d 100644 --- a/common/emu_constants.cpp +++ b/common/emu_constants.cpp @@ -20,6 +20,41 @@ #include "emu_constants.h" +int16 EQEmu::invtype::GetInvTypeSize(int16 inv_type) { + static const int16 local_array[] = { + POSSESSIONS_SIZE, + BANK_SIZE, + SHARED_BANK_SIZE, + TRADE_SIZE, + WORLD_SIZE, + LIMBO_SIZE, + TRIBUTE_SIZE, + TROPHY_TRIBUTE_SIZE, + GUILD_TRIBUTE_SIZE, + MERCHANT_SIZE, + DELETED_SIZE, + CORPSE_SIZE, + BAZAAR_SIZE, + INSPECT_SIZE, + REAL_ESTATE_SIZE, + VIEW_MOD_PC_SIZE, + VIEW_MOD_BANK_SIZE, + VIEW_MOD_SHARED_BANK_SIZE, + VIEW_MOD_LIMBO_SIZE, + ALT_STORAGE_SIZE, + ARCHIVED_SIZE, + MAIL_SIZE, + GUILD_TROPHY_TRIBUTE_SIZE, + KRONO_SIZE, + OTHER_SIZE, + }; + + if (inv_type < TYPE_BEGIN || inv_type > TYPE_END) + return INULL; + + return local_array[inv_type]; +} + const char* EQEmu::bug::CategoryIDToCategoryName(CategoryID category_id) { switch (category_id) { case catVideo: diff --git a/common/emu_constants.h b/common/emu_constants.h index 32968458c..fcddeac09 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -21,104 +21,173 @@ #define COMMON_EMU_CONSTANTS_H #include "eq_limits.h" -#include "emu_legacy.h" #include "emu_versions.h" #include +// local definitions are the result of using hybrid-client or server-only values and methods namespace EQEmu { + using RoF2::IINVALID; + using RoF2::INULL; + namespace inventory { - //using namespace RoF2::invtype; - //using namespace RoF2::invslot; - //using namespace RoF2::invbag; - //using namespace RoF2::invaug; - - enum : int16 { typeInvalid = -1, slotInvalid = -1, containerInvalid = -1, socketInvalid = -1 }; // temporary - enum : int16 { typeBegin = 0, slotBegin = 0, containerBegin = 0, socketBegin = 0 }; // temporary - - enum PossessionsSlots : int16 { // temporary - slotCharm = 0, - slotEar1, - slotHead, - slotFace, - slotEar2, - slotNeck, // 5 - slotShoulders, - slotArms, - slotBack, - slotWrist1, - slotWrist2, // 10 - slotRange, - slotHands, - slotPrimary, - slotSecondary, - slotFinger1, // 15 - slotFinger2, - slotChest, - slotLegs, - slotFeet, - slotWaist, // 20 - slotPowerSource = 9999, - slotAmmo = 21, - slotGeneral1, - slotGeneral2, - slotGeneral3, - slotGeneral4, // 25 - slotGeneral5, - slotGeneral6, - slotGeneral7, - slotGeneral8, - slotCursor, // 30 - slotCount - }; - - enum InventoryTypes : int16 { // temporary - typePossessions = 0, - typeBank, - typeSharedBank, - typeTrade, - typeWorld, - typeLimbo, // 5 - typeTribute, - typeTrophyTribute, - typeGuildTribute, - typeMerchant, - typeDeleted, // 10 - typeCorpse, - typeBazaar, - typeInspect, - typeRealEstate, - typeViewMODPC, // 15 - typeViewMODBank, - typeViewMODSharedBank, - typeViewMODLimbo, - typeAltStorage, - typeArchived, // 20 - typeMail, - typeGuildTrophyTribute, - typeKrono, - typeOther, - typeCount - }; - - static int16 SlotCount(int16 type_index) { return 0; } // temporary - - const int16 ContainerCount = 10; // temporary - const int16 SocketCount = 6; // temporary - + } /*inventory*/ - namespace constants { - const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2; - const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit; + namespace invtype { + using namespace RoF2::invtype::enum_; - const size_t SayLinkOpenerSize = 1; - const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize; - const size_t SayLinkTextSize = 256; // this may be varied until it breaks something (tested:374) - the others are constant - const size_t SayLinkCloserSize = 1; - const size_t SayLinkMaximumSize = (SayLinkOpenerSize + SayLinkBodySize + SayLinkTextSize + SayLinkCloserSize); + using RoF2::invtype::POSSESSIONS_SIZE; + using RoF2::invtype::BANK_SIZE; + using RoF2::invtype::SHARED_BANK_SIZE; + using RoF2::invtype::TRADE_SIZE; + using RoF2::invtype::WORLD_SIZE; + using RoF2::invtype::LIMBO_SIZE; + using RoF2::invtype::TRIBUTE_SIZE; + using RoF2::invtype::TROPHY_TRIBUTE_SIZE; + using RoF2::invtype::GUILD_TRIBUTE_SIZE; + using RoF2::invtype::MERCHANT_SIZE; + using RoF2::invtype::DELETED_SIZE; + using RoF2::invtype::CORPSE_SIZE; + using RoF2::invtype::BAZAAR_SIZE; + using RoF2::invtype::INSPECT_SIZE; + using RoF2::invtype::REAL_ESTATE_SIZE; + using RoF2::invtype::VIEW_MOD_PC_SIZE; + using RoF2::invtype::VIEW_MOD_BANK_SIZE; + using RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE; + using RoF2::invtype::VIEW_MOD_LIMBO_SIZE; + using RoF2::invtype::ALT_STORAGE_SIZE; + using RoF2::invtype::ARCHIVED_SIZE; + using RoF2::invtype::MAIL_SIZE; + using RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE; + using RoF2::invtype::KRONO_SIZE; + using RoF2::invtype::OTHER_SIZE; + + using Titanium::invtype::TRADE_NPC_SIZE; + + using RoF2::invtype::TYPE_INVALID; + using RoF2::invtype::TYPE_BEGIN; + using RoF2::invtype::TYPE_END; + using RoF2::invtype::TYPE_COUNT; + + int16 GetInvTypeSize(int16 inv_type); + using RoF2::invtype::GetInvTypeName; + + } // namespace invtype + + namespace invslot { + using namespace Titanium::invslot::enum_; + + const int16 SLOT_POWER_SOURCE = 9999; + + using RoF2::invslot::SLOT_INVALID; + using RoF2::invslot::SLOT_BEGIN; + + using Titanium::invslot::POSSESSIONS_BEGIN; + using Titanium::invslot::POSSESSIONS_END; + using SoF::invslot::POSSESSIONS_COUNT; + + using Titanium::invslot::EQUIPMENT_BEGIN; + using Titanium::invslot::EQUIPMENT_END; + using Titanium::invslot::EQUIPMENT_COUNT; + + using Titanium::invslot::GENERAL_BEGIN; + using Titanium::invslot::GENERAL_END; + using Titanium::invslot::GENERAL_COUNT; + + using Titanium::invslot::BONUS_BEGIN; + using Titanium::invslot::BONUS_STAT_END; + using Titanium::invslot::BONUS_SKILL_END; + + using Titanium::invslot::BANK_BEGIN; + using SoF::invslot::BANK_END; + + using Titanium::invslot::SHARED_BANK_BEGIN; + using Titanium::invslot::SHARED_BANK_END; + + using Titanium::invslot::TRADE_BEGIN; + using Titanium::invslot::TRADE_END; + + using Titanium::invslot::TRADE_NPC_END; + + using Titanium::invslot::WORLD_BEGIN; + using Titanium::invslot::WORLD_END; + + using Titanium::invslot::TRIBUTE_BEGIN; + using Titanium::invslot::TRIBUTE_END; + + using Titanium::invslot::GUILD_TRIBUTE_BEGIN; + using Titanium::invslot::GUILD_TRIBUTE_END; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor; + + using RoF2::invslot::POSSESSIONS_BITMASK; + using RoF2::invslot::CORPSE_BITMASK; + + using RoF2::invslot::GetInvPossessionsSlotName; + using RoF2::invslot::GetInvSlotName; + + } // namespace invslot + + namespace invbag { + using Titanium::invbag::SLOT_INVALID; + using Titanium::invbag::SLOT_BEGIN; + using Titanium::invbag::SLOT_END; + using Titanium::invbag::SLOT_COUNT; + + using Titanium::invbag::GENERAL_BAGS_BEGIN; + const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT; + const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1; + + const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT; + const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1; + + const int16 CURSOR_BAG_BEGIN = 331; + const int16 CURSOR_BAG_COUNT = SLOT_COUNT; + const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1; + + using Titanium::invbag::BANK_BAGS_BEGIN; + const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT); + const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1; + + const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT; + const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1; + + using Titanium::invbag::SHARED_BANK_BAGS_BEGIN; + const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT; + const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1; + + using Titanium::invbag::TRADE_BAGS_BEGIN; + const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT; + const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1; + + using Titanium::invbag::GetInvBagIndexName; + + } // namespace invbag + + namespace invaug { + using RoF2::invaug::SOCKET_INVALID; + using RoF2::invaug::SOCKET_BEGIN; + using RoF2::invaug::SOCKET_END; + using RoF2::invaug::SOCKET_COUNT; + + using RoF2::invaug::GetInvAugIndexName; + + } // namespace invaug + + namespace constants { + const EQEmu::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQEmu::versions::ClientVersion::Titanium; + + using RoF2::constants::CHARACTER_CREATION_LIMIT; + + const size_t SAY_LINK_OPENER_SIZE = 1; + using RoF2::constants::SAY_LINK_BODY_SIZE; + const size_t SAY_LINK_TEXT_SIZE = 256; // this may be varied until it breaks something (tested:374) - the others are constant + const size_t SAY_LINK_CLOSER_SIZE = 1; + const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE); const int LongBuffs = RoF2::constants::LongBuffs; const int ShortBuffs = RoF2::constants::ShortBuffs; @@ -130,6 +199,21 @@ namespace EQEmu } /*constants*/ + namespace profile { + using RoF2::profile::BANDOLIERS_SIZE; + using RoF2::profile::BANDOLIER_ITEM_COUNT; + + using RoF2::profile::POTION_BELT_SIZE; + + using RoF2::profile::SKILL_ARRAY_SIZE; + + } // namespace profile + + namespace behavior { + using RoF2::behavior::CoinHasWeight; + + } // namespace behavior + namespace bug { enum CategoryID : uint32 { catOther = 0, diff --git a/common/emu_legacy.cpp b/common/emu_legacy.cpp deleted file mode 100644 index 36cb21c36..000000000 --- a/common/emu_legacy.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* EQEMu: Everquest Server Emulator - - Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) - - 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; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "emu_legacy.h" diff --git a/common/emu_legacy.h b/common/emu_legacy.h deleted file mode 100644 index 812a33ca1..000000000 --- a/common/emu_legacy.h +++ /dev/null @@ -1,182 +0,0 @@ -/* EQEMu: Everquest Server Emulator - - Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) - - 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; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef COMMON_EMU_LEGACY_H -#define COMMON_EMU_LEGACY_H - -#include "types.h" - -#include - - -namespace EQEmu -{ - // this is for perl and other legacy systems - namespace legacy { - enum InventorySlot { - SLOT_CHARM = 0, - SLOT_EAR01 = 1, - SLOT_HEAD = 2, - SLOT_FACE = 3, - SLOT_EAR02 = 4, - SLOT_NECK = 5, - SLOT_SHOULDER = 6, - SLOT_ARMS = 7, - SLOT_BACK = 8, - SLOT_BRACER01 = 9, - SLOT_BRACER02 = 10, - SLOT_RANGE = 11, - SLOT_HANDS = 12, - SLOT_PRIMARY = 13, - SLOT_SECONDARY = 14, - SLOT_RING01 = 15, - SLOT_RING02 = 16, - SLOT_CHEST = 17, - SLOT_LEGS = 18, - SLOT_FEET = 19, - SLOT_WAIST = 20, - SLOT_POWER_SOURCE = 9999, - SLOT_AMMO = 21, - SLOT_GENERAL_1 = 22, - SLOT_GENERAL_2 = 23, - SLOT_GENERAL_3 = 24, - SLOT_GENERAL_4 = 25, - SLOT_GENERAL_5 = 26, - SLOT_GENERAL_6 = 27, - SLOT_GENERAL_7 = 28, - SLOT_GENERAL_8 = 29, - SLOT_CURSOR = 30, - SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this... - SLOT_TRADESKILL = 1000, - SLOT_AUGMENT = 1001, - SLOT_INVALID = (int16)0xFFFF, - SLOT_POSSESSIONS_BEGIN = 0, - SLOT_POSSESSIONS_END = 30, - SLOT_EQUIPMENT_BEGIN = 0, - SLOT_EQUIPMENT_END = 21, - SLOT_PERSONAL_BEGIN = 22, - SLOT_PERSONAL_END = 29, - SLOT_PERSONAL_BAGS_BEGIN = 251, - SLOT_PERSONAL_BAGS_END = 330, - SLOT_CURSOR_BAG_BEGIN = 331, - SLOT_CURSOR_BAG_END = 340, - SLOT_TRIBUTE_BEGIN = 400, - SLOT_TRIBUTE_END = 404, - SLOT_GUILD_TRIBUTE_BEGIN = 450, - SLOT_GUILD_TRIBUTE_END = 451, - SLOT_BANK_BEGIN = 2000, - SLOT_BANK_END = 2023, - SLOT_BANK_BAGS_BEGIN = 2031, - SLOT_BANK_BAGS_END = 2270, - SLOT_SHARED_BANK_BEGIN = 2500, - SLOT_SHARED_BANK_END = 2501, - SLOT_SHARED_BANK_BAGS_BEGIN = 2531, - SLOT_SHARED_BANK_BAGS_END = 2550, - SLOT_TRADE_BEGIN = 3000, - SLOT_TRADE_END = 3007, - SLOT_TRADE_BAGS_BEGIN = 3031, - SLOT_TRADE_BAGS_END = 3110, - SLOT_WORLD_BEGIN = 4000, - SLOT_WORLD_END = 4009 - }; - - // these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready - static const uint16 TYPE_POSSESSIONS_SIZE = 31; - static const uint16 TYPE_BANK_SIZE = 24; - static const uint16 TYPE_SHARED_BANK_SIZE = 2; - static const uint16 TYPE_TRADE_SIZE = 8; - static const uint16 TYPE_WORLD_SIZE = 10; - static const uint16 TYPE_LIMBO_SIZE = 36; - static const uint16 TYPE_TRIBUTE_SIZE = 5; // (need client values) - static const uint16 TYPE_TROPHY_TRIBUTE_SIZE = 0; - static const uint16 TYPE_GUILD_TRIBUTE_SIZE = 0; - static const uint16 TYPE_MERCHANT_SIZE = 0; - static const uint16 TYPE_DELETED_SIZE = 0; - static const uint16 TYPE_CORPSE_SIZE = 31; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, ItemList; diff --git a/common/event/background_task.h b/common/event/background_task.h index 8082abaf3..41fe4accb 100644 --- a/common/event/background_task.h +++ b/common/event/background_task.h @@ -1,32 +1,35 @@ #pragma once #include +#include "../any.h" #include "event_loop.h" namespace EQ { class BackgroundTask { public: - typedef std::function BackgroundTaskFunction; + typedef std::function BackgroundTaskFunction; struct BackgroundTaskBaton { BackgroundTaskFunction fn; BackgroundTaskFunction on_finish; + EQEmu::Any data; }; - BackgroundTask(BackgroundTaskFunction fn, BackgroundTaskFunction on_finish) { + BackgroundTask(BackgroundTaskFunction fn, BackgroundTaskFunction on_finish, EQEmu::Any data) { uv_work_t *m_work = new uv_work_t; memset(m_work, 0, sizeof(uv_work_t)); BackgroundTaskBaton *baton = new BackgroundTaskBaton(); baton->fn = fn; baton->on_finish = on_finish; + baton->data = data; m_work->data = baton; uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) { BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data; - baton->fn(); + baton->fn(baton->data); }, [](uv_work_t* req, int status) { BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data; - baton->on_finish(); + baton->on_finish(baton->data); delete baton; delete req; }); diff --git a/common/features.h b/common/features.h index a35431bff..a80fb9f3c 100644 --- a/common/features.h +++ b/common/features.h @@ -154,6 +154,7 @@ enum { //timer settings, all in milliseconds AIscanarea_delay = 6000, AIfeignremember_delay = 500, AItarget_check_duration = 500, + AI_scan_door_open_interval = 1000, // AIClientScanarea_delay = 750, //used in REVERSE_AGGRO AIassistcheck_delay = 3000, //now often a fighting NPC will yell for help AI_check_signal_timer_delay = 500, // How often EVENT_SIGNAL checks are processed diff --git a/common/inventory_profile.cpp b/common/inventory_profile.cpp index 4f64c7a58..cb20cd8a8 100644 --- a/common/inventory_profile.cpp +++ b/common/inventory_profile.cpp @@ -119,6 +119,21 @@ EQEmu::InventoryProfile::~InventoryProfile() m_trade.clear(); } +bool EQEmu::InventoryProfile::SetInventoryVersion(versions::MobVersion inventory_version) { + if (!m_mob_version_set) { + m_mob_version = versions::ValidateMobVersion(inventory_version); + m_lookup = inventory::Lookup(m_mob_version); + m_mob_version_set = true; + return true; + } + else { + m_lookup = inventory::Lookup(versions::MobVersion::Unknown); + Log(Logs::General, Logs::Error, "InventoryVersion set request after initial set (old: %u, new: %u)", + static_cast(m_mob_version), static_cast(inventory_version)); + return false; + } +} + void EQEmu::InventoryProfile::CleanDirty() { auto iter = dirty_inst.begin(); while (iter != dirty_inst.end()) { @@ -140,63 +155,63 @@ EQEmu::ItemInstance* EQEmu::InventoryProfile::GetItem(int16 slot_id) const ItemInstance* result = nullptr; // Cursor - if (slot_id == inventory::slotCursor) { + if (slot_id == invslot::slotCursor) { // Cursor slot result = m_cursor.peek_front(); } // Non bag slots - else if (slot_id >= legacy::TRADE_BEGIN && slot_id <= legacy::TRADE_END) { + else if (slot_id >= invslot::TRADE_BEGIN && slot_id <= invslot::TRADE_END) { result = _GetItem(m_trade, slot_id); } - else if (slot_id >= legacy::SHARED_BANK_BEGIN && slot_id <= legacy::SHARED_BANK_END) { + else if (slot_id >= invslot::SHARED_BANK_BEGIN && slot_id <= invslot::SHARED_BANK_END) { // Shared Bank slots result = _GetItem(m_shbank, slot_id); } - else if (slot_id >= legacy::BANK_BEGIN && slot_id <= legacy::BANK_END) { + else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) { // Bank slots result = _GetItem(m_bank, slot_id); } - else if ((slot_id >= legacy::GENERAL_BEGIN && slot_id <= legacy::GENERAL_END)) { + else if ((slot_id >= invslot::GENERAL_BEGIN && slot_id <= invslot::GENERAL_END)) { // Personal inventory slots result = _GetItem(m_inv, slot_id); } - else if ((slot_id >= legacy::EQUIPMENT_BEGIN && slot_id <= legacy::EQUIPMENT_END) || - (slot_id >= legacy::TRIBUTE_BEGIN && slot_id <= legacy::TRIBUTE_END) || (slot_id == inventory::slotPowerSource)) { + else if ((slot_id >= invslot::EQUIPMENT_BEGIN && slot_id <= invslot::EQUIPMENT_END) || + (slot_id >= invslot::TRIBUTE_BEGIN && slot_id <= invslot::TRIBUTE_END) || (slot_id == invslot::SLOT_POWER_SOURCE)) { // Equippable slots (on body) result = _GetItem(m_worn, slot_id); } // Inner bag slots - else if (slot_id >= legacy::TRADE_BAGS_BEGIN && slot_id <= legacy::TRADE_BAGS_END) { + else if (slot_id >= invbag::TRADE_BAGS_BEGIN && slot_id <= invbag::TRADE_BAGS_END) { // Trade bag slots ItemInstance* inst = _GetItem(m_trade, InventoryProfile::CalcSlotId(slot_id)); if (inst && inst->IsClassBag()) { result = inst->GetItem(InventoryProfile::CalcBagIdx(slot_id)); } } - else if (slot_id >= legacy::SHARED_BANK_BAGS_BEGIN && slot_id <= legacy::SHARED_BANK_BAGS_END) { + else if (slot_id >= invbag::SHARED_BANK_BAGS_BEGIN && slot_id <= invbag::SHARED_BANK_BAGS_END) { // Shared Bank bag slots ItemInstance* inst = _GetItem(m_shbank, InventoryProfile::CalcSlotId(slot_id)); if (inst && inst->IsClassBag()) { result = inst->GetItem(InventoryProfile::CalcBagIdx(slot_id)); } } - else if (slot_id >= legacy::BANK_BAGS_BEGIN && slot_id <= legacy::BANK_BAGS_END) { + else if (slot_id >= invbag::BANK_BAGS_BEGIN && slot_id <= invbag::BANK_BAGS_END) { // Bank bag slots ItemInstance* inst = _GetItem(m_bank, InventoryProfile::CalcSlotId(slot_id)); if (inst && inst->IsClassBag()) { result = inst->GetItem(InventoryProfile::CalcBagIdx(slot_id)); } } - else if (slot_id >= legacy::CURSOR_BAG_BEGIN && slot_id <= legacy::CURSOR_BAG_END) { + else if (slot_id >= invbag::CURSOR_BAG_BEGIN && slot_id <= invbag::CURSOR_BAG_END) { // Cursor bag slots ItemInstance* inst = m_cursor.peek_front(); if (inst && inst->IsClassBag()) { result = inst->GetItem(InventoryProfile::CalcBagIdx(slot_id)); } } - else if (slot_id >= legacy::GENERAL_BAGS_BEGIN && slot_id <= legacy::GENERAL_BAGS_END) { + else if (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END) { // Personal inventory bag slots ItemInstance* inst = _GetItem(m_inv, InventoryProfile::CalcSlotId(slot_id)); if (inst && inst->IsClassBag()) { @@ -232,7 +247,7 @@ int16 EQEmu::InventoryProfile::PutItem(int16 slot_id, const ItemInstance& inst) int16 EQEmu::InventoryProfile::PushCursor(const ItemInstance& inst) { m_cursor.push(inst.Clone()); - return inventory::slotCursor; + return invslot::slotCursor; } EQEmu::ItemInstance* EQEmu::InventoryProfile::GetCursorItem() @@ -254,7 +269,7 @@ bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailS fail_state = swapNotAllowed; return false; } - if ((slot_b >= legacy::EQUIPMENT_BEGIN && slot_b <= legacy::EQUIPMENT_END) || slot_b == inventory::slotPowerSource) { + if ((slot_b >= invslot::EQUIPMENT_BEGIN && slot_b <= invslot::EQUIPMENT_END) || slot_b == invslot::SLOT_POWER_SOURCE) { auto item_a = inst_a->GetItem(); if (!item_a) { fail_state = swapNullData; @@ -280,7 +295,7 @@ bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailS fail_state = swapNotAllowed; return false; } - if ((slot_a >= legacy::EQUIPMENT_BEGIN && slot_a <= legacy::EQUIPMENT_END) || slot_a == inventory::slotPowerSource) { + if ((slot_a >= invslot::EQUIPMENT_BEGIN && slot_a <= invslot::EQUIPMENT_END) || slot_a == invslot::SLOT_POWER_SOURCE) { auto item_b = inst_b->GetItem(); if (!item_b) { fail_state = swapNullData; @@ -361,30 +376,30 @@ EQEmu::ItemInstance* EQEmu::InventoryProfile::PopItem(int16 slot_id) { ItemInstance* p = nullptr; - if (slot_id == inventory::slotCursor) { + if (slot_id == invslot::slotCursor) { p = m_cursor.pop(); } - else if ((slot_id >= legacy::EQUIPMENT_BEGIN && slot_id <= legacy::EQUIPMENT_END) || (slot_id == inventory::slotPowerSource)) { + else if ((slot_id >= invslot::EQUIPMENT_BEGIN && slot_id <= invslot::EQUIPMENT_END) || (slot_id == invslot::SLOT_POWER_SOURCE)) { p = m_worn[slot_id]; m_worn.erase(slot_id); } - else if ((slot_id >= legacy::GENERAL_BEGIN && slot_id <= legacy::GENERAL_END)) { + else if ((slot_id >= invslot::GENERAL_BEGIN && slot_id <= invslot::GENERAL_END)) { p = m_inv[slot_id]; m_inv.erase(slot_id); } - else if (slot_id >= legacy::TRIBUTE_BEGIN && slot_id <= legacy::TRIBUTE_END) { + else if (slot_id >= invslot::TRIBUTE_BEGIN && slot_id <= invslot::TRIBUTE_END) { p = m_worn[slot_id]; m_worn.erase(slot_id); } - else if (slot_id >= legacy::BANK_BEGIN && slot_id <= legacy::BANK_END) { + else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) { p = m_bank[slot_id]; m_bank.erase(slot_id); } - else if (slot_id >= legacy::SHARED_BANK_BEGIN && slot_id <= legacy::SHARED_BANK_END) { + else if (slot_id >= invslot::SHARED_BANK_BEGIN && slot_id <= invslot::SHARED_BANK_END) { p = m_shbank[slot_id]; m_shbank.erase(slot_id); } - else if (slot_id >= legacy::TRADE_BEGIN && slot_id <= legacy::TRADE_END) { + else if (slot_id >= invslot::TRADE_BEGIN && slot_id <= invslot::TRADE_END) { p = m_trade[slot_id]; m_trade.erase(slot_id); } @@ -404,7 +419,7 @@ bool EQEmu::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Q if (ItemToTry->Stackable) { - for (int16 i = legacy::GENERAL_BEGIN; i <= legacy::GENERAL_END; i++) { + for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) { ItemInstance* InvItem = GetItem(i); @@ -420,9 +435,9 @@ bool EQEmu::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Q } if (InvItem && InvItem->IsClassBag()) { - int16 BaseSlotID = InventoryProfile::CalcSlotId(i, inventory::containerBegin); + int16 BaseSlotID = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN); uint8 BagSize = InvItem->GetItem()->BagSlots; - for (uint8 BagSlot = inventory::containerBegin; BagSlot < BagSize; BagSlot++) { + for (uint8 BagSlot = invbag::SLOT_BEGIN; BagSlot < BagSize; BagSlot++) { InvItem = GetItem(BaseSlotID + BagSlot); @@ -441,7 +456,7 @@ bool EQEmu::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Q } } - for (int16 i = legacy::GENERAL_BEGIN; i <= legacy::GENERAL_END; i++) { + for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) { ItemInstance* InvItem = GetItem(i); @@ -464,11 +479,11 @@ bool EQEmu::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Q } else if (InvItem->IsClassBag() && CanItemFitInContainer(ItemToTry, InvItem->GetItem())) { - int16 BaseSlotID = InventoryProfile::CalcSlotId(i, inventory::containerBegin); + int16 BaseSlotID = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN); uint8 BagSize = InvItem->GetItem()->BagSlots; - for (uint8 BagSlot = inventory::containerBegin; BagSlotIsClassBag() && inst->GetItem()->BagSize >= min_size) { @@ -663,11 +678,11 @@ int16 EQEmu::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 continue; } - int16 base_slot_id = InventoryProfile::CalcSlotId(i, inventory::containerBegin); + int16 base_slot_id = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN); uint8 slots = inst->GetItem()->BagSlots; uint8 j; - for (j = inventory::containerBegin; j legacy::GENERAL_END)) + if ((general_start < invslot::GENERAL_BEGIN) || (general_start > invslot::GENERAL_END)) return INVALID_INDEX; - if (bag_start >= inventory::ContainerCount) + if (bag_start > invbag::SLOT_END) return INVALID_INDEX; if (!inst || !inst->GetID()) @@ -704,17 +719,17 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst // step 1: find room for bags (caller should really ask for slots for bags first to avoid sending them to cursor..and bag item loss) if (inst->IsClassBag()) { - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { if (!m_inv[free_slot]) return free_slot; } - return inventory::slotCursor; // return cursor since bags do not stack and will not fit inside other bags..yet...) + return invslot::slotCursor; // return cursor since bags do not stack and will not fit inside other bags..yet...) } // step 2: find partial room for stackables if (inst->IsStackable()) { - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { const ItemInstance* main_inst = m_inv[free_slot]; if (!main_inst) @@ -724,15 +739,15 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst return free_slot; } - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { const ItemInstance* main_inst = m_inv[free_slot]; if (!main_inst) continue; if (main_inst->IsClassBag()) { // if item-specific containers already have bad items, we won't fix it here... - uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start; - for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) { + uint8 _bag_start = (free_slot > general_start) ? invbag::SLOT_BEGIN : bag_start; + for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot <= invbag::SLOT_END); ++free_bag_slot) { const ItemInstance* sub_inst = main_inst->GetItem(free_bag_slot); if (!sub_inst) @@ -747,14 +762,14 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst // step 3a: find room for container-specific items (ItemClassArrow) if (inst->GetItem()->ItemType == item::ItemTypeArrow) { - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { const ItemInstance* main_inst = m_inv[free_slot]; if (!main_inst || (main_inst->GetItem()->BagType != item::BagTypeQuiver) || !main_inst->IsClassBag()) continue; - uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start; - for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) { + uint8 _bag_start = (free_slot > general_start) ? invbag::SLOT_BEGIN : bag_start; + for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot <= invbag::SLOT_END); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) return InventoryProfile::CalcSlotId(free_slot, free_bag_slot); } @@ -763,14 +778,14 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst // step 3b: find room for container-specific items (ItemClassSmallThrowing) if (inst->GetItem()->ItemType == item::ItemTypeSmallThrowing) { - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { const ItemInstance* main_inst = m_inv[free_slot]; if (!main_inst || (main_inst->GetItem()->BagType != item::BagTypeBandolier) || !main_inst->IsClassBag()) continue; - uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start; - for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) { + uint8 _bag_start = (free_slot > general_start) ? invbag::SLOT_BEGIN : bag_start; + for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot <= invbag::SLOT_END); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) return InventoryProfile::CalcSlotId(free_slot, free_bag_slot); } @@ -778,22 +793,22 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst } // step 4: just find an empty slot - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { const ItemInstance* main_inst = m_inv[free_slot]; if (!main_inst) return free_slot; } - for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) { + for (int16 free_slot = general_start; free_slot <= invslot::GENERAL_END; ++free_slot) { const ItemInstance* main_inst = m_inv[free_slot]; if (main_inst && main_inst->IsClassBag()) { if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == item::BagTypeBandolier) || (main_inst->GetItem()->BagType == item::BagTypeQuiver)) continue; - uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start; - for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) { + uint8 _bag_start = (free_slot > general_start) ? invbag::SLOT_BEGIN : bag_start; + for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot <= invbag::SLOT_END); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) return InventoryProfile::CalcSlotId(free_slot, free_bag_slot); } @@ -801,7 +816,7 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst } //return INVALID_INDEX; // everything else pushes to the cursor - return inventory::slotCursor; + return invslot::slotCursor; } // Opposite of below: Get parent bag slot_id from a slot inside of bag @@ -813,20 +828,20 @@ int16 EQEmu::InventoryProfile::CalcSlotId(int16 slot_id) { // parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; //else if (slot_id >= 3100 && slot_id <= 3179) should be {3031..3110}..where did this range come from!!? (verified db save range) - if (slot_id >= legacy::GENERAL_BAGS_BEGIN && slot_id <= legacy::GENERAL_BAGS_END) { - parent_slot_id = legacy::GENERAL_BEGIN + (slot_id - legacy::GENERAL_BAGS_BEGIN) / inventory::ContainerCount; + if (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END) { + parent_slot_id = invslot::GENERAL_BEGIN + (slot_id - invbag::GENERAL_BAGS_BEGIN) / invbag::SLOT_COUNT; } - else if (slot_id >= legacy::CURSOR_BAG_BEGIN && slot_id <= legacy::CURSOR_BAG_END) { - parent_slot_id = inventory::slotCursor; + else if (slot_id >= invbag::CURSOR_BAG_BEGIN && slot_id <= invbag::CURSOR_BAG_END) { + parent_slot_id = invslot::slotCursor; } - else if (slot_id >= legacy::BANK_BAGS_BEGIN && slot_id <= legacy::BANK_BAGS_END) { - parent_slot_id = legacy::BANK_BEGIN + (slot_id - legacy::BANK_BAGS_BEGIN) / inventory::ContainerCount; + else if (slot_id >= invbag::BANK_BAGS_BEGIN && slot_id <= invbag::BANK_BAGS_END) { + parent_slot_id = invslot::BANK_BEGIN + (slot_id - invbag::BANK_BAGS_BEGIN) / invbag::SLOT_COUNT; } - else if (slot_id >= legacy::SHARED_BANK_BAGS_BEGIN && slot_id <= legacy::SHARED_BANK_BAGS_END) { - parent_slot_id = legacy::SHARED_BANK_BEGIN + (slot_id - legacy::SHARED_BANK_BAGS_BEGIN) / inventory::ContainerCount; + else if (slot_id >= invbag::SHARED_BANK_BAGS_BEGIN && slot_id <= invbag::SHARED_BANK_BAGS_END) { + parent_slot_id = invslot::SHARED_BANK_BEGIN + (slot_id - invbag::SHARED_BANK_BAGS_BEGIN) / invbag::SLOT_COUNT; } - else if (slot_id >= legacy::TRADE_BAGS_BEGIN && slot_id <= legacy::TRADE_BAGS_END) { - parent_slot_id = legacy::TRADE_BEGIN + (slot_id - legacy::TRADE_BAGS_BEGIN) / inventory::ContainerCount; + else if (slot_id >= invbag::TRADE_BAGS_BEGIN && slot_id <= invbag::TRADE_BAGS_END) { + parent_slot_id = invslot::TRADE_BEGIN + (slot_id - invbag::TRADE_BAGS_BEGIN) / invbag::SLOT_COUNT; } return parent_slot_id; @@ -839,20 +854,20 @@ int16 EQEmu::InventoryProfile::CalcSlotId(int16 bagslot_id, uint8 bagidx) { int16 slot_id = INVALID_INDEX; - if (bagslot_id == inventory::slotCursor || bagslot_id == 8000) { - slot_id = legacy::CURSOR_BAG_BEGIN + bagidx; + if (bagslot_id == invslot::slotCursor || bagslot_id == 8000) { + slot_id = invbag::CURSOR_BAG_BEGIN + bagidx; } - else if (bagslot_id >= legacy::GENERAL_BEGIN && bagslot_id <= legacy::GENERAL_END) { - slot_id = legacy::GENERAL_BAGS_BEGIN + (bagslot_id - legacy::GENERAL_BEGIN) * inventory::ContainerCount + bagidx; + else if (bagslot_id >= invslot::GENERAL_BEGIN && bagslot_id <= invslot::GENERAL_END) { + slot_id = invbag::GENERAL_BAGS_BEGIN + (bagslot_id - invslot::GENERAL_BEGIN) * invbag::SLOT_COUNT + bagidx; } - else if (bagslot_id >= legacy::BANK_BEGIN && bagslot_id <= legacy::BANK_END) { - slot_id = legacy::BANK_BAGS_BEGIN + (bagslot_id - legacy::BANK_BEGIN) * inventory::ContainerCount + bagidx; + else if (bagslot_id >= invslot::BANK_BEGIN && bagslot_id <= invslot::BANK_END) { + slot_id = invbag::BANK_BAGS_BEGIN + (bagslot_id - invslot::BANK_BEGIN) * invbag::SLOT_COUNT + bagidx; } - else if (bagslot_id >= legacy::SHARED_BANK_BEGIN && bagslot_id <= legacy::SHARED_BANK_END) { - slot_id = legacy::SHARED_BANK_BAGS_BEGIN + (bagslot_id - legacy::SHARED_BANK_BEGIN) * inventory::ContainerCount + bagidx; + else if (bagslot_id >= invslot::SHARED_BANK_BEGIN && bagslot_id <= invslot::SHARED_BANK_END) { + slot_id = invbag::SHARED_BANK_BAGS_BEGIN + (bagslot_id - invslot::SHARED_BANK_BEGIN) * invbag::SLOT_COUNT + bagidx; } - else if (bagslot_id >= legacy::TRADE_BEGIN && bagslot_id <= legacy::TRADE_END) { - slot_id = legacy::TRADE_BAGS_BEGIN + (bagslot_id - legacy::TRADE_BEGIN) * inventory::ContainerCount + bagidx; + else if (bagslot_id >= invslot::TRADE_BEGIN && bagslot_id <= invslot::TRADE_END) { + slot_id = invbag::TRADE_BAGS_BEGIN + (bagslot_id - invslot::TRADE_BEGIN) * invbag::SLOT_COUNT + bagidx; } return slot_id; @@ -865,23 +880,23 @@ uint8 EQEmu::InventoryProfile::CalcBagIdx(int16 slot_id) { //else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) // index = (slot_id - EmuConstants::BANK_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - if (slot_id >= legacy::GENERAL_BAGS_BEGIN && slot_id <= legacy::GENERAL_BAGS_END) { - index = (slot_id - legacy::GENERAL_BAGS_BEGIN) % inventory::ContainerCount; + if (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END) { + index = (slot_id - invbag::GENERAL_BAGS_BEGIN) % invbag::SLOT_COUNT; } - else if (slot_id >= legacy::CURSOR_BAG_BEGIN && slot_id <= legacy::CURSOR_BAG_END) { - index = (slot_id - legacy::CURSOR_BAG_BEGIN); // % inventory::ContainerCount; - not needed since range is 10 slots + else if (slot_id >= invbag::CURSOR_BAG_BEGIN && slot_id <= invbag::CURSOR_BAG_END) { + index = (slot_id - invbag::CURSOR_BAG_BEGIN); // % invbag::SLOT_COUNT; - not needed since range is 10 slots } - else if (slot_id >= legacy::BANK_BAGS_BEGIN && slot_id <= legacy::BANK_BAGS_END) { - index = (slot_id - legacy::BANK_BAGS_BEGIN) % inventory::ContainerCount; + else if (slot_id >= invbag::BANK_BAGS_BEGIN && slot_id <= invbag::BANK_BAGS_END) { + index = (slot_id - invbag::BANK_BAGS_BEGIN) % invbag::SLOT_COUNT; } - else if (slot_id >= legacy::SHARED_BANK_BAGS_BEGIN && slot_id <= legacy::SHARED_BANK_BAGS_END) { - index = (slot_id - legacy::SHARED_BANK_BAGS_BEGIN) % inventory::ContainerCount; + else if (slot_id >= invbag::SHARED_BANK_BAGS_BEGIN && slot_id <= invbag::SHARED_BANK_BAGS_END) { + index = (slot_id - invbag::SHARED_BANK_BAGS_BEGIN) % invbag::SLOT_COUNT; } - else if (slot_id >= legacy::TRADE_BAGS_BEGIN && slot_id <= legacy::TRADE_BAGS_END) { - index = (slot_id - legacy::TRADE_BAGS_BEGIN) % inventory::ContainerCount; + else if (slot_id >= invbag::TRADE_BAGS_BEGIN && slot_id <= invbag::TRADE_BAGS_END) { + index = (slot_id - invbag::TRADE_BAGS_BEGIN) % invbag::SLOT_COUNT; } - else if (slot_id >= legacy::WORLD_BEGIN && slot_id <= legacy::WORLD_END) { - index = (slot_id - legacy::WORLD_BEGIN); // % inventory::ContainerCount; - not needed since range is 10 slots + else if (slot_id >= invslot::WORLD_BEGIN && slot_id <= invslot::WORLD_END) { + index = (slot_id - invslot::WORLD_BEGIN); // % invbag::SLOT_COUNT; - not needed since range is 10 slots } return index; @@ -892,23 +907,23 @@ int16 EQEmu::InventoryProfile::CalcSlotFromMaterial(uint8 material) switch (material) { case textures::armorHead: - return inventory::slotHead; + return invslot::slotHead; case textures::armorChest: - return inventory::slotChest; + return invslot::slotChest; case textures::armorArms: - return inventory::slotArms; + return invslot::slotArms; case textures::armorWrist: - return inventory::slotWrist1; // there's 2 bracers, only one bracer material + return invslot::slotWrist1; // there's 2 bracers, only one bracer material case textures::armorHands: - return inventory::slotHands; + return invslot::slotHands; case textures::armorLegs: - return inventory::slotLegs; + return invslot::slotLegs; case textures::armorFeet: - return inventory::slotFeet; + return invslot::slotFeet; case textures::weaponPrimary: - return inventory::slotPrimary; + return invslot::slotPrimary; case textures::weaponSecondary: - return inventory::slotSecondary; + return invslot::slotSecondary; default: return INVALID_INDEX; } @@ -918,24 +933,24 @@ uint8 EQEmu::InventoryProfile::CalcMaterialFromSlot(int16 equipslot) { switch (equipslot) { - case inventory::slotHead: + case invslot::slotHead: return textures::armorHead; - case inventory::slotChest: + case invslot::slotChest: return textures::armorChest; - case inventory::slotArms: + case invslot::slotArms: return textures::armorArms; - case inventory::slotWrist1: + case invslot::slotWrist1: //case SLOT_BRACER02: // non-live behavior return textures::armorWrist; - case inventory::slotHands: + case invslot::slotHands: return textures::armorHands; - case inventory::slotLegs: + case invslot::slotLegs: return textures::armorLegs; - case inventory::slotFeet: + case invslot::slotFeet: return textures::armorFeet; - case inventory::slotPrimary: + case invslot::slotPrimary: return textures::weaponPrimary; - case inventory::slotSecondary: + case invslot::slotSecondary: return textures::weaponSecondary; default: return textures::materialInvalid; @@ -962,11 +977,11 @@ bool EQEmu::InventoryProfile::CanItemFitInContainer(const ItemData *ItemToTry, c bool EQEmu::InventoryProfile::SupportsClickCasting(int16 slot_id) { // there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range - if ((uint16)slot_id <= legacy::GENERAL_END || slot_id == inventory::slotPowerSource) + if ((uint16)slot_id <= invslot::GENERAL_END || slot_id == invslot::SLOT_POWER_SOURCE) { return true; } - else if (slot_id >= legacy::GENERAL_BAGS_BEGIN && slot_id <= legacy::GENERAL_BAGS_END) + else if (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END) { if (inventory::Lookup(m_mob_version)->AllowClickCastFromBag) return true; @@ -977,7 +992,7 @@ bool EQEmu::InventoryProfile::SupportsClickCasting(int16 slot_id) bool EQEmu::InventoryProfile::SupportsPotionBeltCasting(int16 slot_id) { - if ((uint16)slot_id <= legacy::GENERAL_END || slot_id == inventory::slotPowerSource || (slot_id >= legacy::GENERAL_BAGS_BEGIN && slot_id <= legacy::GENERAL_BAGS_END)) + if ((uint16)slot_id <= invslot::GENERAL_END || slot_id == invslot::SLOT_POWER_SOURCE || (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END)) return true; return false; @@ -986,11 +1001,11 @@ bool EQEmu::InventoryProfile::SupportsPotionBeltCasting(int16 slot_id) // Test whether a given slot can support a container item bool EQEmu::InventoryProfile::SupportsContainers(int16 slot_id) { - if ((slot_id == inventory::slotCursor) || - (slot_id >= legacy::GENERAL_BEGIN && slot_id <= legacy::GENERAL_END) || - (slot_id >= legacy::BANK_BEGIN && slot_id <= legacy::BANK_END) || - (slot_id >= legacy::SHARED_BANK_BEGIN && slot_id <= legacy::SHARED_BANK_END) || - (slot_id >= legacy::TRADE_BEGIN && slot_id <= legacy::TRADE_END) + if ((slot_id == invslot::slotCursor) || + (slot_id >= invslot::GENERAL_BEGIN && slot_id <= invslot::GENERAL_END) || + (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) || + (slot_id >= invslot::SHARED_BANK_BEGIN && slot_id <= invslot::SHARED_BANK_END) || + (slot_id >= invslot::TRADE_BEGIN && slot_id <= invslot::TRADE_END) ) { return true; } @@ -1028,7 +1043,7 @@ int EQEmu::InventoryProfile::GetSlotByItemInst(ItemInstance *inst) { } if (m_cursor.peek_front() == inst) { - return inventory::slotCursor; + return invslot::slotCursor; } return INVALID_INDEX; @@ -1039,8 +1054,8 @@ uint8 EQEmu::InventoryProfile::FindBrightestLightType() uint8 brightest_light_type = 0; for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) { - if ((iter->first < legacy::EQUIPMENT_BEGIN || iter->first > legacy::EQUIPMENT_END) && iter->first != inventory::slotPowerSource) { continue; } - if (iter->first == inventory::slotAmmo) { continue; } + if ((iter->first < invslot::EQUIPMENT_BEGIN || iter->first > invslot::EQUIPMENT_END) && iter->first != invslot::SLOT_POWER_SOURCE) { continue; } + if (iter->first == invslot::slotAmmo) { continue; } auto inst = iter->second; if (inst == nullptr) { continue; } @@ -1053,7 +1068,7 @@ uint8 EQEmu::InventoryProfile::FindBrightestLightType() uint8 general_light_type = 0; for (auto iter = m_inv.begin(); iter != m_inv.end(); ++iter) { - if (iter->first < legacy::GENERAL_BEGIN || iter->first > legacy::GENERAL_END) { continue; } + if (iter->first < invslot::GENERAL_BEGIN || iter->first > invslot::GENERAL_END) { continue; } auto inst = iter->second; if (inst == nullptr) { continue; } @@ -1184,33 +1199,33 @@ int16 EQEmu::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst) int16 result = INVALID_INDEX; int16 parentSlot = INVALID_INDEX; - if (slot_id == inventory::slotCursor) { + if (slot_id == invslot::slotCursor) { // Replace current item on cursor, if exists m_cursor.pop(); // no memory delete, clients of this function know what they are doing m_cursor.push_front(inst); result = slot_id; } - else if ((slot_id >= legacy::EQUIPMENT_BEGIN && slot_id <= legacy::EQUIPMENT_END) || (slot_id == inventory::slotPowerSource)) { + else if ((slot_id >= invslot::EQUIPMENT_BEGIN && slot_id <= invslot::EQUIPMENT_END) || (slot_id == invslot::SLOT_POWER_SOURCE)) { m_worn[slot_id] = inst; result = slot_id; } - else if ((slot_id >= legacy::GENERAL_BEGIN && slot_id <= legacy::GENERAL_END)) { + else if ((slot_id >= invslot::GENERAL_BEGIN && slot_id <= invslot::GENERAL_END)) { m_inv[slot_id] = inst; result = slot_id; } - else if (slot_id >= legacy::TRIBUTE_BEGIN && slot_id <= legacy::TRIBUTE_END) { + else if (slot_id >= invslot::TRIBUTE_BEGIN && slot_id <= invslot::TRIBUTE_END) { m_worn[slot_id] = inst; result = slot_id; } - else if (slot_id >= legacy::BANK_BEGIN && slot_id <= legacy::BANK_END) { + else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) { m_bank[slot_id] = inst; result = slot_id; } - else if (slot_id >= legacy::SHARED_BANK_BEGIN && slot_id <= legacy::SHARED_BANK_END) { + else if (slot_id >= invslot::SHARED_BANK_BEGIN && slot_id <= invslot::SHARED_BANK_END) { m_shbank[slot_id] = inst; result = slot_id; } - else if (slot_id >= legacy::TRADE_BEGIN && slot_id <= legacy::TRADE_END) { + else if (slot_id >= invslot::TRADE_BEGIN && slot_id <= invslot::TRADE_END) { m_trade[slot_id] = inst; result = slot_id; } @@ -1248,7 +1263,7 @@ int16 EQEmu::InventoryProfile::_HasItem(std::map& bucket, return iter->first; } - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { if (inst->GetAugmentItemID(index) == item_id && quantity <= 1) return legacy::SLOT_AUGMENT; } @@ -1265,7 +1280,7 @@ int16 EQEmu::InventoryProfile::_HasItem(std::map& bucket, return InventoryProfile::CalcSlotId(iter->first, bag_iter->first); } - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { if (bag_inst->GetAugmentItemID(index) == item_id && quantity <= 1) return legacy::SLOT_AUGMENT; } @@ -1293,10 +1308,10 @@ int16 EQEmu::InventoryProfile::_HasItem(ItemInstQueue& iqueue, uint32 item_id, u if (inst->GetID() == item_id) { quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); if (quantity_found >= quantity) - return inventory::slotCursor; + return invslot::slotCursor; } - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { if (inst->GetAugmentItemID(index) == item_id && quantity <= 1) return legacy::SLOT_AUGMENT; } @@ -1310,10 +1325,10 @@ int16 EQEmu::InventoryProfile::_HasItem(ItemInstQueue& iqueue, uint32 item_id, u if (bag_inst->GetID() == item_id) { quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); if (quantity_found >= quantity) - return InventoryProfile::CalcSlotId(inventory::slotCursor, bag_iter->first); + return InventoryProfile::CalcSlotId(invslot::slotCursor, bag_iter->first); } - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { if (bag_inst->GetAugmentItemID(index) == item_id && quantity <= 1) return legacy::SLOT_AUGMENT; } @@ -1370,7 +1385,7 @@ int16 EQEmu::InventoryProfile::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, u if (inst->IsClassCommon() && inst->GetItem()->ItemType == use) { quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); if (quantity_found >= quantity) - return inventory::slotCursor; + return invslot::slotCursor; } if (!inst->IsClassBag()) { continue; } @@ -1382,7 +1397,7 @@ int16 EQEmu::InventoryProfile::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, u if (bag_inst->IsClassCommon() && bag_inst->GetItem()->ItemType == use) { quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); if (quantity_found >= quantity) - return InventoryProfile::CalcSlotId(inventory::slotCursor, bag_iter->first); + return InventoryProfile::CalcSlotId(invslot::slotCursor, bag_iter->first); } } @@ -1402,7 +1417,7 @@ int16 EQEmu::InventoryProfile::_HasItemByLoreGroup(std::mapGetItem()->LoreGroup == loregroup) return iter->first; - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { auto aug_inst = inst->GetAugment(index); if (aug_inst == nullptr) { continue; } @@ -1419,7 +1434,7 @@ int16 EQEmu::InventoryProfile::_HasItemByLoreGroup(std::mapIsClassCommon() && bag_inst->GetItem()->LoreGroup == loregroup) return InventoryProfile::CalcSlotId(iter->first, bag_iter->first); - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { auto aug_inst = bag_inst->GetAugment(index); if (aug_inst == nullptr) { continue; } @@ -1440,9 +1455,9 @@ int16 EQEmu::InventoryProfile::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 if (inst == nullptr) { continue; } if (inst->GetItem()->LoreGroup == loregroup) - return inventory::slotCursor; + return invslot::slotCursor; - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { auto aug_inst = inst->GetAugment(index); if (aug_inst == nullptr) { continue; } @@ -1457,9 +1472,9 @@ int16 EQEmu::InventoryProfile::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 if (bag_inst == nullptr) { continue; } if (bag_inst->IsClassCommon() && bag_inst->GetItem()->LoreGroup == loregroup) - return InventoryProfile::CalcSlotId(inventory::slotCursor, bag_iter->first); + return InventoryProfile::CalcSlotId(invslot::slotCursor, bag_iter->first); - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { auto aug_inst = bag_inst->GetAugment(index); if (aug_inst == nullptr) { continue; } diff --git a/common/inventory_profile.h b/common/inventory_profile.h index 5be7ed8d3..1f28b00f9 100644 --- a/common/inventory_profile.h +++ b/common/inventory_profile.h @@ -92,22 +92,13 @@ namespace EQEmu } ~InventoryProfile(); - bool SetInventoryVersion(versions::MobVersion inventory_version) { - if (!m_mob_version_set) { - m_mob_version = versions::ValidateMobVersion(inventory_version); - m_lookup = inventory::Lookup(m_mob_version); - m_mob_version_set = true; - return true; - } - else { - m_lookup = inventory::Lookup(versions::MobVersion::Unknown); - return false; - } - } + bool SetInventoryVersion(versions::MobVersion inventory_version); bool SetInventoryVersion(versions::ClientVersion client_version) { return SetInventoryVersion(versions::ConvertClientVersionToMobVersion(client_version)); } versions::MobVersion InventoryVersion() { return m_mob_version; } + const inventory::LookupEntry* GetLookup() const { return m_lookup; } + static void CleanDirty(); static void MarkDirty(ItemInstance *inst); @@ -163,7 +154,7 @@ namespace EQEmu // Locate an available inventory slot int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false); - int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = legacy::GENERAL_BEGIN, uint8 bag_start = inventory::containerBegin); + int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN); // Calculate slot_id for an item within a bag static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id diff --git a/common/inventory_slot.cpp b/common/inventory_slot.cpp index 8158e0bbf..ac4aaa412 100644 --- a/common/inventory_slot.cpp +++ b/common/inventory_slot.cpp @@ -25,23 +25,23 @@ int8 EQEmu::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index) { switch (slot_index) { - case slotHead: + case invslot::slotHead: return textures::armorHead; - case slotChest: + case invslot::slotChest: return textures::armorChest; - case slotArms: + case invslot::slotArms: return textures::armorArms; - case slotWrist1: + case invslot::slotWrist1: return textures::armorWrist; - case slotHands: + case invslot::slotHands: return textures::armorHands; - case slotLegs: + case invslot::slotLegs: return textures::armorLegs; - case slotFeet: + case invslot::slotFeet: return textures::armorFeet; - case slotPrimary: + case invslot::slotPrimary: return textures::weaponPrimary; - case slotSecondary: + case invslot::slotSecondary: return textures::weaponSecondary; default: return textures::textureInvalid; @@ -50,7 +50,7 @@ int8 EQEmu::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index) int8 EQEmu::inventory::ConvertEquipmentSlotToTextureIndex(const InventorySlot& inventory_slot) { - if ((!inventory_slot.Typeless() && !inventory_slot.IsTypeIndex(typePossessions)) || !inventory_slot.IsContainerIndex(containerInvalid) || !inventory_slot.IsSocketIndex(socketInvalid)) + if ((!inventory_slot.Typeless() && !inventory_slot.IsTypeIndex(invtype::typePossessions)) || !inventory_slot.IsContainerIndex(invbag::SLOT_INVALID) || !inventory_slot.IsSocketIndex(invaug::SOCKET_INVALID)) return textures::textureInvalid; return ConvertEquipmentIndexToTextureIndex(inventory_slot.SlotIndex()); @@ -60,25 +60,25 @@ int16 EQEmu::inventory::ConvertTextureIndexToEquipmentIndex(int8 texture_index) { switch (texture_index) { case textures::armorHead: - return slotHead; + return invslot::slotHead; case textures::armorChest: - return slotChest; + return invslot::slotChest; case textures::armorArms: - return slotArms; + return invslot::slotArms; case textures::armorWrist: - return slotWrist1; + return invslot::slotWrist1; case textures::armorHands: - return slotHands; + return invslot::slotHands; case textures::armorLegs: - return slotLegs; + return invslot::slotLegs; case textures::armorFeet: - return slotFeet; + return invslot::slotFeet; case textures::weaponPrimary: - return slotPrimary; + return invslot::slotPrimary; case textures::weaponSecondary: - return slotSecondary; + return invslot::slotSecondary; default: - return slotInvalid; + return invslot::SLOT_INVALID; } } @@ -87,14 +87,14 @@ bool EQEmu::InventorySlot::IsValidSlot() const if (_typeless) return false; - int16 slot_count = inventory::SlotCount(_type_index); - if (!slot_count || _slot_index < inventory::slotBegin || _slot_index >= slot_count) + int16 slot_count = invtype::GetInvTypeSize(_type_index); + if (!slot_count || _slot_index < invslot::SLOT_BEGIN || _slot_index >= slot_count) return false; - if (_container_index < inventory::containerInvalid || _container_index >= inventory::ContainerCount) + if (_container_index < invbag::SLOT_INVALID || _container_index >= invbag::SLOT_COUNT) return false; - if (_socket_index < inventory::socketInvalid || _socket_index >= inventory::SocketCount) + if (_socket_index < invaug::SOCKET_INVALID || _socket_index >= invaug::SOCKET_COUNT) return false; return true; @@ -103,16 +103,16 @@ bool EQEmu::InventorySlot::IsValidSlot() const bool EQEmu::InventorySlot::IsDeleteSlot() const { if (_typeless) - return (_slot_index == inventory::slotInvalid && _container_index == inventory::containerInvalid && _socket_index == inventory::socketInvalid); + return (_slot_index == invslot::SLOT_INVALID && _container_index == invbag::SLOT_INVALID && _socket_index == invaug::SOCKET_INVALID); else - return (_type_index == inventory::typeInvalid && _slot_index == inventory::slotInvalid && _container_index == inventory::containerInvalid && _socket_index == inventory::socketInvalid); + return (_type_index == invtype::TYPE_INVALID && _slot_index == invslot::SLOT_INVALID && _container_index == invbag::SLOT_INVALID && _socket_index == invaug::SOCKET_INVALID); } bool EQEmu::InventorySlot::IsEquipmentIndex(int16 slot_index) { /*if (slot_index < inventory::EquipmentBegin || slot_index > inventory::EquipmentEnd) return false;*/ - if ((slot_index < legacy::EQUIPMENT_BEGIN || slot_index > legacy::EQUIPMENT_END) && slot_index != legacy::SLOT_POWER_SOURCE) + if ((slot_index < invslot::EQUIPMENT_BEGIN || slot_index > invslot::EQUIPMENT_END) && slot_index != invslot::SLOT_POWER_SOURCE) return false; return true; @@ -122,7 +122,7 @@ bool EQEmu::InventorySlot::IsGeneralIndex(int16 slot_index) { /*if (slot_index < inventory::GeneralBegin || slot_index > inventory::GeneralEnd) return false;*/ - if (slot_index < legacy::GENERAL_BEGIN || slot_index > legacy::GENERAL_END) + if (slot_index < invslot::GENERAL_BEGIN || slot_index > invslot::GENERAL_END) return false; return true; @@ -132,7 +132,7 @@ bool EQEmu::InventorySlot::IsCursorIndex(int16 slot_index) { /*if (slot_index != inventory::slotCursor) return false;*/ - if (slot_index != legacy::SLOT_CURSOR) + if (slot_index != invslot::slotCursor) return false; return true; @@ -142,7 +142,7 @@ bool EQEmu::InventorySlot::IsWeaponIndex(int16 slot_index) { /*if ((slot_index != inventory::slotRange) && (slot_index != inventory::slotPrimary) && (slot_index != inventory::slotSecondary)) return false;*/ - if ((slot_index != legacy::SLOT_RANGE) && (slot_index != legacy::SLOT_PRIMARY) && (slot_index != legacy::SLOT_SECONDARY)) + if ((slot_index != invslot::slotRange) && (slot_index != invslot::slotPrimary) && (slot_index != invslot::slotSecondary)) return false; return true; @@ -151,15 +151,15 @@ bool EQEmu::InventorySlot::IsWeaponIndex(int16 slot_index) bool EQEmu::InventorySlot::IsTextureIndex(int16 slot_index) { switch (slot_index) { - case inventory::slotHead: - case inventory::slotChest: - case inventory::slotArms: - case inventory::slotWrist1: - case inventory::slotHands: - case inventory::slotLegs: - case inventory::slotFeet: - case inventory::slotPrimary: - case inventory::slotSecondary: + case invslot::slotHead: + case invslot::slotChest: + case invslot::slotArms: + case invslot::slotWrist1: + case invslot::slotHands: + case invslot::slotLegs: + case invslot::slotFeet: + case invslot::slotPrimary: + case invslot::slotSecondary: return true; default: return false; @@ -169,13 +169,13 @@ bool EQEmu::InventorySlot::IsTextureIndex(int16 slot_index) bool EQEmu::InventorySlot::IsTintableIndex(int16 slot_index) { switch (slot_index) { - case inventory::slotHead: - case inventory::slotChest: - case inventory::slotArms: - case inventory::slotWrist1: - case inventory::slotHands: - case inventory::slotLegs: - case inventory::slotFeet: + case invslot::slotHead: + case invslot::slotChest: + case invslot::slotArms: + case invslot::slotWrist1: + case invslot::slotHands: + case invslot::slotLegs: + case invslot::slotFeet: return true; default: return false; @@ -184,10 +184,10 @@ bool EQEmu::InventorySlot::IsTintableIndex(int16 slot_index) bool EQEmu::InventorySlot::IsEquipmentSlot() const { - if (!_typeless && (_type_index != inventory::typePossessions)) + if (!_typeless && (_type_index != invtype::typePossessions)) return false; - if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid)) + if ((_container_index != invbag::SLOT_INVALID) || (_socket_index != invaug::SOCKET_INVALID)) return false; return IsEquipmentIndex(_slot_index); @@ -195,10 +195,10 @@ bool EQEmu::InventorySlot::IsEquipmentSlot() const bool EQEmu::InventorySlot::IsGeneralSlot() const { - if (!_typeless && (_type_index != inventory::typePossessions)) + if (!_typeless && (_type_index != invtype::typePossessions)) return false; - if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid)) + if ((_container_index != invbag::SLOT_INVALID) || (_socket_index != invaug::SOCKET_INVALID)) return false; return IsGeneralIndex(_socket_index); @@ -206,10 +206,10 @@ bool EQEmu::InventorySlot::IsGeneralSlot() const bool EQEmu::InventorySlot::IsCursorSlot() const { - if (!_typeless && (_type_index != inventory::typePossessions)) + if (!_typeless && (_type_index != invtype::typePossessions)) return false; - if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid)) + if ((_container_index != invbag::SLOT_INVALID) || (_socket_index != invaug::SOCKET_INVALID)) return false; return IsCursorIndex(_slot_index); @@ -217,10 +217,10 @@ bool EQEmu::InventorySlot::IsCursorSlot() const bool EQEmu::InventorySlot::IsWeaponSlot() const { - if (!_typeless && (_type_index != inventory::typePossessions)) + if (!_typeless && (_type_index != invtype::typePossessions)) return false; - if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid)) + if ((_container_index != invbag::SLOT_INVALID) || (_socket_index != invaug::SOCKET_INVALID)) return false; return IsWeaponIndex(_slot_index); @@ -228,10 +228,10 @@ bool EQEmu::InventorySlot::IsWeaponSlot() const bool EQEmu::InventorySlot::IsTextureSlot() const { - if (!_typeless && (_type_index != inventory::typePossessions)) + if (!_typeless && (_type_index != invtype::typePossessions)) return false; - if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid)) + if ((_container_index != invbag::SLOT_INVALID) || (_socket_index != invaug::SOCKET_INVALID)) return false; return IsTextureIndex(_slot_index); @@ -239,10 +239,10 @@ bool EQEmu::InventorySlot::IsTextureSlot() const bool EQEmu::InventorySlot::IsTintableSlot() const { - if (!_typeless && (_type_index != inventory::typePossessions)) + if (!_typeless && (_type_index != invtype::typePossessions)) return false; - if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid)) + if ((_container_index != invbag::SLOT_INVALID) || (_socket_index != invaug::SOCKET_INVALID)) return false; return IsTintableIndex(_slot_index); @@ -250,13 +250,13 @@ bool EQEmu::InventorySlot::IsTintableSlot() const bool EQEmu::InventorySlot::IsSlot() const { - if (!_typeless && (_type_index == inventory::typeInvalid)) + if (!_typeless && (_type_index == invtype::TYPE_INVALID)) return false; - if (_slot_index == inventory::slotInvalid) + if (_slot_index == invslot::SLOT_INVALID) return false; - if (_container_index != inventory::containerInvalid) + if (_container_index != invbag::SLOT_INVALID) return false; - if (_socket_index != inventory::socketInvalid) + if (_socket_index != invaug::SOCKET_INVALID) return false; return true; @@ -264,13 +264,13 @@ bool EQEmu::InventorySlot::IsSlot() const bool EQEmu::InventorySlot::IsSlotSocket() const { - if (!_typeless && (_type_index == inventory::typeInvalid)) + if (!_typeless && (_type_index == invtype::TYPE_INVALID)) return false; - if (_slot_index == inventory::slotInvalid) + if (_slot_index == invslot::SLOT_INVALID) return false; - if (_container_index != inventory::containerInvalid) + if (_container_index != invbag::SLOT_INVALID) return false; - if (_socket_index == inventory::socketInvalid) + if (_socket_index == invaug::SOCKET_INVALID) return false; return true; @@ -278,13 +278,13 @@ bool EQEmu::InventorySlot::IsSlotSocket() const bool EQEmu::InventorySlot::IsContainer() const { - if (!_typeless && (_type_index == inventory::typeInvalid)) + if (!_typeless && (_type_index == invtype::TYPE_INVALID)) return false; - if (_slot_index == inventory::slotInvalid) + if (_slot_index == invslot::SLOT_INVALID) return false; - if (_container_index == inventory::containerInvalid) + if (_container_index == invbag::SLOT_INVALID) return false; - if (_socket_index != inventory::socketInvalid) + if (_socket_index != invaug::SOCKET_INVALID) return false; return true; @@ -292,13 +292,13 @@ bool EQEmu::InventorySlot::IsContainer() const bool EQEmu::InventorySlot::IsContainerSocket() const { - if (!_typeless && (_type_index == inventory::typeInvalid)) + if (!_typeless && (_type_index == invtype::TYPE_INVALID)) return false; - if (_slot_index == inventory::slotInvalid) + if (_slot_index == invslot::SLOT_INVALID) return false; - if (_container_index == inventory::containerInvalid) + if (_container_index == invbag::SLOT_INVALID) return false; - if (_socket_index == inventory::socketInvalid) + if (_socket_index == invaug::SOCKET_INVALID) return false; return true; @@ -332,10 +332,10 @@ const std::string EQEmu::InventorySlot::ToName() const void EQEmu::InventorySlot::SetInvalidSlot() { - _type_index = inventory::typeInvalid; - _slot_index = inventory::slotInvalid; - _container_index = inventory::containerInvalid; - _socket_index = inventory::socketInvalid; + _type_index = invtype::TYPE_INVALID; + _slot_index = invslot::SLOT_INVALID; + _container_index = invbag::SLOT_INVALID; + _socket_index = invaug::SOCKET_INVALID; } //bool EQEmu::InventorySlot::IsBonusIndex(int16 slot_index) diff --git a/common/inventory_slot.h b/common/inventory_slot.h index 695282e34..967673f99 100644 --- a/common/inventory_slot.h +++ b/common/inventory_slot.h @@ -35,10 +35,10 @@ namespace EQEmu class InventorySlot { public: - InventorySlot() : _type_index(inventory::typeInvalid), _slot_index(inventory::slotInvalid), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { } - InventorySlot(int16 type_index) : _type_index(type_index), _slot_index(inventory::slotInvalid), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { } - InventorySlot(int16 type_index, int16 parent_index) : _type_index(type_index), _slot_index(parent_index), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { } - InventorySlot(int16 type_index, int16 parent_index, int16 bag_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(inventory::socketInvalid), _typeless(false) { } + InventorySlot() : _type_index(invtype::TYPE_INVALID), _slot_index(invslot::SLOT_INVALID), _container_index(invbag::SLOT_INVALID), _socket_index(invaug::SOCKET_INVALID), _typeless(false) { } + InventorySlot(int16 type_index) : _type_index(type_index), _slot_index(invslot::SLOT_INVALID), _container_index(invbag::SLOT_INVALID), _socket_index(invaug::SOCKET_INVALID), _typeless(false) { } + InventorySlot(int16 type_index, int16 parent_index) : _type_index(type_index), _slot_index(parent_index), _container_index(invbag::SLOT_INVALID), _socket_index(invaug::SOCKET_INVALID), _typeless(false) { } + InventorySlot(int16 type_index, int16 parent_index, int16 bag_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(invaug::SOCKET_INVALID), _typeless(false) { } InventorySlot(int16 type_index, int16 parent_index, int16 bag_index, int16 aug_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(aug_index), _typeless(false) { } InventorySlot(const InventorySlot& r) : _type_index(r._type_index), _slot_index(r._slot_index), _container_index(r._container_index), _socket_index(r._socket_index), _typeless(r._typeless) { } InventorySlot(int16 type_index, const InventorySlot& r) : _type_index(type_index), _slot_index(r._slot_index), _container_index(r._container_index), _socket_index(r._socket_index), _typeless(false) { } @@ -90,15 +90,15 @@ namespace EQEmu void SetInvalidSlot(); - void SetTypeInvalid() { _type_index = inventory::typeInvalid; } - void SetSlotInvalid() { _slot_index = inventory::slotInvalid; } - void SetContainerInvalid() { _container_index = inventory::containerInvalid; } - void SetSocketInvalid() { _socket_index = inventory::socketInvalid; } + void SetTypeInvalid() { _type_index = invtype::TYPE_INVALID; } + void SetSlotInvalid() { _slot_index = invslot::SLOT_INVALID; } + void SetContainerInvalid() { _container_index = invbag::SLOT_INVALID; } + void SetSocketInvalid() { _socket_index = invaug::SOCKET_INVALID; } - void SetTypeBegin() { _type_index = inventory::typeBegin; } - void SetSlotBegin() { _slot_index = inventory::slotBegin; } - void SetContainerBegin() { _container_index = inventory::containerBegin; } - void SetSocketBegin() { _socket_index = inventory::socketBegin; } + void SetTypeBegin() { _type_index = invtype::TYPE_BEGIN; } + void SetSlotBegin() { _slot_index = invslot::SLOT_BEGIN; } + void SetContainerBegin() { _container_index = invbag::SLOT_BEGIN; } + void SetSocketBegin() { _socket_index = invaug::SOCKET_BEGIN; } void IncrementType() { ++_type_index; } void IncrementSlot() { ++_slot_index; } diff --git a/common/item_data.h b/common/item_data.h index ae7e3bbdb..45ca8e9e0 100644 --- a/common/item_data.h +++ b/common/item_data.h @@ -464,9 +464,9 @@ namespace EQEmu int32 FactionAmt4; // Faction Amt 4 char CharmFile[32]; // ? uint32 AugType; - uint8 AugSlotType[inventory::SocketCount]; // RoF: Augment Slot 1-6 Type - uint8 AugSlotVisible[inventory::SocketCount]; // RoF: Augment Slot 1-6 Visible - uint8 AugSlotUnk2[inventory::SocketCount]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related + uint8 AugSlotType[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Type + uint8 AugSlotVisible[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Visible + uint8 AugSlotUnk2[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related uint32 LDoNTheme; uint32 LDoNPrice; uint32 LDoNSold; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index a2860f3e5..922d0e032 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -273,8 +273,8 @@ bool EQEmu::ItemInstance::IsEquipable(int16 slot_id) const // another "shouldn't do" fix..will be fixed in future updates (requires code and database work) int16 use_slot = INVALID_INDEX; - if (slot_id == inventory::slotPowerSource) { use_slot = inventory::slotGeneral1; } - if ((uint16)slot_id <= legacy::EQUIPMENT_END) { use_slot = slot_id; } + if (slot_id == invslot::SLOT_POWER_SOURCE) { use_slot = invslot::slotGeneral1; } + if ((uint16)slot_id <= invslot::EQUIPMENT_END) { use_slot = slot_id; } if (use_slot != INVALID_INDEX) { if (m_item->Slots & (1 << use_slot)) @@ -289,7 +289,7 @@ bool EQEmu::ItemInstance::IsAugmentable() const if (!m_item) return false; - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { if (m_item->AugSlotType[index] != 0) return true; } @@ -303,8 +303,8 @@ bool EQEmu::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const { if (!m_item || !m_item->IsClassCommon()) return false; - int index = legacy::EQUIPMENT_BEGIN; - for (; index <= inventory::slotGeneral1; ++index) { // MainGeneral1 should be legacy::EQUIPMENT_END + int index = invslot::EQUIPMENT_BEGIN; + for (; index <= invslot::slotGeneral1; ++index) { // MainGeneral1 should be legacy::EQUIPMENT_END if (m_item->Slots & (1 << index)) { if (aug_wear_slots & (1 << index)) break; @@ -319,14 +319,14 @@ int8 EQEmu::ItemInstance::AvailableAugmentSlot(int32 augtype) const if (!m_item || !m_item->IsClassCommon()) return INVALID_INDEX; - int index = inventory::socketBegin; - for (; index < inventory::SocketCount; ++index) { + int index = invaug::SOCKET_BEGIN; + for (; index <= invaug::SOCKET_END; ++index) { if (GetItem(index)) { continue; } if (augtype == -1 || (m_item->AugSlotType[index] && ((1 << (m_item->AugSlotType[index] - 1)) & augtype))) break; } - return (index < inventory::SocketCount) ? index : INVALID_INDEX; + return (index <= invaug::SOCKET_END) ? index : INVALID_INDEX; } bool EQEmu::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const @@ -469,7 +469,7 @@ uint8 EQEmu::ItemInstance::FirstOpenSlot() const return INVALID_INDEX; uint8 slots = m_item->BagSlots, i; - for (i = inventory::containerBegin; i < slots; i++) { + for (i = invbag::SLOT_BEGIN; i < slots; i++) { if (!GetItem(i)) break; } @@ -486,7 +486,7 @@ uint8 EQEmu::ItemInstance::GetTotalItemCount() const if (m_item && !m_item->IsClassBag()) { return item_count; } - for (int index = inventory::containerBegin; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } } + for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } } return item_count; } @@ -496,7 +496,7 @@ bool EQEmu::ItemInstance::IsNoneEmptyContainer() if (!m_item || !m_item->IsClassBag()) return false; - for (int index = inventory::containerBegin; index < m_item->BagSlots; ++index) { + for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) return true; } @@ -518,7 +518,7 @@ EQEmu::ItemInstance* EQEmu::ItemInstance::GetOrnamentationAug(int32 ornamentatio if (!m_item || !m_item->IsClassCommon()) { return nullptr; } if (ornamentationAugtype == 0) { return nullptr; } - for (int i = inventory::socketBegin; i < inventory::SocketCount; i++) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) { if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype) { @@ -686,7 +686,7 @@ bool EQEmu::ItemInstance::IsAugmented() if (!m_item || !m_item->IsClassCommon()) return false; - for (int index = inventory::socketBegin; index < inventory::SocketCount; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { if (GetAugmentItemID(index)) return true; } @@ -814,8 +814,8 @@ bool EQEmu::ItemInstance::IsSlotAllowed(int16 slot_id) const { if (!m_item) { return false; } else if (InventoryProfile::SupportsContainers(slot_id)) { return true; } else if (m_item->Slots & (1 << slot_id)) { return true; } - else if (slot_id == inventory::slotPowerSource && (m_item->Slots & (1 << 22))) { return true; } // got lazy... - else if (slot_id != inventory::slotPowerSource && slot_id > legacy::EQUIPMENT_END) { return true; } + else if (slot_id == invslot::SLOT_POWER_SOURCE && (m_item->Slots & (1 << 22))) { return true; } // got lazy... + else if (slot_id != invslot::SLOT_POWER_SOURCE && slot_id > invslot::EQUIPMENT_END) { return true; } else { return false; } } @@ -993,7 +993,7 @@ int EQEmu::ItemInstance::GetItemArmorClass(bool augments) const if (item) { ac = item->AC; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) ac += GetAugment(i)->GetItemArmorClass(); } @@ -1035,7 +1035,7 @@ int EQEmu::ItemInstance::GetItemElementalDamage(int &magic, int &fire, int &cold } if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) GetAugment(i)->GetItemElementalDamage(magic, fire, cold, poison, disease, chromatic, prismatic, physical, corruption); } @@ -1052,7 +1052,7 @@ int EQEmu::ItemInstance::GetItemElementalFlag(bool augments) const return flag; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) { + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) { if (GetAugment(i)) flag = GetAugment(i)->GetItemElementalFlag(); if (flag) @@ -1073,7 +1073,7 @@ int EQEmu::ItemInstance::GetItemElementalDamage(bool augments) const return damage; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) { + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) { if (GetAugment(i)) damage = GetAugment(i)->GetItemElementalDamage(); if (damage) @@ -1092,7 +1092,7 @@ int EQEmu::ItemInstance::GetItemRecommendedLevel(bool augments) const level = item->RecLevel; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) { + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) { int temp = 0; if (GetAugment(i)) { temp = GetAugment(i)->GetItemRecommendedLevel(); @@ -1114,7 +1114,7 @@ int EQEmu::ItemInstance::GetItemRequiredLevel(bool augments) const level = item->ReqLevel; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) { + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) { int temp = 0; if (GetAugment(i)) { temp = GetAugment(i)->GetItemRequiredLevel(); @@ -1136,7 +1136,7 @@ int EQEmu::ItemInstance::GetItemWeaponDamage(bool augments) const damage = item->Damage; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) damage += GetAugment(i)->GetItemWeaponDamage(); } @@ -1152,7 +1152,7 @@ int EQEmu::ItemInstance::GetItemBackstabDamage(bool augments) const damage = item->BackstabDmg; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) damage += GetAugment(i)->GetItemBackstabDamage(); } @@ -1170,7 +1170,7 @@ int EQEmu::ItemInstance::GetItemBaneDamageBody(bool augments) const return body; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) { body = GetAugment(i)->GetItemBaneDamageBody(); if (body) @@ -1191,7 +1191,7 @@ int EQEmu::ItemInstance::GetItemBaneDamageRace(bool augments) const return race; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) { race = GetAugment(i)->GetItemBaneDamageRace(); if (race) @@ -1211,7 +1211,7 @@ int EQEmu::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) damage += item->BaneDmgAmt; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) damage += GetAugment(i)->GetItemBaneDamageBody(against); } @@ -1228,7 +1228,7 @@ int EQEmu::ItemInstance::GetItemBaneDamageRace(uint16 against, bool augments) co damage += item->BaneDmgRaceAmt; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) damage += GetAugment(i)->GetItemBaneDamageRace(against); } @@ -1244,7 +1244,7 @@ int EQEmu::ItemInstance::GetItemMagical(bool augments) const return 1; if (augments) { - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i) && GetAugment(i)->GetItemMagical()) return 1; } @@ -1259,7 +1259,7 @@ int EQEmu::ItemInstance::GetItemHP(bool augments) const if (item) { hp = item->HP; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) hp += GetAugment(i)->GetItemHP(); } @@ -1273,7 +1273,7 @@ int EQEmu::ItemInstance::GetItemMana(bool augments) const if (item) { mana = item->Mana; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) mana += GetAugment(i)->GetItemMana(); } @@ -1287,7 +1287,7 @@ int EQEmu::ItemInstance::GetItemEndur(bool augments) const if (item) { endur = item->Endur; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) endur += GetAugment(i)->GetItemEndur(); } @@ -1301,7 +1301,7 @@ int EQEmu::ItemInstance::GetItemAttack(bool augments) const if (item) { atk = item->Attack; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) atk += GetAugment(i)->GetItemAttack(); } @@ -1315,7 +1315,7 @@ int EQEmu::ItemInstance::GetItemStr(bool augments) const if (item) { str = item->AStr; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) str += GetAugment(i)->GetItemStr(); } @@ -1329,7 +1329,7 @@ int EQEmu::ItemInstance::GetItemSta(bool augments) const if (item) { sta = item->ASta; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) sta += GetAugment(i)->GetItemSta(); } @@ -1343,7 +1343,7 @@ int EQEmu::ItemInstance::GetItemDex(bool augments) const if (item) { total = item->ADex; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemDex(); } @@ -1357,7 +1357,7 @@ int EQEmu::ItemInstance::GetItemAgi(bool augments) const if (item) { total = item->AAgi; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemAgi(); } @@ -1371,7 +1371,7 @@ int EQEmu::ItemInstance::GetItemInt(bool augments) const if (item) { total = item->AInt; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemInt(); } @@ -1385,7 +1385,7 @@ int EQEmu::ItemInstance::GetItemWis(bool augments) const if (item) { total = item->AWis; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemWis(); } @@ -1399,7 +1399,7 @@ int EQEmu::ItemInstance::GetItemCha(bool augments) const if (item) { total = item->ACha; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemCha(); } @@ -1413,7 +1413,7 @@ int EQEmu::ItemInstance::GetItemMR(bool augments) const if (item) { total = item->MR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemMR(); } @@ -1427,7 +1427,7 @@ int EQEmu::ItemInstance::GetItemFR(bool augments) const if (item) { total = item->FR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemFR(); } @@ -1441,7 +1441,7 @@ int EQEmu::ItemInstance::GetItemCR(bool augments) const if (item) { total = item->CR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemCR(); } @@ -1455,7 +1455,7 @@ int EQEmu::ItemInstance::GetItemPR(bool augments) const if (item) { total = item->PR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemPR(); } @@ -1469,7 +1469,7 @@ int EQEmu::ItemInstance::GetItemDR(bool augments) const if (item) { total = item->DR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemDR(); } @@ -1483,7 +1483,7 @@ int EQEmu::ItemInstance::GetItemCorrup(bool augments) const if (item) { total = item->SVCorruption; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemCorrup(); } @@ -1497,7 +1497,7 @@ int EQEmu::ItemInstance::GetItemHeroicStr(bool augments) const if (item) { total = item->HeroicStr; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicStr(); } @@ -1511,7 +1511,7 @@ int EQEmu::ItemInstance::GetItemHeroicSta(bool augments) const if (item) { total = item->HeroicSta; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicSta(); } @@ -1525,7 +1525,7 @@ int EQEmu::ItemInstance::GetItemHeroicDex(bool augments) const if (item) { total = item->HeroicDex; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicDex(); } @@ -1539,7 +1539,7 @@ int EQEmu::ItemInstance::GetItemHeroicAgi(bool augments) const if (item) { total = item->HeroicAgi; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicAgi(); } @@ -1553,7 +1553,7 @@ int EQEmu::ItemInstance::GetItemHeroicInt(bool augments) const if (item) { total = item->HeroicInt; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicInt(); } @@ -1567,7 +1567,7 @@ int EQEmu::ItemInstance::GetItemHeroicWis(bool augments) const if (item) { total = item->HeroicWis; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicWis(); } @@ -1581,7 +1581,7 @@ int EQEmu::ItemInstance::GetItemHeroicCha(bool augments) const if (item) { total = item->HeroicCha; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicCha(); } @@ -1595,7 +1595,7 @@ int EQEmu::ItemInstance::GetItemHeroicMR(bool augments) const if (item) { total = item->HeroicMR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicMR(); } @@ -1609,7 +1609,7 @@ int EQEmu::ItemInstance::GetItemHeroicFR(bool augments) const if (item) { total = item->HeroicFR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicFR(); } @@ -1623,7 +1623,7 @@ int EQEmu::ItemInstance::GetItemHeroicCR(bool augments) const if (item) { total = item->HeroicCR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicCR(); } @@ -1637,7 +1637,7 @@ int EQEmu::ItemInstance::GetItemHeroicPR(bool augments) const if (item) { total = item->HeroicPR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicPR(); } @@ -1651,7 +1651,7 @@ int EQEmu::ItemInstance::GetItemHeroicDR(bool augments) const if (item) { total = item->HeroicDR; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicDR(); } @@ -1665,7 +1665,7 @@ int EQEmu::ItemInstance::GetItemHeroicCorrup(bool augments) const if (item) { total = item->HeroicSVCorrup; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) total += GetAugment(i)->GetItemHeroicCorrup(); } @@ -1679,7 +1679,7 @@ int EQEmu::ItemInstance::GetItemHaste(bool augments) const if (item) { total = item->Haste; if (augments) - for (int i = inventory::socketBegin; i < inventory::SocketCount; ++i) + for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) if (GetAugment(i)) { int temp = GetAugment(i)->GetItemHaste(); if (temp > total) diff --git a/common/misc_functions.cpp b/common/misc_functions.cpp index e31da211f..a85ca9c2b 100644 --- a/common/misc_functions.cpp +++ b/common/misc_functions.cpp @@ -275,7 +275,7 @@ float EQHtoFloat(int d) } // returns a swapped-bit value for use in client translator and inventory functions -uint32 SwapBits21and22(uint32 mask) +uint32 SwapBits21And22(uint32 mask) { static const uint32 BIT21 = 1 << 21; static const uint32 BIT22 = 1 << 22; diff --git a/common/misc_functions.h b/common/misc_functions.h index 8214c7df0..2ead697e7 100644 --- a/common/misc_functions.h +++ b/common/misc_functions.h @@ -69,7 +69,7 @@ int FloatToEQSpeedRun(float d); // brings heading back into EQ angles range float FixHeading(float in); -uint32 SwapBits21and22(uint32 mask); +uint32 SwapBits21And22(uint32 mask); uint32 Catch22(uint32 mask); // macro to catch fp errors (provided by noudness) diff --git a/common/net/console_server_connection.cpp b/common/net/console_server_connection.cpp index 249817818..7cff94cbb 100644 --- a/common/net/console_server_connection.cpp +++ b/common/net/console_server_connection.cpp @@ -1,9 +1,9 @@ #include "console_server.h" -#include "../common/util/uuid.h" -#include "../common/net/packet.h" -#include "../common/eqemu_logsys.h" -#include "../common/servertalk.h" -#include "../common/rulesys.h" +#include "../util/uuid.h" +#include "../net/packet.h" +#include "../eqemu_logsys.h" +#include "../servertalk.h" +#include "../rulesys.h" EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent, std::shared_ptr connection) { diff --git a/common/net/daybreak_connection.cpp b/common/net/daybreak_connection.cpp index d32f9f678..73bb51e82 100644 --- a/common/net/daybreak_connection.cpp +++ b/common/net/daybreak_connection.cpp @@ -747,7 +747,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p) response.zero = 0; response.opcode = OP_SessionStatResponse; response.timestamp = request.timestamp; - response.our_timestamp = EQ::Net::HostToNetwork(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); + response.our_timestamp = EQ::Net::HostToNetwork(std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count()); response.client_sent = request.packets_sent; response.client_recv = request.packets_recv; response.server_sent = EQ::Net::HostToNetwork(m_stats.sent_packets); diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index 016ef3258..05b420133 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -68,8 +68,8 @@ namespace EQ SequencePast }; - typedef std::chrono::high_resolution_clock::time_point Timestamp; - typedef std::chrono::high_resolution_clock Clock; + typedef std::chrono::steady_clock::time_point Timestamp; + typedef std::chrono::steady_clock Clock; struct DaybreakConnectionStats { @@ -282,4 +282,4 @@ namespace EQ friend class DaybreakConnection; }; } -} \ No newline at end of file +} diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 62ef6751a..6faabf88c 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -1863,120 +1863,6 @@ namespace RoF FINISH_ENCODE(); } - /* - ENCODE(OP_OpenNewTasksWindow) - { - AvailableTaskHeader_Struct* __emu_AvailableTaskHeader; - AvailableTaskData1_Struct* __emu_AvailableTaskData1; - AvailableTaskData2_Struct* __emu_AvailableTaskData2; - AvailableTaskTrailer_Struct* __emu_AvailableTaskTrailer; - - structs::AvailableTaskHeader_Struct* __eq_AvailableTaskHeader; - structs::AvailableTaskData1_Struct* __eq_AvailableTaskData1; - structs::AvailableTaskData2_Struct* __eq_AvailableTaskData2; - structs::AvailableTaskTrailer_Struct* __eq_AvailableTaskTrailer; - - EQApplicationPacket *in = *p; - *p = nullptr; - - unsigned char *__emu_buffer = in->pBuffer; - - __emu_AvailableTaskHeader = (AvailableTaskHeader_Struct*)__emu_buffer; - - // For each task, SoF has an extra uint32 and what appears to be space for a null terminated string. - // - in->size = in->size + (__emu_AvailableTaskHeader->TaskCount * 5); - - in->pBuffer = new unsigned char[in->size]; - - unsigned char *__eq_buffer = in->pBuffer; - - __eq_AvailableTaskHeader = (structs::AvailableTaskHeader_Struct*)__eq_buffer; - - char *__eq_ptr, *__emu_Ptr; - - // Copy Header - // - // - - __eq_AvailableTaskHeader->TaskCount = __emu_AvailableTaskHeader->TaskCount; - __eq_AvailableTaskHeader->unknown1 = __emu_AvailableTaskHeader->unknown1; - __eq_AvailableTaskHeader->TaskGiver = __emu_AvailableTaskHeader->TaskGiver; - - __emu_Ptr = (char *) __emu_AvailableTaskHeader + sizeof(AvailableTaskHeader_Struct); - __eq_ptr = (char *) __eq_AvailableTaskHeader + sizeof(structs::AvailableTaskHeader_Struct); - - for(uint32 i=0; i<__emu_AvailableTaskHeader->TaskCount; i++) { - - __emu_AvailableTaskData1 = (AvailableTaskData1_Struct*)__emu_Ptr; - __eq_AvailableTaskData1 = (structs::AvailableTaskData1_Struct*)__eq_ptr; - - __eq_AvailableTaskData1->TaskID = __emu_AvailableTaskData1->TaskID; - // This next unknown seems to affect the colour of the task title. 0x3f80000 is what I have seen - // in RoF packets. Changing it to 0x3f000000 makes the title red. - __eq_AvailableTaskData1->unknown1 = 0x3f800000; - __eq_AvailableTaskData1->TimeLimit = __emu_AvailableTaskData1->TimeLimit; - __eq_AvailableTaskData1->unknown2 = __emu_AvailableTaskData1->unknown2; - - __emu_Ptr += sizeof(AvailableTaskData1_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData1_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Title - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Description - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __eq_ptr[0] = 0; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskData2 = (AvailableTaskData2_Struct*)__emu_Ptr; - __eq_AvailableTaskData2 = (structs::AvailableTaskData2_Struct*)__eq_ptr; - - __eq_AvailableTaskData2->unknown1 = __emu_AvailableTaskData2->unknown1; - __eq_AvailableTaskData2->unknown2 = __emu_AvailableTaskData2->unknown2; - __eq_AvailableTaskData2->unknown3 = __emu_AvailableTaskData2->unknown3; - __eq_AvailableTaskData2->unknown4 = __emu_AvailableTaskData2->unknown4; - - __emu_Ptr += sizeof(AvailableTaskData2_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData2_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskTrailer = (AvailableTaskTrailer_Struct*)__emu_Ptr; - __eq_AvailableTaskTrailer = (structs::AvailableTaskTrailer_Struct*)__eq_ptr; - - __eq_AvailableTaskTrailer->ItemCount = __emu_AvailableTaskTrailer->ItemCount; - __eq_AvailableTaskTrailer->unknown1 = __emu_AvailableTaskTrailer->unknown1; - __eq_AvailableTaskTrailer->unknown2 = __emu_AvailableTaskTrailer->unknown2; - __eq_AvailableTaskTrailer->StartZone = __emu_AvailableTaskTrailer->StartZone; - - __emu_Ptr += sizeof(AvailableTaskTrailer_Struct); - __eq_ptr += sizeof(structs::AvailableTaskTrailer_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - } - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); - } - */ - ENCODE(OP_PetBuffWindow) { // The format of the RoF packet is identical to the OP_BuffCreate packet. @@ -2338,12 +2224,12 @@ namespace RoF outapp->WriteUInt8(0); // Unknown outapp->WriteUInt8(0); // Unknown - outapp->WriteUInt32(profile::BandoliersSize); + outapp->WriteUInt32(profile::BANDOLIERS_SIZE); // Copy bandoliers where server and client indexes converge - for (uint32 r = 0; r < EQEmu::legacy::BANDOLIERS_SIZE && r < profile::BandoliersSize; ++r) { + for (uint32 r = 0; r < EQEmu::profile::BANDOLIERS_SIZE && r < profile::BANDOLIERS_SIZE; ++r) { outapp->WriteString(emu->bandoliers[r].Name); - for (uint32 j = 0; j < profile::BandolierItemCount; ++j) { // Will need adjusting if 'server != client' is ever true + for (uint32 j = 0; j < profile::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true outapp->WriteString(emu->bandoliers[r].Items[j].Name); outapp->WriteUInt32(emu->bandoliers[r].Items[j].ID); if (emu->bandoliers[r].Items[j].Icon) { @@ -2356,19 +2242,19 @@ namespace RoF } } // Nullify bandoliers where server and client indexes diverge, with a client bias - for (uint32 r = EQEmu::legacy::BANDOLIERS_SIZE; r < profile::BandoliersSize; ++r) { + for (uint32 r = EQEmu::profile::BANDOLIERS_SIZE; r < profile::BANDOLIERS_SIZE; ++r) { outapp->WriteString(""); - for (uint32 j = 0; j < profile::BandolierItemCount; ++j) { // Will need adjusting if 'server != client' is ever true + for (uint32 j = 0; j < profile::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true outapp->WriteString(""); outapp->WriteUInt32(0); outapp->WriteSInt32(-1); } } - outapp->WriteUInt32(profile::PotionBeltSize); + outapp->WriteUInt32(profile::POTION_BELT_SIZE); // Copy potion belt where server and client indexes converge - for (uint32 r = 0; r < EQEmu::legacy::POTION_BELT_ITEM_COUNT && r < profile::PotionBeltSize; ++r) { + for (uint32 r = 0; r < EQEmu::profile::POTION_BELT_SIZE && r < profile::POTION_BELT_SIZE; ++r) { outapp->WriteString(emu->potionbelt.Items[r].Name); outapp->WriteUInt32(emu->potionbelt.Items[r].ID); if (emu->potionbelt.Items[r].Icon) { @@ -2380,7 +2266,7 @@ namespace RoF } } // Nullify potion belt where server and client indexes diverge, with a client bias - for (uint32 r = EQEmu::legacy::POTION_BELT_ITEM_COUNT; r < profile::PotionBeltSize; ++r) { + for (uint32 r = EQEmu::profile::POTION_BELT_SIZE; r < profile::POTION_BELT_SIZE; ++r) { outapp->WriteString(""); outapp->WriteUInt32(0); outapp->WriteSInt32(-1); @@ -2501,9 +2387,9 @@ namespace RoF outapp->WriteUInt8(0); // Unknown outapp->WriteUInt8(0); // Unknown - outapp->WriteUInt32(EQEmu::legacy::TRIBUTE_SIZE); + outapp->WriteUInt32(EQEmu::invtype::TRIBUTE_SIZE); - for (uint32 r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) + for (uint32 r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { outapp->WriteUInt32(emu->tributes[r].tribute); outapp->WriteUInt32(emu->tributes[r].tier); @@ -2994,7 +2880,7 @@ namespace RoF size_t names_length = 0; size_t character_count = 0; - for (; character_count < emu->CharCount && character_count < constants::SayLinkBodySize; ++character_count) { + for (; character_count < emu->CharCount && character_count < constants::CHARACTER_CREATION_LIMIT; ++character_count) { emu_cse = (CharacterSelectEntry_Struct *)emu_ptr; names_length += strlen(emu_cse->Name); emu_ptr += sizeof(CharacterSelectEntry_Struct); @@ -3368,13 +3254,16 @@ namespace RoF InBuffer += description_size; InBuffer += sizeof(TaskDescriptionData2_Struct); - std::string old_message = InBuffer; // start 'Reward' as string + uint32 reward_size = strlen(InBuffer) + 1; + InBuffer += reward_size; + + std::string old_message = InBuffer; // start item link string std::string new_message; ServerToRoFSayLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ - title_size + description_size + new_message.length() + 1; + title_size + description_size + reward_size + new_message.length() + 1; in->pBuffer = new unsigned char[in->size]; @@ -4811,7 +4700,7 @@ namespace RoF IN(item_id); int r; - for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) { + for (r = EQEmu::invaug::SOCKET_BEGIN; r <= EQEmu::invaug::SOCKET_END; r++) { IN(augments[r]); } IN(link_hash); @@ -5205,7 +5094,7 @@ namespace RoF structs::InventorySlot_Struct slot_id = ServerToRoFSlot(slot_id_in); - hdr.slot_type = (inst->GetMerchantSlot() ? invtype::InvTypeMerchant : slot_id.Type); + hdr.slot_type = (inst->GetMerchantSlot() ? invtype::typeMerchant : slot_id.Type); hdr.main_slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id.Slot); hdr.sub_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.SubIndex); hdr.aug_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.AugIndex); @@ -5299,7 +5188,7 @@ namespace RoF ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; ibs.size = item->Size; - ibs.slots = SwapBits21and22(item->Slots); + ibs.slots = SwapBits21And22(item->Slots); ibs.price = item->Price; ibs.icon = item->Icon; ibs.unknown1 = 1; @@ -5393,7 +5282,7 @@ namespace RoF isbs.augdistiller = 65535; isbs.augrestrict = item->AugRestrict; - for (int index = 0; index < invaug::ItemAugSize; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { isbs.augslots[index].type = item->AugSlotType[index]; isbs.augslots[index].visible = item->AugSlotVisible[index]; isbs.augslots[index].unknown = item->AugSlotUnk2[index]; @@ -5603,18 +5492,18 @@ namespace RoF ob.write((const char*)&subitem_count, sizeof(uint32)); - for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) { + for (uint32 index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) { EQEmu::ItemInstance* sub = inst->GetItem(index); if (!sub) continue; int SubSlotNumber = INVALID_INDEX; - if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END) - SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1); - else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index); - else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index); + if (slot_id_in >= EQEmu::invslot::GENERAL_BEGIN && slot_id_in <= EQEmu::invslot::GENERAL_END) + SubSlotNumber = (((slot_id_in + 3) * EQEmu::invbag::SLOT_COUNT) + index + 1); + else if (slot_id_in >= EQEmu::invslot::BANK_BEGIN && slot_id_in <= EQEmu::invslot::BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::BANK_BAGS_BEGIN + index); + else if (slot_id_in >= EQEmu::invslot::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::invslot::SHARED_BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::SHARED_BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::SHARED_BANK_BAGS_BEGIN + index); else SubSlotNumber = slot_id_in; @@ -5640,17 +5529,17 @@ namespace RoF uint32 TempSlot = 0; - if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // Main Inventory and Cursor - RoFSlot.Type = invtype::InvTypePossessions; + if (serverSlot < 56 || serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) { // Main Inventory and Cursor + RoFSlot.Type = invtype::typePossessions; RoFSlot.Slot = serverSlot; - if (serverSlot == EQEmu::inventory::slotPowerSource) - RoFSlot.Slot = invslot::PossessionsPowerSource; + if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + RoFSlot.Slot = invslot::slotPowerSource; - else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory + else if (serverSlot >= EQEmu::invslot::slotCursor) // Cursor and Extended Corpse Inventory RoFSlot.Slot += 3; - else if (serverSlot >= EQEmu::inventory::slotAmmo) // (> 20) + else if (serverSlot >= EQEmu::invslot::slotAmmo) // (> 20) RoFSlot.Slot += 1; } @@ -5659,51 +5548,51 @@ namespace RoF RoFSlot.MainSlot = ServerSlot - 31; }*/ - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { // (> 250 && < 341) - RoFSlot.Type = invtype::InvTypePossessions; + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) { // (> 250 && < 341) + RoFSlot.Type = invtype::typePossessions; TempSlot = serverSlot - 1; - RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2; - RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::inventory::ContainerCount); + RoFSlot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 2; + RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::invbag::SLOT_COUNT); - if (RoFSlot.Slot >= invslot::PossessionsGeneral9) // (> 30) - RoFSlot.Slot = invslot::PossessionsCursor; + if (RoFSlot.Slot >= invslot::slotGeneral9) // (> 30) + RoFSlot.Slot = invslot::slotCursor; } - else if (serverSlot >= EQEmu::legacy::TRIBUTE_BEGIN && serverSlot <= EQEmu::legacy::TRIBUTE_END) { // Tribute - RoFSlot.Type = invtype::InvTypeTribute; - RoFSlot.Slot = serverSlot - EQEmu::legacy::TRIBUTE_BEGIN; + else if (serverSlot >= EQEmu::invslot::TRIBUTE_BEGIN && serverSlot <= EQEmu::invslot::TRIBUTE_END) { // Tribute + RoFSlot.Type = invtype::typeTribute; + RoFSlot.Slot = serverSlot - EQEmu::invslot::TRIBUTE_BEGIN; } - else if (serverSlot >= EQEmu::legacy::BANK_BEGIN && serverSlot <= EQEmu::legacy::BANK_BAGS_END) { - RoFSlot.Type = invtype::InvTypeBank; - TempSlot = serverSlot - EQEmu::legacy::BANK_BEGIN; + else if (serverSlot >= EQEmu::invslot::BANK_BEGIN && serverSlot <= EQEmu::invbag::BANK_BAGS_END) { + RoFSlot.Type = invtype::typeBank; + TempSlot = serverSlot - EQEmu::invslot::BANK_BEGIN; RoFSlot.Slot = TempSlot; if (TempSlot > 30) { // (> 30) - RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3; - RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount); + RoFSlot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 3; + RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::invbag::SLOT_COUNT); } } - else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END) { - RoFSlot.Type = invtype::InvTypeSharedBank; - TempSlot = serverSlot - EQEmu::legacy::SHARED_BANK_BEGIN; + else if (serverSlot >= EQEmu::invslot::SHARED_BANK_BEGIN && serverSlot <= EQEmu::invbag::SHARED_BANK_BAGS_END) { + RoFSlot.Type = invtype::typeSharedBank; + TempSlot = serverSlot - EQEmu::invslot::SHARED_BANK_BEGIN; RoFSlot.Slot = TempSlot; if (TempSlot > 30) { // (> 30) - RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3; - RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount); + RoFSlot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 3; + RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::invbag::SLOT_COUNT); } } - else if (serverSlot >= EQEmu::legacy::TRADE_BEGIN && serverSlot <= EQEmu::legacy::TRADE_BAGS_END) { - RoFSlot.Type = invtype::InvTypeTrade; - TempSlot = serverSlot - EQEmu::legacy::TRADE_BEGIN; + else if (serverSlot >= EQEmu::invslot::TRADE_BEGIN && serverSlot <= EQEmu::invbag::TRADE_BAGS_END) { + RoFSlot.Type = invtype::typeTrade; + TempSlot = serverSlot - EQEmu::invslot::TRADE_BEGIN; RoFSlot.Slot = TempSlot; if (TempSlot > 30) { - RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3; - RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount); + RoFSlot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 3; + RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::invbag::SLOT_COUNT); } /* @@ -5720,9 +5609,9 @@ namespace RoF */ } - else if (serverSlot >= EQEmu::legacy::WORLD_BEGIN && serverSlot <= EQEmu::legacy::WORLD_END) { - RoFSlot.Type = invtype::InvTypeWorld; - TempSlot = serverSlot - EQEmu::legacy::WORLD_BEGIN; + else if (serverSlot >= EQEmu::invslot::WORLD_BEGIN && serverSlot <= EQEmu::invslot::WORLD_END) { + RoFSlot.Type = invtype::typeWorld; + TempSlot = serverSlot - EQEmu::invslot::WORLD_BEGIN; RoFSlot.Slot = TempSlot; } @@ -5741,16 +5630,16 @@ namespace RoF uint32 TempSlot = 0; - if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // (< 52) + if (serverSlot < 56 || serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) { // (< 52) RoFSlot.Slot = serverSlot; - if (serverSlot == EQEmu::inventory::slotPowerSource) - RoFSlot.Slot = invslot::PossessionsPowerSource; + if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + RoFSlot.Slot = invslot::slotPowerSource; - else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory + else if (serverSlot >= EQEmu::invslot::slotCursor) // Cursor and Extended Corpse Inventory RoFSlot.Slot += 3; - else if (serverSlot >= EQEmu::inventory::slotAmmo) // Ammo and Personl Inventory + else if (serverSlot >= EQEmu::invslot::slotAmmo) // Ammo and Personl Inventory RoFSlot.Slot += 1; /*else if (ServerSlot >= MainCursor) { // Cursor @@ -5761,10 +5650,10 @@ namespace RoF }*/ } - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) { TempSlot = serverSlot - 1; - RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2; - RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::inventory::ContainerCount); + RoFSlot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 2; + RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::invbag::SLOT_COUNT); } Log(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoFSlot.Slot, RoFSlot.SubIndex, RoFSlot.AugIndex, RoFSlot.Unknown01); @@ -5782,11 +5671,11 @@ namespace RoF uint32 ServerSlot = INVALID_INDEX; uint32 TempSlot = 0; - if (rofSlot.Type == invtype::InvTypePossessions && rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51) - if (rofSlot.Slot == invslot::PossessionsPowerSource) - TempSlot = EQEmu::inventory::slotPowerSource; + if (rofSlot.Type == invtype::typePossessions && rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51) + if (rofSlot.Slot == invslot::slotPowerSource) + TempSlot = EQEmu::invslot::SLOT_POWER_SOURCE; - else if (rofSlot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory + else if (rofSlot.Slot >= invslot::slotCursor) // Cursor and Extended Corpse Inventory TempSlot = rofSlot.Slot - 3; /*else if (RoFSlot.MainSlot == slots::MainGeneral9 || RoFSlot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF inventory/corpse slots @@ -5800,23 +5689,23 @@ namespace RoF // For now, it's probably best to leave as-is and let this work itself out in the inventory rework. }*/ - else if (rofSlot.Slot >= invslot::PossessionsAmmo) // Ammo and Main Inventory + else if (rofSlot.Slot >= invslot::slotAmmo) // Ammo and Main Inventory TempSlot = rofSlot.Slot - 1; else // Worn Slots TempSlot = rofSlot.Slot; - if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots - TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1; + if (rofSlot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EQEmu::invbag::SLOT_COUNT) + rofSlot.SubIndex + 1; ServerSlot = TempSlot; } - else if (rofSlot.Type == invtype::InvTypeBank) { - TempSlot = EQEmu::legacy::BANK_BEGIN; + else if (rofSlot.Type == invtype::typeBank) { + TempSlot = EQEmu::invslot::BANK_BEGIN; - if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) - TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1; + if (rofSlot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) + TempSlot += ((rofSlot.Slot + 3) * EQEmu::invbag::SLOT_COUNT) + rofSlot.SubIndex + 1; else TempSlot += rofSlot.Slot; @@ -5824,11 +5713,11 @@ namespace RoF ServerSlot = TempSlot; } - else if (rofSlot.Type == invtype::InvTypeSharedBank) { - TempSlot = EQEmu::legacy::SHARED_BANK_BEGIN; + else if (rofSlot.Type == invtype::typeSharedBank) { + TempSlot = EQEmu::invslot::SHARED_BANK_BEGIN; - if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) - TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1; + if (rofSlot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) + TempSlot += ((rofSlot.Slot + 3) * EQEmu::invbag::SLOT_COUNT) + rofSlot.SubIndex + 1; else TempSlot += rofSlot.Slot; @@ -5836,11 +5725,11 @@ namespace RoF ServerSlot = TempSlot; } - else if (rofSlot.Type == invtype::InvTypeTrade) { - TempSlot = EQEmu::legacy::TRADE_BEGIN; + else if (rofSlot.Type == invtype::typeTrade) { + TempSlot = EQEmu::invslot::TRADE_BEGIN; - if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) - TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1; + if (rofSlot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) + TempSlot += ((rofSlot.Slot + 3) * EQEmu::invbag::SLOT_COUNT) + rofSlot.SubIndex + 1; // OLD CODE: //TempSlot += 100 + (RoFSlot.MainSlot * EQEmu::inventory::ContainerCount) + RoFSlot.SubSlot; @@ -5850,10 +5739,10 @@ namespace RoF ServerSlot = TempSlot; } - else if (rofSlot.Type == invtype::InvTypeWorld) { - TempSlot = EQEmu::legacy::WORLD_BEGIN; + else if (rofSlot.Type == invtype::typeWorld) { + TempSlot = EQEmu::invslot::WORLD_BEGIN; - if (rofSlot.Slot >= EQEmu::inventory::containerBegin) + if (rofSlot.Slot >= EQEmu::invbag::SLOT_BEGIN) TempSlot += rofSlot.Slot; ServerSlot = TempSlot; @@ -5868,7 +5757,7 @@ namespace RoF ServerSlot = TempSlot; }*/ - else if (rofSlot.Type == invtype::InvTypeGuildTribute) { + else if (rofSlot.Type == invtype::typeGuildTribute) { ServerSlot = INVALID_INDEX; } @@ -5883,10 +5772,10 @@ namespace RoF uint32 TempSlot = 0; if (rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 33) - if (rofSlot.Slot == invslot::PossessionsPowerSource) - TempSlot = EQEmu::inventory::slotPowerSource; + if (rofSlot.Slot == invslot::slotPowerSource) + TempSlot = EQEmu::invslot::SLOT_POWER_SOURCE; - else if (rofSlot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory + else if (rofSlot.Slot >= invslot::slotCursor) // Cursor and Extended Corpse Inventory TempSlot = rofSlot.Slot - 3; /*else if (RoFSlot.MainSlot == slots::MainGeneral9 || RoFSlot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF inventory slots @@ -5895,14 +5784,14 @@ namespace RoF // Same as above }*/ - else if (rofSlot.Slot >= invslot::PossessionsAmmo) // Main Inventory and Ammo Slots + else if (rofSlot.Slot >= invslot::slotAmmo) // Main Inventory and Ammo Slots TempSlot = rofSlot.Slot - 1; else TempSlot = rofSlot.Slot; - if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots - TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1; + if (rofSlot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EQEmu::invbag::SLOT_COUNT) + rofSlot.SubIndex + 1; ServerSlot = TempSlot; } @@ -5919,7 +5808,7 @@ namespace RoF static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink) { - if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) { + if ((constants::SAY_LINK_BODY_SIZE == EQEmu::constants::SAY_LINK_BODY_SIZE) || (serverSayLink.find('\x12') == std::string::npos)) { rofSayLink = serverSayLink; return; } @@ -5928,7 +5817,7 @@ namespace RoF for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= EQEmu::constants::SAY_LINK_BODY_SIZE) { rofSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; @@ -5958,7 +5847,7 @@ namespace RoF static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink) { - if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rofSayLink.find('\x12') == std::string::npos)) { + if ((EQEmu::constants::SAY_LINK_BODY_SIZE == constants::SAY_LINK_BODY_SIZE) || (rofSayLink.find('\x12') == std::string::npos)) { serverSayLink = rofSayLink; return; } @@ -5967,7 +5856,7 @@ namespace RoF for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= constants::SAY_LINK_BODY_SIZE) { serverSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 5a30c1695..9cba1d0b4 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -1940,120 +1940,6 @@ namespace RoF2 FINISH_ENCODE(); } - /* - ENCODE(OP_OpenNewTasksWindow) - { - AvailableTaskHeader_Struct* __emu_AvailableTaskHeader; - AvailableTaskData1_Struct* __emu_AvailableTaskData1; - AvailableTaskData2_Struct* __emu_AvailableTaskData2; - AvailableTaskTrailer_Struct* __emu_AvailableTaskTrailer; - - structs::AvailableTaskHeader_Struct* __eq_AvailableTaskHeader; - structs::AvailableTaskData1_Struct* __eq_AvailableTaskData1; - structs::AvailableTaskData2_Struct* __eq_AvailableTaskData2; - structs::AvailableTaskTrailer_Struct* __eq_AvailableTaskTrailer; - - EQApplicationPacket *in = *p; - *p = nullptr; - - unsigned char *__emu_buffer = in->pBuffer; - - __emu_AvailableTaskHeader = (AvailableTaskHeader_Struct*)__emu_buffer; - - // For each task, SoF has an extra uint32 and what appears to be space for a null terminated string. - // - in->size = in->size + (__emu_AvailableTaskHeader->TaskCount * 5); - - in->pBuffer = new unsigned char[in->size]; - - unsigned char *__eq_buffer = in->pBuffer; - - __eq_AvailableTaskHeader = (structs::AvailableTaskHeader_Struct*)__eq_buffer; - - char *__eq_ptr, *__emu_Ptr; - - // Copy Header - // - // - - __eq_AvailableTaskHeader->TaskCount = __emu_AvailableTaskHeader->TaskCount; - __eq_AvailableTaskHeader->unknown1 = __emu_AvailableTaskHeader->unknown1; - __eq_AvailableTaskHeader->TaskGiver = __emu_AvailableTaskHeader->TaskGiver; - - __emu_Ptr = (char *) __emu_AvailableTaskHeader + sizeof(AvailableTaskHeader_Struct); - __eq_ptr = (char *) __eq_AvailableTaskHeader + sizeof(structs::AvailableTaskHeader_Struct); - - for(uint32 i=0; i<__emu_AvailableTaskHeader->TaskCount; i++) { - - __emu_AvailableTaskData1 = (AvailableTaskData1_Struct*)__emu_Ptr; - __eq_AvailableTaskData1 = (structs::AvailableTaskData1_Struct*)__eq_ptr; - - __eq_AvailableTaskData1->TaskID = __emu_AvailableTaskData1->TaskID; - // This next unknown seems to affect the colour of the task title. 0x3f80000 is what I have seen - // in RoF2 packets. Changing it to 0x3f000000 makes the title red. - __eq_AvailableTaskData1->unknown1 = 0x3f800000; - __eq_AvailableTaskData1->TimeLimit = __emu_AvailableTaskData1->TimeLimit; - __eq_AvailableTaskData1->unknown2 = __emu_AvailableTaskData1->unknown2; - - __emu_Ptr += sizeof(AvailableTaskData1_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData1_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Title - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Description - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __eq_ptr[0] = 0; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskData2 = (AvailableTaskData2_Struct*)__emu_Ptr; - __eq_AvailableTaskData2 = (structs::AvailableTaskData2_Struct*)__eq_ptr; - - __eq_AvailableTaskData2->unknown1 = __emu_AvailableTaskData2->unknown1; - __eq_AvailableTaskData2->unknown2 = __emu_AvailableTaskData2->unknown2; - __eq_AvailableTaskData2->unknown3 = __emu_AvailableTaskData2->unknown3; - __eq_AvailableTaskData2->unknown4 = __emu_AvailableTaskData2->unknown4; - - __emu_Ptr += sizeof(AvailableTaskData2_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData2_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskTrailer = (AvailableTaskTrailer_Struct*)__emu_Ptr; - __eq_AvailableTaskTrailer = (structs::AvailableTaskTrailer_Struct*)__eq_ptr; - - __eq_AvailableTaskTrailer->ItemCount = __emu_AvailableTaskTrailer->ItemCount; - __eq_AvailableTaskTrailer->unknown1 = __emu_AvailableTaskTrailer->unknown1; - __eq_AvailableTaskTrailer->unknown2 = __emu_AvailableTaskTrailer->unknown2; - __eq_AvailableTaskTrailer->StartZone = __emu_AvailableTaskTrailer->StartZone; - - __emu_Ptr += sizeof(AvailableTaskTrailer_Struct); - __eq_ptr += sizeof(structs::AvailableTaskTrailer_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - } - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); - } - */ - ENCODE(OP_PetBuffWindow) { // The format of the RoF2 packet is identical to the OP_BuffCreate packet. @@ -2415,12 +2301,12 @@ namespace RoF2 outapp->WriteUInt8(0); // Unknown outapp->WriteUInt8(0); // Unknown - outapp->WriteUInt32(profile::BandoliersSize); + outapp->WriteUInt32(profile::BANDOLIERS_SIZE); // Copy bandoliers where server and client indexes converge - for (uint32 r = 0; r < EQEmu::legacy::BANDOLIERS_SIZE && r < profile::BandoliersSize; ++r) { + for (uint32 r = 0; r < EQEmu::profile::BANDOLIERS_SIZE && r < profile::BANDOLIERS_SIZE; ++r) { outapp->WriteString(emu->bandoliers[r].Name); - for (uint32 j = 0; j < profile::BandolierItemCount; ++j) { // Will need adjusting if 'server != client' is ever true + for (uint32 j = 0; j < profile::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true outapp->WriteString(emu->bandoliers[r].Items[j].Name); outapp->WriteUInt32(emu->bandoliers[r].Items[j].ID); if (emu->bandoliers[r].Items[j].Icon) { @@ -2433,19 +2319,19 @@ namespace RoF2 } } // Nullify bandoliers where server and client indexes diverge, with a client bias - for (uint32 r = EQEmu::legacy::BANDOLIERS_SIZE; r < profile::BandoliersSize; ++r) { + for (uint32 r = EQEmu::profile::BANDOLIERS_SIZE; r < profile::BANDOLIERS_SIZE; ++r) { outapp->WriteString(""); - for (uint32 j = 0; j < profile::BandolierItemCount; ++j) { // Will need adjusting if 'server != client' is ever true + for (uint32 j = 0; j < profile::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true outapp->WriteString(""); outapp->WriteUInt32(0); outapp->WriteSInt32(-1); } } - outapp->WriteUInt32(profile::PotionBeltSize); + outapp->WriteUInt32(profile::POTION_BELT_SIZE); // Copy potion belt where server and client indexes converge - for (uint32 r = 0; r < EQEmu::legacy::POTION_BELT_ITEM_COUNT && r < profile::PotionBeltSize; ++r) { + for (uint32 r = 0; r < EQEmu::profile::POTION_BELT_SIZE && r < profile::POTION_BELT_SIZE; ++r) { outapp->WriteString(emu->potionbelt.Items[r].Name); outapp->WriteUInt32(emu->potionbelt.Items[r].ID); if (emu->potionbelt.Items[r].Icon) { @@ -2457,7 +2343,7 @@ namespace RoF2 } } // Nullify potion belt where server and client indexes diverge, with a client bias - for (uint32 r = EQEmu::legacy::POTION_BELT_ITEM_COUNT; r < profile::PotionBeltSize; ++r) { + for (uint32 r = EQEmu::profile::POTION_BELT_SIZE; r < profile::POTION_BELT_SIZE; ++r) { outapp->WriteString(""); outapp->WriteUInt32(0); outapp->WriteSInt32(-1); @@ -2574,9 +2460,9 @@ namespace RoF2 outapp->WriteUInt8(0); // Unknown outapp->WriteUInt8(0); // Unknown - outapp->WriteUInt32(EQEmu::legacy::TRIBUTE_SIZE); + outapp->WriteUInt32(EQEmu::invtype::TRIBUTE_SIZE); - for (uint32 r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) + for (uint32 r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { outapp->WriteUInt32(emu->tributes[r].tribute); outapp->WriteUInt32(emu->tributes[r].tier); @@ -3081,7 +2967,7 @@ namespace RoF2 size_t names_length = 0; size_t character_count = 0; - for (; character_count < emu->CharCount && character_count < constants::CharacterCreationLimit; ++character_count) { + for (; character_count < emu->CharCount && character_count < constants::CHARACTER_CREATION_LIMIT; ++character_count) { emu_cse = (CharacterSelectEntry_Struct *)emu_ptr; names_length += strlen(emu_cse->Name); emu_ptr += sizeof(CharacterSelectEntry_Struct); @@ -3437,13 +3323,16 @@ namespace RoF2 InBuffer += description_size; InBuffer += sizeof(TaskDescriptionData2_Struct); - std::string old_message = InBuffer; // start 'Reward' as string + uint32 reward_size = strlen(InBuffer) + 1; + InBuffer += reward_size; + + std::string old_message = InBuffer; // start item link string std::string new_message; ServerToRoF2SayLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ - title_size + description_size + new_message.length() + 1; + title_size + description_size + reward_size + new_message.length() + 1; in->pBuffer = new unsigned char[in->size]; @@ -5051,7 +4940,7 @@ namespace RoF2 IN(item_id); int r; - for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) { + for (r = EQEmu::invaug::SOCKET_BEGIN; r <= EQEmu::invaug::SOCKET_END; r++) { IN(augments[r]); } IN(link_hash); @@ -5500,7 +5389,7 @@ namespace RoF2 structs::InventorySlot_Struct slot_id = ServerToRoF2Slot(slot_id_in, packet_type); - hdr.slot_type = (inst->GetMerchantSlot() ? invtype::InvTypeMerchant : slot_id.Type); + hdr.slot_type = (inst->GetMerchantSlot() ? invtype::typeMerchant : slot_id.Type); hdr.main_slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id.Slot); hdr.sub_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.SubIndex); hdr.aug_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.AugIndex); @@ -5594,7 +5483,7 @@ namespace RoF2 ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; ibs.size = item->Size; - ibs.slots = SwapBits21and22(item->Slots); + ibs.slots = SwapBits21And22(item->Slots); ibs.price = item->Price; ibs.icon = item->Icon; ibs.unknown1 = 1; @@ -5688,7 +5577,7 @@ namespace RoF2 isbs.augrestrict2 = -1; isbs.augrestrict = item->AugRestrict; - for (int index = 0; index < invaug::ItemAugSize; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { isbs.augslots[index].type = item->AugSlotType[index]; isbs.augslots[index].visible = item->AugSlotVisible[index]; isbs.augslots[index].unknown = item->AugSlotUnk2[index]; @@ -5908,18 +5797,18 @@ namespace RoF2 ob.write((const char*)&subitem_count, sizeof(uint32)); - for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) { + for (uint32 index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) { EQEmu::ItemInstance* sub = inst->GetItem(index); if (!sub) continue; int SubSlotNumber = INVALID_INDEX; - if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END) - SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1); - else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index); - else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index); + if (slot_id_in >= EQEmu::invslot::GENERAL_BEGIN && slot_id_in <= EQEmu::invslot::GENERAL_END) + SubSlotNumber = (((slot_id_in + 3) * EQEmu::invbag::SLOT_COUNT) + index + 1); + else if (slot_id_in >= EQEmu::invslot::BANK_BEGIN && slot_id_in <= EQEmu::invslot::BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::BANK_BAGS_BEGIN + index); + else if (slot_id_in >= EQEmu::invslot::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::invslot::SHARED_BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::SHARED_BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::SHARED_BANK_BAGS_BEGIN + index); else SubSlotNumber = slot_id_in; @@ -5945,25 +5834,25 @@ namespace RoF2 uint32 TempSlot = 0; - if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // Main Inventory and Cursor + if (serverSlot < 56 || serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) { // Main Inventory and Cursor if (PacketType == ItemPacketLoot) { - RoF2Slot.Type = invtype::InvTypeCorpse; - RoF2Slot.Slot = serverSlot - EQEmu::legacy::CORPSE_BEGIN; + RoF2Slot.Type = invtype::typeCorpse; + RoF2Slot.Slot = serverSlot - EQEmu::invslot::CORPSE_BEGIN; } else { - RoF2Slot.Type = invtype::InvTypePossessions; + RoF2Slot.Type = invtype::typePossessions; RoF2Slot.Slot = serverSlot; } - if (serverSlot == EQEmu::inventory::slotPowerSource) - RoF2Slot.Slot = invslot::PossessionsPowerSource; + if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + RoF2Slot.Slot = invslot::slotPowerSource; - else if (serverSlot >= EQEmu::inventory::slotCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory + else if (serverSlot >= EQEmu::invslot::slotCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory RoF2Slot.Slot += 3; - else if (serverSlot >= EQEmu::inventory::slotAmmo) // (> 20) + else if (serverSlot >= EQEmu::invslot::slotAmmo) // (> 20) RoF2Slot.Slot += 1; } @@ -5972,51 +5861,51 @@ namespace RoF2 RoF2Slot.MainSlot = ServerSlot - 31; }*/ - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { // (> 250 && < 341) - RoF2Slot.Type = invtype::InvTypePossessions; + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) { // (> 250 && < 341) + RoF2Slot.Type = invtype::typePossessions; TempSlot = serverSlot - 1; - RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2; - RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::inventory::ContainerCount); + RoF2Slot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 2; + RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::invbag::SLOT_COUNT); - if (RoF2Slot.Slot >= invslot::PossessionsGeneral9) // (> 30) - RoF2Slot.Slot = invslot::PossessionsCursor; + if (RoF2Slot.Slot >= invslot::slotGeneral9) // (> 30) + RoF2Slot.Slot = invslot::slotCursor; } - else if (serverSlot >= EQEmu::legacy::TRIBUTE_BEGIN && serverSlot <= EQEmu::legacy::TRIBUTE_END) { // Tribute - RoF2Slot.Type = invtype::InvTypeTribute; - RoF2Slot.Slot = serverSlot - EQEmu::legacy::TRIBUTE_BEGIN; + else if (serverSlot >= EQEmu::invslot::TRIBUTE_BEGIN && serverSlot <= EQEmu::invslot::TRIBUTE_END) { // Tribute + RoF2Slot.Type = invtype::typeTribute; + RoF2Slot.Slot = serverSlot - EQEmu::invslot::TRIBUTE_BEGIN; } - else if (serverSlot >= EQEmu::legacy::BANK_BEGIN && serverSlot <= EQEmu::legacy::BANK_BAGS_END) { - RoF2Slot.Type = invtype::InvTypeBank; - TempSlot = serverSlot - EQEmu::legacy::BANK_BEGIN; + else if (serverSlot >= EQEmu::invslot::BANK_BEGIN && serverSlot <= EQEmu::invbag::BANK_BAGS_END) { + RoF2Slot.Type = invtype::typeBank; + TempSlot = serverSlot - EQEmu::invslot::BANK_BEGIN; RoF2Slot.Slot = TempSlot; if (TempSlot > 30) { // (> 30) - RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3; - RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount); + RoF2Slot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 3; + RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::invbag::SLOT_COUNT); } } - else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END) { - RoF2Slot.Type = invtype::InvTypeSharedBank; - TempSlot = serverSlot - EQEmu::legacy::SHARED_BANK_BEGIN; + else if (serverSlot >= EQEmu::invslot::SHARED_BANK_BEGIN && serverSlot <= EQEmu::invbag::SHARED_BANK_BAGS_END) { + RoF2Slot.Type = invtype::typeSharedBank; + TempSlot = serverSlot - EQEmu::invslot::SHARED_BANK_BEGIN; RoF2Slot.Slot = TempSlot; if (TempSlot > 30) { // (> 30) - RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3; - RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount); + RoF2Slot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 3; + RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::invbag::SLOT_COUNT); } } - else if (serverSlot >= EQEmu::legacy::TRADE_BEGIN && serverSlot <= EQEmu::legacy::TRADE_BAGS_END) { - RoF2Slot.Type = invtype::InvTypeTrade; - TempSlot = serverSlot - EQEmu::legacy::TRADE_BEGIN; + else if (serverSlot >= EQEmu::invslot::TRADE_BEGIN && serverSlot <= EQEmu::invbag::TRADE_BAGS_END) { + RoF2Slot.Type = invtype::typeTrade; + TempSlot = serverSlot - EQEmu::invslot::TRADE_BEGIN; RoF2Slot.Slot = TempSlot; if (TempSlot > 30) { - RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3; - RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount); + RoF2Slot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 3; + RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::invbag::SLOT_COUNT); } /* @@ -6033,9 +5922,9 @@ namespace RoF2 */ } - else if (serverSlot >= EQEmu::legacy::WORLD_BEGIN && serverSlot <= EQEmu::legacy::WORLD_END) { - RoF2Slot.Type = invtype::InvTypeWorld; - TempSlot = serverSlot - EQEmu::legacy::WORLD_BEGIN; + else if (serverSlot >= EQEmu::invslot::WORLD_BEGIN && serverSlot <= EQEmu::invslot::WORLD_END) { + RoF2Slot.Type = invtype::typeWorld; + TempSlot = serverSlot - EQEmu::invslot::WORLD_BEGIN; RoF2Slot.Slot = TempSlot; } @@ -6054,16 +5943,16 @@ namespace RoF2 uint32 TempSlot = 0; - if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // (< 52) + if (serverSlot < 56 || serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) { // (< 52) RoF2Slot.Slot = serverSlot; - if (serverSlot == EQEmu::inventory::slotPowerSource) - RoF2Slot.Slot = invslot::PossessionsPowerSource; + if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + RoF2Slot.Slot = invslot::slotPowerSource; - else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory + else if (serverSlot >= EQEmu::invslot::slotCursor) // Cursor and Extended Corpse Inventory RoF2Slot.Slot += 3; - else if (serverSlot >= EQEmu::inventory::slotAmmo) // Ammo and Personl Inventory + else if (serverSlot >= EQEmu::invslot::slotAmmo) // Ammo and Personl Inventory RoF2Slot.Slot += 1; /*else if (ServerSlot >= MainCursor) { // Cursor @@ -6074,10 +5963,10 @@ namespace RoF2 }*/ } - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) { TempSlot = serverSlot - 1; - RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2; - RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::inventory::ContainerCount); + RoF2Slot.Slot = int(TempSlot / EQEmu::invbag::SLOT_COUNT) - 2; + RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::invbag::SLOT_COUNT); } Log(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoF2Slot.Slot, RoF2Slot.SubIndex, RoF2Slot.AugIndex, RoF2Slot.Unknown01); @@ -6087,7 +5976,7 @@ namespace RoF2 static inline uint32 ServerToRoF2CorpseSlot(uint32 serverCorpseSlot) { - return (serverCorpseSlot - EQEmu::legacy::CORPSE_BEGIN + 1); + return (serverCorpseSlot - EQEmu::invslot::CORPSE_BEGIN + 1); } static inline uint32 RoF2ToServerSlot(structs::InventorySlot_Struct rof2Slot, ItemPacketType PacketType) @@ -6095,11 +5984,11 @@ namespace RoF2 uint32 ServerSlot = INVALID_INDEX; uint32 TempSlot = 0; - if (rof2Slot.Type == invtype::InvTypePossessions && rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51) - if (rof2Slot.Slot == invslot::PossessionsPowerSource) - TempSlot = EQEmu::inventory::slotPowerSource; + if (rof2Slot.Type == invtype::typePossessions && rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51) + if (rof2Slot.Slot == invslot::slotPowerSource) + TempSlot = EQEmu::invslot::SLOT_POWER_SOURCE; - else if (rof2Slot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory + else if (rof2Slot.Slot >= invslot::slotCursor) // Cursor and Extended Corpse Inventory TempSlot = rof2Slot.Slot - 3; /*else if (RoF2Slot.MainSlot == slots::MainGeneral9 || RoF2Slot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF2 inventory/corpse slots @@ -6113,23 +6002,23 @@ namespace RoF2 // For now, it's probably best to leave as-is and let this work itself out in the inventory rework. }*/ - else if (rof2Slot.Slot >= invslot::PossessionsAmmo) // Ammo and Main Inventory + else if (rof2Slot.Slot >= invslot::slotAmmo) // Ammo and Main Inventory TempSlot = rof2Slot.Slot - 1; else // Worn Slots TempSlot = rof2Slot.Slot; - if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots - TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1; + if (rof2Slot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EQEmu::invbag::SLOT_COUNT) + rof2Slot.SubIndex + 1; ServerSlot = TempSlot; } - else if (rof2Slot.Type == invtype::InvTypeBank) { - TempSlot = EQEmu::legacy::BANK_BEGIN; + else if (rof2Slot.Type == invtype::typeBank) { + TempSlot = EQEmu::invslot::BANK_BEGIN; - if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) - TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1; + if (rof2Slot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) + TempSlot += ((rof2Slot.Slot + 3) * EQEmu::invbag::SLOT_COUNT) + rof2Slot.SubIndex + 1; else TempSlot += rof2Slot.Slot; @@ -6137,11 +6026,11 @@ namespace RoF2 ServerSlot = TempSlot; } - else if (rof2Slot.Type == invtype::InvTypeSharedBank) { - TempSlot = EQEmu::legacy::SHARED_BANK_BEGIN; + else if (rof2Slot.Type == invtype::typeSharedBank) { + TempSlot = EQEmu::invslot::SHARED_BANK_BEGIN; - if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) - TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1; + if (rof2Slot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) + TempSlot += ((rof2Slot.Slot + 3) * EQEmu::invbag::SLOT_COUNT) + rof2Slot.SubIndex + 1; else TempSlot += rof2Slot.Slot; @@ -6149,11 +6038,11 @@ namespace RoF2 ServerSlot = TempSlot; } - else if (rof2Slot.Type == invtype::InvTypeTrade) { - TempSlot = EQEmu::legacy::TRADE_BEGIN; + else if (rof2Slot.Type == invtype::typeTrade) { + TempSlot = EQEmu::invslot::TRADE_BEGIN; - if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) - TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1; + if (rof2Slot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) + TempSlot += ((rof2Slot.Slot + 3) * EQEmu::invbag::SLOT_COUNT) + rof2Slot.SubIndex + 1; // OLD CODE: //TempSlot += 100 + (RoF2Slot.MainSlot * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot; @@ -6163,10 +6052,10 @@ namespace RoF2 ServerSlot = TempSlot; } - else if (rof2Slot.Type == invtype::InvTypeWorld) { - TempSlot = EQEmu::legacy::WORLD_BEGIN; + else if (rof2Slot.Type == invtype::typeWorld) { + TempSlot = EQEmu::invslot::WORLD_BEGIN; - if (rof2Slot.Slot >= EQEmu::inventory::containerBegin) + if (rof2Slot.Slot >= EQEmu::invbag::SLOT_BEGIN) TempSlot += rof2Slot.Slot; ServerSlot = TempSlot; @@ -6181,12 +6070,12 @@ namespace RoF2 ServerSlot = TempSlot; }*/ - else if (rof2Slot.Type == invtype::InvTypeGuildTribute) { + else if (rof2Slot.Type == invtype::typeGuildTribute) { ServerSlot = INVALID_INDEX; } - else if (rof2Slot.Type == invtype::InvTypeCorpse) { - ServerSlot = rof2Slot.Slot + EQEmu::legacy::CORPSE_BEGIN; + else if (rof2Slot.Type == invtype::typeCorpse) { + ServerSlot = rof2Slot.Slot + EQEmu::invslot::CORPSE_BEGIN; } Log(Logs::General, Logs::Netcode, "[ERROR] Convert RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", rof2Slot.Type, rof2Slot.Unknown02, rof2Slot.Slot, rof2Slot.SubIndex, rof2Slot.AugIndex, rof2Slot.Unknown01, ServerSlot); @@ -6200,10 +6089,10 @@ namespace RoF2 uint32 TempSlot = 0; if (rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 33) - if (rof2Slot.Slot == invslot::PossessionsPowerSource) - TempSlot = EQEmu::inventory::slotPowerSource; + if (rof2Slot.Slot == invslot::slotPowerSource) + TempSlot = EQEmu::invslot::SLOT_POWER_SOURCE; - else if (rof2Slot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory + else if (rof2Slot.Slot >= invslot::slotCursor) // Cursor and Extended Corpse Inventory TempSlot = rof2Slot.Slot - 3; /*else if (RoF2Slot.MainSlot == slots::MainGeneral9 || RoF2Slot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF2 inventory slots @@ -6212,14 +6101,14 @@ namespace RoF2 // Same as above }*/ - else if (rof2Slot.Slot >= invslot::PossessionsAmmo) // Main Inventory and Ammo Slots + else if (rof2Slot.Slot >= invslot::slotAmmo) // Main Inventory and Ammo Slots TempSlot = rof2Slot.Slot - 1; else TempSlot = rof2Slot.Slot; - if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots - TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1; + if (rof2Slot.SubIndex >= EQEmu::invbag::SLOT_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EQEmu::invbag::SLOT_COUNT) + rof2Slot.SubIndex + 1; ServerSlot = TempSlot; } @@ -6231,12 +6120,12 @@ namespace RoF2 static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot) { - return (rof2CorpseSlot + EQEmu::legacy::CORPSE_BEGIN - 1); + return (rof2CorpseSlot + EQEmu::invslot::CORPSE_BEGIN - 1); } static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink) { - if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) { + if ((constants::SAY_LINK_BODY_SIZE == EQEmu::constants::SAY_LINK_BODY_SIZE) || (serverSayLink.find('\x12') == std::string::npos)) { rof2SayLink = serverSayLink; return; } @@ -6245,7 +6134,7 @@ namespace RoF2 for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= EQEmu::constants::SAY_LINK_BODY_SIZE) { rof2SayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; @@ -6268,7 +6157,7 @@ namespace RoF2 static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink) { - if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rof2SayLink.find('\x12') == std::string::npos)) { + if ((EQEmu::constants::SAY_LINK_BODY_SIZE == constants::SAY_LINK_BODY_SIZE) || (rof2SayLink.find('\x12') == std::string::npos)) { serverSayLink = rof2SayLink; return; } @@ -6277,7 +6166,7 @@ namespace RoF2 for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= constants::SAY_LINK_BODY_SIZE) { serverSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; diff --git a/common/patches/rof2_limits.cpp b/common/patches/rof2_limits.cpp index 85e15e21d..c67ccf3ad 100644 --- a/common/patches/rof2_limits.cpp +++ b/common/patches/rof2_limits.cpp @@ -22,231 +22,231 @@ #include "../string_util.h" -size_t RoF2::invtype::GetInvTypeSize(int inv_type) +int16 RoF2::invtype::GetInvTypeSize(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - return invtype::InvTypePossessionsSize; - case invtype::InvTypeBank: - return invtype::InvTypeBankSize; - case invtype::InvTypeSharedBank: - return invtype::InvTypeSharedBankSize; - case invtype::InvTypeTrade: - return invtype::InvTypeTradeSize; - case invtype::InvTypeWorld: - return invtype::InvTypeWorldSize; - case invtype::InvTypeLimbo: - return invtype::InvTypeLimboSize; - case invtype::InvTypeTribute: - return invtype::InvTypeTributeSize; - case invtype::InvTypeTrophyTribute: - return invtype::InvTypeTrophyTributeSize; - case invtype::InvTypeGuildTribute: - return invtype::InvTypeGuildTributeSize; - case invtype::InvTypeMerchant: - return invtype::InvTypeMerchantSize; - case invtype::InvTypeDeleted: - return invtype::InvTypeDeletedSize; - case invtype::InvTypeCorpse: - return invtype::InvTypeCorpseSize; - case invtype::InvTypeBazaar: - return invtype::InvTypeBazaarSize; - case invtype::InvTypeInspect: - return invtype::InvTypeInspectSize; - case invtype::InvTypeRealEstate: - return invtype::InvTypeRealEstateSize; - case invtype::InvTypeViewMODPC: - return invtype::InvTypeViewMODPCSize; - case invtype::InvTypeViewMODBank: - return invtype::InvTypeViewMODBankSize; - case invtype::InvTypeViewMODSharedBank: - return invtype::InvTypeViewMODSharedBankSize; - case invtype::InvTypeViewMODLimbo: - return invtype::InvTypeViewMODLimboSize; - case invtype::InvTypeAltStorage: - return invtype::InvTypeAltStorageSize; - case invtype::InvTypeArchived: - return invtype::InvTypeArchivedSize; - case invtype::InvTypeMail: - return invtype::InvTypeMailSize; - case invtype::InvTypeGuildTrophyTribute: - return invtype::InvTypeGuildTrophyTributeSize; - case invtype::InvTypeKrono: - return invtype::InvTypeKronoSize; - case invtype::InvTypeOther: - return invtype::InvTypeOtherSize; + case invtype::typePossessions: + return invtype::POSSESSIONS_SIZE; + case invtype::typeBank: + return invtype::BANK_SIZE; + case invtype::typeSharedBank: + return invtype::SHARED_BANK_SIZE; + case invtype::typeTrade: + return invtype::TRADE_SIZE; + case invtype::typeWorld: + return invtype::WORLD_SIZE; + case invtype::typeLimbo: + return invtype::LIMBO_SIZE; + case invtype::typeTribute: + return invtype::TRIBUTE_SIZE; + case invtype::typeTrophyTribute: + return invtype::TROPHY_TRIBUTE_SIZE; + case invtype::typeGuildTribute: + return invtype::GUILD_TRIBUTE_SIZE; + case invtype::typeMerchant: + return invtype::MERCHANT_SIZE; + case invtype::typeDeleted: + return invtype::DELETED_SIZE; + case invtype::typeCorpse: + return invtype::CORPSE_SIZE; + case invtype::typeBazaar: + return invtype::BAZAAR_SIZE; + case invtype::typeInspect: + return invtype::INSPECT_SIZE; + case invtype::typeRealEstate: + return invtype::REAL_ESTATE_SIZE; + case invtype::typeViewMODPC: + return invtype::VIEW_MOD_PC_SIZE; + case invtype::typeViewMODBank: + return invtype::VIEW_MOD_BANK_SIZE; + case invtype::typeViewMODSharedBank: + return invtype::VIEW_MOD_SHARED_BANK_SIZE; + case invtype::typeViewMODLimbo: + return invtype::VIEW_MOD_LIMBO_SIZE; + case invtype::typeAltStorage: + return invtype::ALT_STORAGE_SIZE; + case invtype::typeArchived: + return invtype::ARCHIVED_SIZE; + case invtype::typeMail: + return invtype::MAIL_SIZE; + case invtype::typeGuildTrophyTribute: + return invtype::GUILD_TROPHY_TRIBUTE_SIZE; + case invtype::typeKrono: + return invtype::KRONO_SIZE; + case invtype::typeOther: + return invtype::OTHER_SIZE; default: - return 0; + return INULL; } } -const char* RoF2::invtype::GetInvTypeName(int inv_type) +const char* RoF2::invtype::GetInvTypeName(int16 inv_type) { switch (inv_type) { - case invtype::InvTypeInvalid: + case invtype::TYPE_INVALID: return "Invalid Type"; - case invtype::InvTypePossessions: + case invtype::typePossessions: return "Possessions"; - case invtype::InvTypeBank: + case invtype::typeBank: return "Bank"; - case invtype::InvTypeSharedBank: + case invtype::typeSharedBank: return "Shared Bank"; - case invtype::InvTypeTrade: + case invtype::typeTrade: return "Trade"; - case invtype::InvTypeWorld: + case invtype::typeWorld: return "World"; - case invtype::InvTypeLimbo: + case invtype::typeLimbo: return "Limbo"; - case invtype::InvTypeTribute: + case invtype::typeTribute: return "Tribute"; - case invtype::InvTypeTrophyTribute: + case invtype::typeTrophyTribute: return "Trophy Tribute"; - case invtype::InvTypeGuildTribute: + case invtype::typeGuildTribute: return "Guild Tribute"; - case invtype::InvTypeMerchant: + case invtype::typeMerchant: return "Merchant"; - case invtype::InvTypeDeleted: + case invtype::typeDeleted: return "Deleted"; - case invtype::InvTypeCorpse: + case invtype::typeCorpse: return "Corpse"; - case invtype::InvTypeBazaar: + case invtype::typeBazaar: return "Bazaar"; - case invtype::InvTypeInspect: + case invtype::typeInspect: return "Inspect"; - case invtype::InvTypeRealEstate: + case invtype::typeRealEstate: return "Real Estate"; - case invtype::InvTypeViewMODPC: + case invtype::typeViewMODPC: return "View MOD PC"; - case invtype::InvTypeViewMODBank: + case invtype::typeViewMODBank: return "View MOD Bank"; - case invtype::InvTypeViewMODSharedBank: + case invtype::typeViewMODSharedBank: return "View MOD Shared Bank"; - case invtype::InvTypeViewMODLimbo: + case invtype::typeViewMODLimbo: return "View MOD Limbo"; - case invtype::InvTypeAltStorage: + case invtype::typeAltStorage: return "Alt Storage"; - case invtype::InvTypeArchived: + case invtype::typeArchived: return "Archived"; - case invtype::InvTypeMail: + case invtype::typeMail: return "Mail"; - case invtype::InvTypeGuildTrophyTribute: + case invtype::typeGuildTrophyTribute: return "Guild Trophy Tribute"; - case invtype::InvTypeKrono: + case invtype::typeKrono: return "Krono"; - case invtype::InvTypeOther: + case invtype::typeOther: return "Other"; default: return "Unknown Type"; } } -bool RoF2::invtype::IsInvTypePersistent(int inv_type) +bool RoF2::invtype::IsInvTypePersistent(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - case invtype::InvTypeBank: - case invtype::InvTypeSharedBank: - case invtype::InvTypeTrade: - case invtype::InvTypeWorld: - case invtype::InvTypeLimbo: - case invtype::InvTypeTribute: - case invtype::InvTypeTrophyTribute: - case invtype::InvTypeGuildTribute: + case invtype::typePossessions: + case invtype::typeBank: + case invtype::typeSharedBank: + case invtype::typeTrade: + case invtype::typeWorld: + case invtype::typeLimbo: + case invtype::typeTribute: + case invtype::typeTrophyTribute: + case invtype::typeGuildTribute: return true; default: return false; } } -const char* RoF2::invslot::GetInvPossessionsSlotName(int inv_slot) +const char* RoF2::invslot::GetInvPossessionsSlotName(int16 inv_slot) { switch (inv_slot) { - case invslot::InvSlotInvalid: + case invslot::SLOT_INVALID: return "Invalid Slot"; - case invslot::PossessionsCharm: + case invslot::slotCharm: return "Charm"; - case invslot::PossessionsEar1: + case invslot::slotEar1: return "Ear 1"; - case invslot::PossessionsHead: + case invslot::slotHead: return "Head"; - case invslot::PossessionsFace: + case invslot::slotFace: return "Face"; - case invslot::PossessionsEar2: + case invslot::slotEar2: return "Ear 2"; - case invslot::PossessionsNeck: + case invslot::slotNeck: return "Neck"; - case invslot::PossessionsShoulders: + case invslot::slotShoulders: return "Shoulders"; - case invslot::PossessionsArms: + case invslot::slotArms: return "Arms"; - case invslot::PossessionsBack: + case invslot::slotBack: return "Back"; - case invslot::PossessionsWrist1: + case invslot::slotWrist1: return "Wrist 1"; - case invslot::PossessionsWrist2: + case invslot::slotWrist2: return "Wrist 2"; - case invslot::PossessionsRange: + case invslot::slotRange: return "Range"; - case invslot::PossessionsHands: + case invslot::slotHands: return "Hands"; - case invslot::PossessionsPrimary: + case invslot::slotPrimary: return "Primary"; - case invslot::PossessionsSecondary: + case invslot::slotSecondary: return "Secondary"; - case invslot::PossessionsFinger1: + case invslot::slotFinger1: return "Finger 1"; - case invslot::PossessionsFinger2: + case invslot::slotFinger2: return "Finger 2"; - case invslot::PossessionsChest: + case invslot::slotChest: return "Chest"; - case invslot::PossessionsLegs: + case invslot::slotLegs: return "Legs"; - case invslot::PossessionsFeet: + case invslot::slotFeet: return "Feet"; - case invslot::PossessionsWaist: + case invslot::slotWaist: return "Waist"; - case invslot::PossessionsPowerSource: + case invslot::slotPowerSource: return "Power Source"; - case invslot::PossessionsAmmo: + case invslot::slotAmmo: return "Ammo"; - case invslot::PossessionsGeneral1: + case invslot::slotGeneral1: return "General 1"; - case invslot::PossessionsGeneral2: + case invslot::slotGeneral2: return "General 2"; - case invslot::PossessionsGeneral3: + case invslot::slotGeneral3: return "General 3"; - case invslot::PossessionsGeneral4: + case invslot::slotGeneral4: return "General 4"; - case invslot::PossessionsGeneral5: + case invslot::slotGeneral5: return "General 5"; - case invslot::PossessionsGeneral6: + case invslot::slotGeneral6: return "General 6"; - case invslot::PossessionsGeneral7: + case invslot::slotGeneral7: return "General 7"; - case invslot::PossessionsGeneral8: + case invslot::slotGeneral8: return "General 8"; - case invslot::PossessionsGeneral9: + case invslot::slotGeneral9: return "General 9"; - case invslot::PossessionsGeneral10: + case invslot::slotGeneral10: return "General 10"; - case invslot::PossessionsCursor: + case invslot::slotCursor: return "Cursor"; default: return "Unknown Slot"; } } -const char* RoF2::invslot::GetInvSlotName(int inv_type, int inv_slot) +const char* RoF2::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot) { - if (inv_type == invtype::InvTypePossessions) + if (inv_type == invtype::typePossessions) return invslot::GetInvPossessionsSlotName(inv_slot); - size_t type_size = invtype::GetInvTypeSize(inv_type); + int16 type_size = invtype::GetInvTypeSize(inv_type); - if (!type_size || inv_slot == invslot::InvSlotInvalid) + if (!type_size || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; - if ((size_t)(inv_slot + 1) >= type_size) + if ((inv_slot + 1) >= type_size) return "Unknown Slot"; static std::string ret_str; @@ -255,12 +255,12 @@ const char* RoF2::invslot::GetInvSlotName(int inv_type, int inv_slot) return ret_str.c_str(); } -const char* RoF2::invbag::GetInvBagIndexName(int bag_index) +const char* RoF2::invbag::GetInvBagIndexName(int16 bag_index) { - if (bag_index == invbag::InvBagInvalid) + if (bag_index == invbag::SLOT_INVALID) return "Invalid Bag"; - if ((size_t)bag_index >= invbag::ItemBagSize) + if (bag_index >= invbag::SLOT_COUNT) return "Unknown Bag"; static std::string ret_str; @@ -269,12 +269,12 @@ const char* RoF2::invbag::GetInvBagIndexName(int bag_index) return ret_str.c_str(); } -const char* RoF2::invaug::GetInvAugIndexName(int aug_index) +const char* RoF2::invaug::GetInvAugIndexName(int16 aug_index) { - if (aug_index == invaug::InvAugInvalid) + if (aug_index == invaug::SOCKET_INVALID) return "Invalid Augment"; - if ((size_t)aug_index >= invaug::ItemAugSize) + if (aug_index >= invaug::SOCKET_COUNT) return "Unknown Augment"; static std::string ret_str; diff --git a/common/patches/rof2_limits.h b/common/patches/rof2_limits.h index 0dd7067a9..96c231cf4 100644 --- a/common/patches/rof2_limits.h +++ b/common/patches/rof2_limits.h @@ -27,116 +27,191 @@ namespace RoF2 { - enum : int { Invalid = -1, Null, Safety }; + const int16 IINVALID = -1; + const int16 INULL = 0; - enum : bool { False = false, True = true }; - - // pre-declarations namespace inventory { inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::RoF2; } + const bool ConcatenateInvTypeLimbo = false; + + const bool AllowOverLevelEquipment = true; + + const bool AllowEmptyBagInBag = true; + const bool AllowClickCastFromBag = true; + } /*inventory*/ namespace invtype { inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::RoF2; } - enum : int { InvTypeInvalid = -1, InvTypeBegin }; + namespace enum_ { + enum InventoryTypes : int16 { + typePossessions = INULL, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, + typeTribute, + typeTrophyTribute, + typeGuildTribute, + typeMerchant, + typeDeleted, + typeCorpse, + typeBazaar, + typeInspect, + typeRealEstate, + typeViewMODPC, + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, + typeMail, + typeGuildTrophyTribute, + typeKrono, + typeOther + }; - enum InventoryType : int { - InvTypePossessions = InvTypeBegin, - InvTypeBank, - InvTypeSharedBank, - InvTypeTrade, - InvTypeWorld, - InvTypeLimbo, - InvTypeTribute, - InvTypeTrophyTribute, - InvTypeGuildTribute, - InvTypeMerchant, - InvTypeDeleted, - InvTypeCorpse, - InvTypeBazaar, - InvTypeInspect, - InvTypeRealEstate, - InvTypeViewMODPC, - InvTypeViewMODBank, - InvTypeViewMODSharedBank, - InvTypeViewMODLimbo, - InvTypeAltStorage, - InvTypeArchived, - InvTypeMail, - InvTypeGuildTrophyTribute, - InvTypeKrono, - InvTypeOther, - InvTypeCount - }; + } // namespace enum_ + using namespace enum_; + + const int16 POSSESSIONS_SIZE = 34; + const int16 BANK_SIZE = 24; + const int16 SHARED_BANK_SIZE = 2; + const int16 TRADE_SIZE = 8; + const int16 WORLD_SIZE = 10; + const int16 LIMBO_SIZE = 36; + const int16 TRIBUTE_SIZE = 5; + const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown + const int16 GUILD_TRIBUTE_SIZE = 2;//unverified + const int16 MERCHANT_SIZE = 200; + const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab" + const int16 CORPSE_SIZE = POSSESSIONS_SIZE; + const int16 BAZAAR_SIZE = 200; + const int16 INSPECT_SIZE = 23; + const int16 REAL_ESTATE_SIZE = 0;//unknown + const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE; + const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE; + const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE; + const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE; + const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank" + const int16 ARCHIVED_SIZE = 0;//unknown + const int16 MAIL_SIZE = 0;//unknown + const int16 GUILD_TROPHY_TRIBUTE_SIZE = 0;//unknown + const int16 KRONO_SIZE = 0;//unknown + const int16 OTHER_SIZE = 0;//unknown + + const int16 TRADE_NPC_SIZE = 4; // defined by implication + + const int16 TYPE_INVALID = IINVALID; + const int16 TYPE_BEGIN = typePossessions; + const int16 TYPE_END = typeOther; + const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1; + + int16 GetInvTypeSize(int16 inv_type); + const char* GetInvTypeName(int16 inv_type); + + bool IsInvTypePersistent(int16 inv_type); } /*invtype*/ namespace invslot { inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::RoF2; } - enum : int { InvSlotInvalid = -1, InvSlotBegin }; + namespace enum_ { + enum InventorySlots : int16 { + slotCharm = INULL, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, + slotPowerSource, + slotAmmo, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotGeneral9, + slotGeneral10, + slotCursor + }; - enum PossessionsSlot : int { - PossessionsCharm = InvSlotBegin, - PossessionsEar1, - PossessionsHead, - PossessionsFace, - PossessionsEar2, - PossessionsNeck, - PossessionsShoulders, - PossessionsArms, - PossessionsBack, - PossessionsWrist1, - PossessionsWrist2, - PossessionsRange, - PossessionsHands, - PossessionsPrimary, - PossessionsSecondary, - PossessionsFinger1, - PossessionsFinger2, - PossessionsChest, - PossessionsLegs, - PossessionsFeet, - PossessionsWaist, - PossessionsPowerSource, - PossessionsAmmo, - PossessionsGeneral1, - PossessionsGeneral2, - PossessionsGeneral3, - PossessionsGeneral4, - PossessionsGeneral5, - PossessionsGeneral6, - PossessionsGeneral7, - PossessionsGeneral8, - PossessionsGeneral9, - PossessionsGeneral10, - PossessionsCursor, - PossessionsCount - }; + } // namespace enum_ + using namespace enum_; - const int EquipmentBegin = PossessionsCharm; - const int EquipmentEnd = PossessionsAmmo; - const int EquipmentCount = (EquipmentEnd - EquipmentBegin + 1); + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; - const int GeneralBegin = PossessionsGeneral1; - const int GeneralEnd = PossessionsGeneral10; - const int GeneralCount = (GeneralEnd - GeneralBegin + 1); + const int16 POSSESSIONS_BEGIN = slotCharm; + const int16 POSSESSIONS_END = slotCursor; + const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; + + const int16 EQUIPMENT_BEGIN = slotCharm; + const int16 EQUIPMENT_END = slotAmmo; + const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN) + 1; + + const int16 GENERAL_BEGIN = slotGeneral1; + const int16 GENERAL_END = slotGeneral10; + const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN) + 1; + + const int16 BONUS_BEGIN = invslot::slotCharm; + const int16 BONUS_STAT_END = invslot::slotPowerSource; + const int16 BONUS_SKILL_END = invslot::slotAmmo; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor; + + const uint64 POSSESSIONS_BITMASK = 0x00000003FFFFFFFF; // based on 34-slot count (RoF+) + const uint64 CORPSE_BITMASK = 0x01FFFFFFFF800000; // based on 34-slot count (RoF+) + + const char* GetInvPossessionsSlotName(int16 inv_slot); + const char* GetInvSlotName(int16 inv_type, int16 inv_slot); } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::RoF2; } - enum : int { InvBagInvalid = -1, InvBagBegin }; + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; + const int16 SLOT_END = 9; //254; + const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test) + + const char* GetInvBagIndexName(int16 bag_index); } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::RoF2; } - enum : int { InvAugInvalid = -1, InvAugBegin }; + const int16 SOCKET_INVALID = IINVALID; + const int16 SOCKET_BEGIN = INULL; + const int16 SOCKET_END = 5; + const int16 SOCKET_COUNT = 6; + + const char* GetInvAugIndexName(int16 aug_index); } /*invaug*/ @@ -172,110 +247,21 @@ namespace RoF2 namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::RoF2; } + const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances + const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance + + const int16 POTION_BELT_SIZE = 5; + + const int16 SKILL_ARRAY_SIZE = 100; + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::RoF2; } - } /*constants*/ + const size_t CHARACTER_CREATION_LIMIT = 12; - namespace behavior { - inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::RoF2; } - - } /*behavior*/ - - namespace skills { - inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF2; } - - } /*skills*/ - - - // declarations - namespace inventory { - const bool ConcatenateInvTypeLimbo = false; - - const bool AllowOverLevelEquipment = true; - - const bool AllowEmptyBagInBag = true; - const bool AllowClickCastFromBag = true; - - } /*inventory*/ - - namespace invtype { - const size_t InvTypePossessionsSize = invslot::PossessionsCount; - const size_t InvTypeBankSize = 24; - const size_t InvTypeSharedBankSize = 2; - const size_t InvTypeTradeSize = 8; - const size_t InvTypeWorldSize = 10; - const size_t InvTypeLimboSize = 36; - const size_t InvTypeTributeSize = 5; - const size_t InvTypeTrophyTributeSize = 0;//unknown - const size_t InvTypeGuildTributeSize = 2;//unverified - const size_t InvTypeMerchantSize = 200; - const size_t InvTypeDeletedSize = 0;//unknown - "Recovery Tab" - const size_t InvTypeCorpseSize = InvTypePossessionsSize; - const size_t InvTypeBazaarSize = 200; - const size_t InvTypeInspectSize = invslot::EquipmentCount; - const size_t InvTypeRealEstateSize = 0;//unknown - const size_t InvTypeViewMODPCSize = InvTypePossessionsSize; - const size_t InvTypeViewMODBankSize = InvTypeBankSize; - const size_t InvTypeViewMODSharedBankSize = InvTypeSharedBankSize; - const size_t InvTypeViewMODLimboSize = InvTypeLimboSize; - const size_t InvTypeAltStorageSize = 0;//unknown - "Shroud Bank" - const size_t InvTypeArchivedSize = 0;//unknown - const size_t InvTypeMailSize = 0;//unknown - const size_t InvTypeGuildTrophyTributeSize = 0;//unknown - const size_t InvTypeKronoSize = 0;//unknown - const size_t InvTypeOtherSize = 0;//unknown - - extern size_t GetInvTypeSize(int inv_type); - extern const char* GetInvTypeName(int inv_type); - - extern bool IsInvTypePersistent(int inv_type); - - } /*invtype*/ - - namespace invslot { - extern const char* GetInvPossessionsSlotName(int inv_slot); - extern const char* GetInvSlotName(int inv_type, int inv_slot); - - } /*invslot*/ - - namespace invbag { - const size_t ItemBagSize = 255; // server Size will be 255..unsure what actual client is (test) - - extern const char* GetInvBagIndexName(int bag_index); - - } /*invbag*/ - - namespace invaug { - const size_t ItemAugSize = 6; - - extern const char* GetInvAugIndexName(int aug_index); - - } /*invaug*/ - - namespace item { - - } /*item*/ - - namespace profile { - const size_t TributeSize = invtype::InvTypeTributeSize; - const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize; - - const size_t BandoliersSize = 20; // number of bandolier instances - const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance - - const size_t PotionBeltSize = 5; - - const size_t SkillArraySize = 100; - - } /*profile*/ - - namespace constants { - const size_t CharacterCreationLimit = 12; - - const size_t SayLinkBodySize = 56; + const size_t SAY_LINK_BODY_SIZE = 56; const int LongBuffs = 42; const int ShortBuffs = 20; @@ -288,11 +274,15 @@ namespace RoF2 } /*constants*/ namespace behavior { + inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::RoF2; } + const bool CoinHasWeight = false; } /*behavior*/ namespace skills { + inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF2; } + const size_t LastUsableSkill = EQEmu::skills::Skill2HPiercing; } /*skills*/ diff --git a/common/patches/rof2_ops.h b/common/patches/rof2_ops.h index 2cd81aaee..7ee120c97 100644 --- a/common/patches/rof2_ops.h +++ b/common/patches/rof2_ops.h @@ -98,7 +98,6 @@ E(OP_MoveItem) E(OP_NewSpawn) E(OP_NewZone) E(OP_OnLevelMessage) -//E(OP_OpenNewTasksWindow) E(OP_PetBuffWindow) E(OP_PlayerProfile) E(OP_RaidJoin) diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index 13ce49f6e..f53675f83 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -957,13 +957,13 @@ struct BandolierItem_Struct_Old struct Bandolier_Struct { char Name[1]; // Variable Length - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; struct Bandolier_Struct_Old { char Name[32]; - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; struct PotionBeltItem_Struct @@ -983,12 +983,12 @@ struct PotionBeltItem_Struct_Old struct PotionBelt_Struct { - PotionBeltItem_Struct Items[profile::PotionBeltSize]; + PotionBeltItem_Struct Items[profile::POTION_BELT_SIZE]; }; struct PotionBelt_Struct_Old { - PotionBeltItem_Struct_Old Items[profile::PotionBeltSize]; + PotionBeltItem_Struct_Old Items[profile::POTION_BELT_SIZE]; }; struct GroupLeadershipAA_Struct { @@ -1198,7 +1198,7 @@ union /*12949*/ uint32 aapoints; // Unspent AA points - Seen 1 /*12953*/ uint16 unknown_rof20; // /*12955*/ uint32 bandolier_count; // Seen 20 -/*12959*/ Bandolier_Struct bandoliers[profile::BandoliersSize]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents +/*12959*/ Bandolier_Struct bandoliers[profile::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents /*13699*/ uint32 potionbelt_count; // Seen 5 /*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes) /*13748*/ int32 unknown_rof21; // Seen -1 diff --git a/common/patches/rof_limits.cpp b/common/patches/rof_limits.cpp index c78ffc59d..6c30b85f7 100644 --- a/common/patches/rof_limits.cpp +++ b/common/patches/rof_limits.cpp @@ -22,227 +22,227 @@ #include "../string_util.h" -size_t RoF::invtype::GetInvTypeSize(int inv_type) +int16 RoF::invtype::GetInvTypeSize(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - return invtype::InvTypePossessionsSize; - case invtype::InvTypeBank: - return invtype::InvTypeBankSize; - case invtype::InvTypeSharedBank: - return invtype::InvTypeSharedBankSize; - case invtype::InvTypeTrade: - return invtype::InvTypeTradeSize; - case invtype::InvTypeWorld: - return invtype::InvTypeWorldSize; - case invtype::InvTypeLimbo: - return invtype::InvTypeLimboSize; - case invtype::InvTypeTribute: - return invtype::InvTypeTributeSize; - case invtype::InvTypeTrophyTribute: - return invtype::InvTypeTrophyTributeSize; - case invtype::InvTypeGuildTribute: - return invtype::InvTypeGuildTributeSize; - case invtype::InvTypeMerchant: - return invtype::InvTypeMerchantSize; - case invtype::InvTypeDeleted: - return invtype::InvTypeDeletedSize; - case invtype::InvTypeCorpse: - return invtype::InvTypeCorpseSize; - case invtype::InvTypeBazaar: - return invtype::InvTypeBazaarSize; - case invtype::InvTypeInspect: - return invtype::InvTypeInspectSize; - case invtype::InvTypeRealEstate: - return invtype::InvTypeRealEstateSize; - case invtype::InvTypeViewMODPC: - return invtype::InvTypeViewMODPCSize; - case invtype::InvTypeViewMODBank: - return invtype::InvTypeViewMODBankSize; - case invtype::InvTypeViewMODSharedBank: - return invtype::InvTypeViewMODSharedBankSize; - case invtype::InvTypeViewMODLimbo: - return invtype::InvTypeViewMODLimboSize; - case invtype::InvTypeAltStorage: - return invtype::InvTypeAltStorageSize; - case invtype::InvTypeArchived: - return invtype::InvTypeArchivedSize; - case invtype::InvTypeMail: - return invtype::InvTypeMailSize; - case invtype::InvTypeGuildTrophyTribute: - return invtype::InvTypeGuildTrophyTributeSize; - case invtype::InvTypeOther: - return invtype::InvTypeOtherSize; + case invtype::typePossessions: + return invtype::POSSESSIONS_SIZE; + case invtype::typeBank: + return invtype::BANK_SIZE; + case invtype::typeSharedBank: + return invtype::SHARED_BANK_SIZE; + case invtype::typeTrade: + return invtype::TRADE_SIZE; + case invtype::typeWorld: + return invtype::WORLD_SIZE; + case invtype::typeLimbo: + return invtype::LIMBO_SIZE; + case invtype::typeTribute: + return invtype::TRIBUTE_SIZE; + case invtype::typeTrophyTribute: + return invtype::TROPHY_TRIBUTE_SIZE; + case invtype::typeGuildTribute: + return invtype::GUILD_TRIBUTE_SIZE; + case invtype::typeMerchant: + return invtype::MERCHANT_SIZE; + case invtype::typeDeleted: + return invtype::DELETED_SIZE; + case invtype::typeCorpse: + return invtype::CORPSE_SIZE; + case invtype::typeBazaar: + return invtype::BAZAAR_SIZE; + case invtype::typeInspect: + return invtype::INSPECT_SIZE; + case invtype::typeRealEstate: + return invtype::REAL_ESTATE_SIZE; + case invtype::typeViewMODPC: + return invtype::VIEW_MOD_PC_SIZE; + case invtype::typeViewMODBank: + return invtype::VIEW_MOD_BANK_SIZE; + case invtype::typeViewMODSharedBank: + return invtype::VIEW_MOD_SHARED_BANK_SIZE; + case invtype::typeViewMODLimbo: + return invtype::VIEW_MOD_LIMBO_SIZE; + case invtype::typeAltStorage: + return invtype::ALT_STORAGE_SIZE; + case invtype::typeArchived: + return invtype::ARCHIVED_SIZE; + case invtype::typeMail: + return invtype::MAIL_SIZE; + case invtype::typeGuildTrophyTribute: + return invtype::GUILD_TROPHY_TRIBUTE_SIZE; + case invtype::typeOther: + return invtype::OTHER_SIZE; default: - return 0; + return INULL; } } -const char* RoF::invtype::GetInvTypeName(int inv_type) +const char* RoF::invtype::GetInvTypeName(int16 inv_type) { switch (inv_type) { - case invtype::InvTypeInvalid: + case invtype::TYPE_INVALID: return "Invalid Type"; - case invtype::InvTypePossessions: + case invtype::typePossessions: return "Possessions"; - case invtype::InvTypeBank: + case invtype::typeBank: return "Bank"; - case invtype::InvTypeSharedBank: + case invtype::typeSharedBank: return "Shared Bank"; - case invtype::InvTypeTrade: + case invtype::typeTrade: return "Trade"; - case invtype::InvTypeWorld: + case invtype::typeWorld: return "World"; - case invtype::InvTypeLimbo: + case invtype::typeLimbo: return "Limbo"; - case invtype::InvTypeTribute: + case invtype::typeTribute: return "Tribute"; - case invtype::InvTypeTrophyTribute: + case invtype::typeTrophyTribute: return "Trophy Tribute"; - case invtype::InvTypeGuildTribute: + case invtype::typeGuildTribute: return "Guild Tribute"; - case invtype::InvTypeMerchant: + case invtype::typeMerchant: return "Merchant"; - case invtype::InvTypeDeleted: + case invtype::typeDeleted: return "Deleted"; - case invtype::InvTypeCorpse: + case invtype::typeCorpse: return "Corpse"; - case invtype::InvTypeBazaar: + case invtype::typeBazaar: return "Bazaar"; - case invtype::InvTypeInspect: + case invtype::typeInspect: return "Inspect"; - case invtype::InvTypeRealEstate: + case invtype::typeRealEstate: return "Real Estate"; - case invtype::InvTypeViewMODPC: + case invtype::typeViewMODPC: return "View MOD PC"; - case invtype::InvTypeViewMODBank: + case invtype::typeViewMODBank: return "View MOD Bank"; - case invtype::InvTypeViewMODSharedBank: + case invtype::typeViewMODSharedBank: return "View MOD Shared Bank"; - case invtype::InvTypeViewMODLimbo: + case invtype::typeViewMODLimbo: return "View MOD Limbo"; - case invtype::InvTypeAltStorage: + case invtype::typeAltStorage: return "Alt Storage"; - case invtype::InvTypeArchived: + case invtype::typeArchived: return "Archived"; - case invtype::InvTypeMail: + case invtype::typeMail: return "Mail"; - case invtype::InvTypeGuildTrophyTribute: + case invtype::typeGuildTrophyTribute: return "Guild Trophy Tribute"; - case invtype::InvTypeOther: + case invtype::typeOther: return "Other"; default: return "Unknown Type"; } } -bool RoF::invtype::IsInvTypePersistent(int inv_type) +bool RoF::invtype::IsInvTypePersistent(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - case invtype::InvTypeBank: - case invtype::InvTypeSharedBank: - case invtype::InvTypeTrade: - case invtype::InvTypeWorld: - case invtype::InvTypeLimbo: - case invtype::InvTypeTribute: - case invtype::InvTypeTrophyTribute: - case invtype::InvTypeGuildTribute: + case invtype::typePossessions: + case invtype::typeBank: + case invtype::typeSharedBank: + case invtype::typeTrade: + case invtype::typeWorld: + case invtype::typeLimbo: + case invtype::typeTribute: + case invtype::typeTrophyTribute: + case invtype::typeGuildTribute: return true; default: return false; } } -const char* RoF::invslot::GetInvPossessionsSlotName(int inv_slot) +const char* RoF::invslot::GetInvPossessionsSlotName(int16 inv_slot) { switch (inv_slot) { - case invslot::InvSlotInvalid: + case invslot::SLOT_INVALID: return "Invalid Slot"; - case invslot::PossessionsCharm: + case invslot::slotCharm: return "Charm"; - case invslot::PossessionsEar1: + case invslot::slotEar1: return "Ear 1"; - case invslot::PossessionsHead: + case invslot::slotHead: return "Head"; - case invslot::PossessionsFace: + case invslot::slotFace: return "Face"; - case invslot::PossessionsEar2: + case invslot::slotEar2: return "Ear 2"; - case invslot::PossessionsNeck: + case invslot::slotNeck: return "Neck"; - case invslot::PossessionsShoulders: + case invslot::slotShoulders: return "Shoulders"; - case invslot::PossessionsArms: + case invslot::slotArms: return "Arms"; - case invslot::PossessionsBack: + case invslot::slotBack: return "Back"; - case invslot::PossessionsWrist1: + case invslot::slotWrist1: return "Wrist 1"; - case invslot::PossessionsWrist2: + case invslot::slotWrist2: return "Wrist 2"; - case invslot::PossessionsRange: + case invslot::slotRange: return "Range"; - case invslot::PossessionsHands: + case invslot::slotHands: return "Hands"; - case invslot::PossessionsPrimary: + case invslot::slotPrimary: return "Primary"; - case invslot::PossessionsSecondary: + case invslot::slotSecondary: return "Secondary"; - case invslot::PossessionsFinger1: + case invslot::slotFinger1: return "Finger 1"; - case invslot::PossessionsFinger2: + case invslot::slotFinger2: return "Finger 2"; - case invslot::PossessionsChest: + case invslot::slotChest: return "Chest"; - case invslot::PossessionsLegs: + case invslot::slotLegs: return "Legs"; - case invslot::PossessionsFeet: + case invslot::slotFeet: return "Feet"; - case invslot::PossessionsWaist: + case invslot::slotWaist: return "Waist"; - case invslot::PossessionsPowerSource: + case invslot::slotPowerSource: return "Power Source"; - case invslot::PossessionsAmmo: + case invslot::slotAmmo: return "Ammo"; - case invslot::PossessionsGeneral1: + case invslot::slotGeneral1: return "General 1"; - case invslot::PossessionsGeneral2: + case invslot::slotGeneral2: return "General 2"; - case invslot::PossessionsGeneral3: + case invslot::slotGeneral3: return "General 3"; - case invslot::PossessionsGeneral4: + case invslot::slotGeneral4: return "General 4"; - case invslot::PossessionsGeneral5: + case invslot::slotGeneral5: return "General 5"; - case invslot::PossessionsGeneral6: + case invslot::slotGeneral6: return "General 6"; - case invslot::PossessionsGeneral7: + case invslot::slotGeneral7: return "General 7"; - case invslot::PossessionsGeneral8: + case invslot::slotGeneral8: return "General 8"; - case invslot::PossessionsGeneral9: + case invslot::slotGeneral9: return "General 9"; - case invslot::PossessionsGeneral10: + case invslot::slotGeneral10: return "General 10"; - case invslot::PossessionsCursor: + case invslot::slotCursor: return "Cursor"; default: return "Unknown Slot"; } } -const char* RoF::invslot::GetInvSlotName(int inv_type, int inv_slot) +const char* RoF::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot) { - if (inv_type == invtype::InvTypePossessions) + if (inv_type == invtype::typePossessions) return invslot::GetInvPossessionsSlotName(inv_slot); - size_t type_size = invtype::GetInvTypeSize(inv_type); + int16 type_size = invtype::GetInvTypeSize(inv_type); - if (!type_size || inv_slot == invslot::InvSlotInvalid) + if (!type_size || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; - if ((size_t)(inv_slot + 1) >= type_size) + if ((inv_slot + 1) >= type_size) return "Unknown Slot"; static std::string ret_str; @@ -251,12 +251,12 @@ const char* RoF::invslot::GetInvSlotName(int inv_type, int inv_slot) return ret_str.c_str(); } -const char* RoF::invbag::GetInvBagIndexName(int bag_index) +const char* RoF::invbag::GetInvBagIndexName(int16 bag_index) { - if (bag_index == invbag::InvBagInvalid) + if (bag_index == invbag::SLOT_INVALID) return "Invalid Bag"; - if ((size_t)bag_index >= invbag::ItemBagSize) + if (bag_index >= invbag::SLOT_COUNT) return "Unknown Bag"; static std::string ret_str; @@ -265,12 +265,12 @@ const char* RoF::invbag::GetInvBagIndexName(int bag_index) return ret_str.c_str(); } -const char* RoF::invaug::GetInvAugIndexName(int aug_index) +const char* RoF::invaug::GetInvAugIndexName(int16 aug_index) { - if (aug_index == invaug::InvAugInvalid) + if (aug_index == invaug::SOCKET_INVALID) return "Invalid Augment"; - if ((size_t)aug_index >= invaug::ItemAugSize) + if (aug_index >= invaug::SOCKET_COUNT) return "Unknown Augment"; static std::string ret_str; diff --git a/common/patches/rof_limits.h b/common/patches/rof_limits.h index 952d14b20..69db29f8f 100644 --- a/common/patches/rof_limits.h +++ b/common/patches/rof_limits.h @@ -27,115 +27,189 @@ namespace RoF { - enum : int { Invalid = -1, Null, Safety }; + const int16 IINVALID = -1; + const int16 INULL = 0; - enum : bool { False = false, True = true }; - - // pre-declarations namespace inventory { inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::RoF; } + const bool ConcatenateInvTypeLimbo = false; + + const bool AllowOverLevelEquipment = true; + + const bool AllowEmptyBagInBag = true; + const bool AllowClickCastFromBag = true; + } /*inventory*/ namespace invtype { inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::RoF; } - enum : int { InvTypeInvalid = -1, InvTypeBegin }; + namespace enum_ { + enum InventoryTypes : int16 { + typePossessions = INULL, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, + typeTribute, + typeTrophyTribute, + typeGuildTribute, + typeMerchant, + typeDeleted, + typeCorpse, + typeBazaar, + typeInspect, + typeRealEstate, + typeViewMODPC, + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, + typeMail, + typeGuildTrophyTribute, + typeOther + }; - enum InventoryType : int { - InvTypePossessions = InvTypeBegin, - InvTypeBank, - InvTypeSharedBank, - InvTypeTrade, - InvTypeWorld, - InvTypeLimbo, - InvTypeTribute, - InvTypeTrophyTribute, - InvTypeGuildTribute, - InvTypeMerchant, - InvTypeDeleted, - InvTypeCorpse, - InvTypeBazaar, - InvTypeInspect, - InvTypeRealEstate, - InvTypeViewMODPC, - InvTypeViewMODBank, - InvTypeViewMODSharedBank, - InvTypeViewMODLimbo, - InvTypeAltStorage, - InvTypeArchived, - InvTypeMail, - InvTypeGuildTrophyTribute, - InvTypeOther, - InvTypeCount - }; + } // namespace enum_ + using namespace enum_; + + const int16 POSSESSIONS_SIZE = 34; + const int16 BANK_SIZE = 24; + const int16 SHARED_BANK_SIZE = 2; + const int16 TRADE_SIZE = 8; + const int16 WORLD_SIZE = 10; + const int16 LIMBO_SIZE = 36; + const int16 TRIBUTE_SIZE = 5; + const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown + const int16 GUILD_TRIBUTE_SIZE = 2;//unverified + const int16 MERCHANT_SIZE = 200; + const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab" + const int16 CORPSE_SIZE = POSSESSIONS_SIZE; + const int16 BAZAAR_SIZE = 200; + const int16 INSPECT_SIZE = 23; + const int16 REAL_ESTATE_SIZE = 0;//unknown + const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE; + const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE; + const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE; + const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE; + const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank" + const int16 ARCHIVED_SIZE = 0;//unknown + const int16 MAIL_SIZE = 0;//unknown + const int16 GUILD_TROPHY_TRIBUTE_SIZE = 0;//unknown + const int16 OTHER_SIZE = 0;//unknown + + const int16 TRADE_NPC_SIZE = 4; // defined by implication + + const int16 TYPE_INVALID = IINVALID; + const int16 TYPE_BEGIN = typePossessions; + const int16 TYPE_END = typeOther; + const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1; + + int16 GetInvTypeSize(int16 inv_type); + const char* GetInvTypeName(int16 inv_type); + + bool IsInvTypePersistent(int16 inv_type); } /*invtype*/ namespace invslot { inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::RoF; } - enum : int { InvSlotInvalid = -1, InvSlotBegin }; + namespace enum_ { + enum InventorySlots : int16 { + slotCharm = INULL, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, + slotPowerSource, + slotAmmo, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotGeneral9, + slotGeneral10, + slotCursor + }; - enum PossessionsSlot : int { - PossessionsCharm = InvSlotBegin, - PossessionsEar1, - PossessionsHead, - PossessionsFace, - PossessionsEar2, - PossessionsNeck, - PossessionsShoulders, - PossessionsArms, - PossessionsBack, - PossessionsWrist1, - PossessionsWrist2, - PossessionsRange, - PossessionsHands, - PossessionsPrimary, - PossessionsSecondary, - PossessionsFinger1, - PossessionsFinger2, - PossessionsChest, - PossessionsLegs, - PossessionsFeet, - PossessionsWaist, - PossessionsPowerSource, - PossessionsAmmo, - PossessionsGeneral1, - PossessionsGeneral2, - PossessionsGeneral3, - PossessionsGeneral4, - PossessionsGeneral5, - PossessionsGeneral6, - PossessionsGeneral7, - PossessionsGeneral8, - PossessionsGeneral9, - PossessionsGeneral10, - PossessionsCursor, - PossessionsCount - }; + } // namespace enum_ + using namespace enum_; - const int EquipmentBegin = PossessionsCharm; - const int EquipmentEnd = PossessionsAmmo; - const int EquipmentCount = (EquipmentEnd - EquipmentBegin + 1); + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; - const int GeneralBegin = PossessionsGeneral1; - const int GeneralEnd = PossessionsGeneral10; - const int GeneralCount = (GeneralEnd - GeneralBegin + 1); + const int16 POSSESSIONS_BEGIN = slotCharm; + const int16 POSSESSIONS_END = slotCursor; + const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; + + const int16 EQUIPMENT_BEGIN = slotCharm; + const int16 EQUIPMENT_END = slotAmmo; + const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN + 1); + + const int16 GENERAL_BEGIN = slotGeneral1; + const int16 GENERAL_END = slotGeneral10; + const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN + 1); + + const int16 BONUS_BEGIN = invslot::slotCharm; + const int16 BONUS_STAT_END = invslot::slotPowerSource; + const int16 BONUS_SKILL_END = invslot::slotAmmo; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor; + + const uint64 POSSESSIONS_BITMASK = 0x00000003FFFFFFFF; // based on 34-slot count (RoF+) + const uint64 CORPSE_BITMASK = 0x01FFFFFFFF800000; // based on 34-slot count (RoF+) + + const char* GetInvPossessionsSlotName(int16 inv_slot); + const char* GetInvSlotName(int16 inv_type, int16 inv_slot); } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::RoF; } - enum : int { InvBagInvalid = -1, InvBagBegin }; + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; + const int16 SLOT_END = 9; //254; + const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test) + + const char* GetInvBagIndexName(int16 bag_index); } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::RoF; } - enum : int { InvAugInvalid = -1, InvAugBegin }; + const int16 SOCKET_INVALID = IINVALID; + const int16 SOCKET_BEGIN = INULL; + const int16 SOCKET_END = 5; + const int16 SOCKET_COUNT = 6; + + const char* GetInvAugIndexName(int16 aug_index); } /*invaug*/ @@ -164,109 +238,21 @@ namespace RoF namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::RoF; } + const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances + const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance + + const int16 POTION_BELT_SIZE = 5; + + const int16 SKILL_ARRAY_SIZE = 100; + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::RoF; } - } /*constants*/ + const size_t CHARACTER_CREATION_LIMIT = 12; - namespace behavior { - inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::RoF; } - - } /*behavior*/ - - namespace skills { - inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF; } - - } /*skills*/ - - - // declarations - namespace inventory { - const bool ConcatenateInvTypeLimbo = false; - - const bool AllowOverLevelEquipment = true; - - const bool AllowEmptyBagInBag = true; - const bool AllowClickCastFromBag = true; - - } /*inventory*/ - - namespace invtype { - const size_t InvTypePossessionsSize = invslot::PossessionsCount; - const size_t InvTypeBankSize = 24; - const size_t InvTypeSharedBankSize = 2; - const size_t InvTypeTradeSize = 8; - const size_t InvTypeWorldSize = 10; - const size_t InvTypeLimboSize = 36; - const size_t InvTypeTributeSize = 5; - const size_t InvTypeTrophyTributeSize = 0;//unknown - const size_t InvTypeGuildTributeSize = 2;//unverified - const size_t InvTypeMerchantSize = 200; - const size_t InvTypeDeletedSize = 0;//unknown - "Recovery Tab" - const size_t InvTypeCorpseSize = InvTypePossessionsSize; - const size_t InvTypeBazaarSize = 200; - const size_t InvTypeInspectSize = invslot::EquipmentCount; - const size_t InvTypeRealEstateSize = 0;//unknown - const size_t InvTypeViewMODPCSize = InvTypePossessionsSize; - const size_t InvTypeViewMODBankSize = InvTypeBankSize; - const size_t InvTypeViewMODSharedBankSize = InvTypeSharedBankSize; - const size_t InvTypeViewMODLimboSize = InvTypeLimboSize; - const size_t InvTypeAltStorageSize = 0;//unknown - "Shroud Bank" - const size_t InvTypeArchivedSize = 0;//unknown - const size_t InvTypeMailSize = 0;//unknown - const size_t InvTypeGuildTrophyTributeSize = 0;//unknown - const size_t InvTypeOtherSize = 0;//unknown - - extern size_t GetInvTypeSize(int inv_type); - extern const char* GetInvTypeName(int inv_type); - - extern bool IsInvTypePersistent(int inv_type); - - } /*invtype*/ - - namespace invslot { - extern const char* GetInvPossessionsSlotName(int inv_slot); - extern const char* GetInvSlotName(int inv_type, int inv_slot); - - } /*invslot*/ - - namespace invbag { - const size_t ItemBagSize = 255; // server Size will be 255..unsure what actual client is (test) - - extern const char* GetInvBagIndexName(int bag_index); - - } /*invbag*/ - - namespace invaug { - const size_t ItemAugSize = 6; - - extern const char* GetInvAugIndexName(int aug_index); - - } /*invaug*/ - - namespace item { - - } /*item*/ - - namespace profile { - const size_t TributeSize = invtype::InvTypeTributeSize; - const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize; - - const size_t BandoliersSize = 20; // number of bandolier instances - const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance - - const size_t PotionBeltSize = 5; - - const size_t SkillArraySize = 100; - - } /*profile*/ - - namespace constants { - const size_t CharacterCreationLimit = 12; - - const size_t SayLinkBodySize = 55; + const size_t SAY_LINK_BODY_SIZE = 55; const int LongBuffs = 42; const int ShortBuffs = 20; @@ -279,11 +265,15 @@ namespace RoF } /*constants*/ namespace behavior { + inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::RoF; } + const bool CoinHasWeight = false; } /*behavior*/ namespace skills { + inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF; } + const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack; } /*skills*/ diff --git a/common/patches/rof_ops.h b/common/patches/rof_ops.h index 9030a480b..11fd83f51 100644 --- a/common/patches/rof_ops.h +++ b/common/patches/rof_ops.h @@ -83,7 +83,6 @@ E(OP_MoveItem) E(OP_NewSpawn) E(OP_NewZone) E(OP_OnLevelMessage) -//E(OP_OpenNewTasksWindow) E(OP_PetBuffWindow) E(OP_PlayerProfile) E(OP_RaidJoin) diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index 08e3647be..dcc5e4ccc 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -898,13 +898,13 @@ struct BandolierItem_Struct_Old struct Bandolier_Struct { char Name[1]; // Variable Length - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; struct Bandolier_Struct_Old { char Name[32]; - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; struct PotionBeltItem_Struct @@ -924,12 +924,12 @@ struct PotionBeltItem_Struct_Old struct PotionBelt_Struct { - PotionBeltItem_Struct Items[profile::PotionBeltSize]; + PotionBeltItem_Struct Items[profile::POTION_BELT_SIZE]; }; struct PotionBelt_Struct_Old { - PotionBeltItem_Struct_Old Items[profile::PotionBeltSize]; + PotionBeltItem_Struct_Old Items[profile::POTION_BELT_SIZE]; }; struct GroupLeadershipAA_Struct { @@ -1139,7 +1139,7 @@ union /*12949*/ uint32 aapoints; // Unspent AA points - Seen 1 /*12953*/ uint16 unknown_rof20; // /*12955*/ uint32 bandolier_count; // Seen 20 -/*12959*/ Bandolier_Struct bandoliers[profile::BandoliersSize]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents +/*12959*/ Bandolier_Struct bandoliers[profile::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents /*13699*/ uint32 potionbelt_count; // Seen 5 /*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes) /*13748*/ int32 unknown_rof21; // Seen -1 diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 560151bfa..425341af7 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -1383,114 +1383,6 @@ namespace SoD FINISH_ENCODE(); } - ENCODE(OP_OpenNewTasksWindow) - { - AvailableTaskHeader_Struct* __emu_AvailableTaskHeader; - AvailableTaskData1_Struct* __emu_AvailableTaskData1; - AvailableTaskData2_Struct* __emu_AvailableTaskData2; - AvailableTaskTrailer_Struct* __emu_AvailableTaskTrailer; - - structs::AvailableTaskHeader_Struct* __eq_AvailableTaskHeader; - structs::AvailableTaskData1_Struct* __eq_AvailableTaskData1; - structs::AvailableTaskData2_Struct* __eq_AvailableTaskData2; - structs::AvailableTaskTrailer_Struct* __eq_AvailableTaskTrailer; - - EQApplicationPacket *in = *p; - *p = nullptr; - - unsigned char *__emu_buffer = in->pBuffer; - - __emu_AvailableTaskHeader = (AvailableTaskHeader_Struct*)__emu_buffer; - - // For each task, SoF has an extra uint32 and what appears to be space for a null terminated string. - // - in->size = in->size + (__emu_AvailableTaskHeader->TaskCount * 5); - in->pBuffer = new unsigned char[in->size]; - unsigned char *__eq_buffer = in->pBuffer; - __eq_AvailableTaskHeader = (structs::AvailableTaskHeader_Struct*)__eq_buffer; - char *__eq_ptr, *__emu_Ptr; - - // Copy Header - // - // - - __eq_AvailableTaskHeader->TaskCount = __emu_AvailableTaskHeader->TaskCount; - __eq_AvailableTaskHeader->unknown1 = __emu_AvailableTaskHeader->unknown1; - __eq_AvailableTaskHeader->TaskGiver = __emu_AvailableTaskHeader->TaskGiver; - - __emu_Ptr = (char *)__emu_AvailableTaskHeader + sizeof(AvailableTaskHeader_Struct); - __eq_ptr = (char *)__eq_AvailableTaskHeader + sizeof(structs::AvailableTaskHeader_Struct); - - for (uint32 i = 0; i<__emu_AvailableTaskHeader->TaskCount; i++) { - - __emu_AvailableTaskData1 = (AvailableTaskData1_Struct*)__emu_Ptr; - __eq_AvailableTaskData1 = (structs::AvailableTaskData1_Struct*)__eq_ptr; - - __eq_AvailableTaskData1->TaskID = __emu_AvailableTaskData1->TaskID; - // This next unknown seems to affect the colour of the task title. 0x3f80000 is what I have seen - // in Live packets. Changing it to 0x3f000000 makes the title red. - __eq_AvailableTaskData1->unknown1 = 0x3f800000; - __eq_AvailableTaskData1->TimeLimit = __emu_AvailableTaskData1->TimeLimit; - __eq_AvailableTaskData1->unknown2 = __emu_AvailableTaskData1->unknown2; - - __emu_Ptr += sizeof(AvailableTaskData1_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData1_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Title - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Description - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __eq_ptr[0] = 0; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskData2 = (AvailableTaskData2_Struct*)__emu_Ptr; - __eq_AvailableTaskData2 = (structs::AvailableTaskData2_Struct*)__eq_ptr; - - __eq_AvailableTaskData2->unknown1 = __emu_AvailableTaskData2->unknown1; - __eq_AvailableTaskData2->unknown2 = __emu_AvailableTaskData2->unknown2; - __eq_AvailableTaskData2->unknown3 = __emu_AvailableTaskData2->unknown3; - __eq_AvailableTaskData2->unknown4 = __emu_AvailableTaskData2->unknown4; - - __emu_Ptr += sizeof(AvailableTaskData2_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData2_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskTrailer = (AvailableTaskTrailer_Struct*)__emu_Ptr; - __eq_AvailableTaskTrailer = (structs::AvailableTaskTrailer_Struct*)__eq_ptr; - - __eq_AvailableTaskTrailer->ItemCount = __emu_AvailableTaskTrailer->ItemCount; - __eq_AvailableTaskTrailer->unknown1 = __emu_AvailableTaskTrailer->unknown1; - __eq_AvailableTaskTrailer->unknown2 = __emu_AvailableTaskTrailer->unknown2; - __eq_AvailableTaskTrailer->StartZone = __emu_AvailableTaskTrailer->StartZone; - - __emu_Ptr += sizeof(AvailableTaskTrailer_Struct); - __eq_ptr += sizeof(structs::AvailableTaskTrailer_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - } - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); - } - ENCODE(OP_PetBuffWindow) { EQApplicationPacket *in = *p; @@ -1632,18 +1524,18 @@ namespace SoD // OUT(unknown06160[4]); // Copy bandoliers where server and client indexes converge - for (r = 0; r < EQEmu::legacy::BANDOLIERS_SIZE && r < profile::BandoliersSize; ++r) { + for (r = 0; r < EQEmu::profile::BANDOLIERS_SIZE && r < profile::BANDOLIERS_SIZE; ++r) { OUT_str(bandoliers[r].Name); - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true OUT(bandoliers[r].Items[k].ID); OUT(bandoliers[r].Items[k].Icon); OUT_str(bandoliers[r].Items[k].Name); } } // Nullify bandoliers where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::BANDOLIERS_SIZE; r < profile::BandoliersSize; ++r) { + for (r = EQEmu::profile::BANDOLIERS_SIZE; r < profile::BANDOLIERS_SIZE; ++r) { eq->bandoliers[r].Name[0] = '\0'; - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true eq->bandoliers[r].Items[k].ID = 0; eq->bandoliers[r].Items[k].Icon = 0; eq->bandoliers[r].Items[k].Name[0] = '\0'; @@ -1653,13 +1545,13 @@ namespace SoD // OUT(unknown07444[5120]); // Copy potion belt where server and client indexes converge - for (r = 0; r < EQEmu::legacy::POTION_BELT_ITEM_COUNT && r < profile::PotionBeltSize; ++r) { + for (r = 0; r < EQEmu::profile::POTION_BELT_SIZE && r < profile::POTION_BELT_SIZE; ++r) { OUT(potionbelt.Items[r].ID); OUT(potionbelt.Items[r].Icon); OUT_str(potionbelt.Items[r].Name); } // Nullify potion belt where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::POTION_BELT_ITEM_COUNT; r < profile::PotionBeltSize; ++r) { + for (r = EQEmu::profile::POTION_BELT_SIZE; r < profile::POTION_BELT_SIZE; ++r) { eq->potionbelt.Items[r].ID = 0; eq->potionbelt.Items[r].Icon = 0; eq->potionbelt.Items[r].Name[0] = '\0'; @@ -1947,8 +1839,8 @@ namespace SoD eq->CharCount = emu->CharCount; eq->TotalChars = emu->TotalChars; - if (eq->TotalChars > constants::CharacterCreationLimit) - eq->TotalChars = constants::CharacterCreationLimit; + if (eq->TotalChars > constants::CHARACTER_CREATION_LIMIT) + eq->TotalChars = constants::CHARACTER_CREATION_LIMIT; FINISH_ENCODE(); return; @@ -1960,7 +1852,7 @@ namespace SoD size_t names_length = 0; size_t character_count = 0; - for (; character_count < emu->CharCount && character_count < constants::CharacterCreationLimit; ++character_count) { + for (; character_count < emu->CharCount && character_count < constants::CHARACTER_CREATION_LIMIT; ++character_count) { emu_cse = (CharacterSelectEntry_Struct *)emu_ptr; names_length += strlen(emu_cse->Name); emu_ptr += sizeof(CharacterSelectEntry_Struct); @@ -1976,8 +1868,8 @@ namespace SoD eq->CharCount = character_count; eq->TotalChars = emu->TotalChars; - if (eq->TotalChars > constants::CharacterCreationLimit) - eq->TotalChars = constants::CharacterCreationLimit; + if (eq->TotalChars > constants::CHARACTER_CREATION_LIMIT) + eq->TotalChars = constants::CHARACTER_CREATION_LIMIT; emu_ptr = __emu_buffer; emu_ptr += sizeof(CharacterSelect_Struct); @@ -2249,13 +2141,16 @@ namespace SoD InBuffer += description_size; InBuffer += sizeof(TaskDescriptionData2_Struct); - std::string old_message = InBuffer; // start 'Reward' as string + uint32 reward_size = strlen(InBuffer) + 1; + InBuffer += reward_size; + + std::string old_message = InBuffer; // start item link string std::string new_message; ServerToSoDSayLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ - title_size + description_size + new_message.length() + 1; + title_size + description_size + reward_size + new_message.length() + 1; in->pBuffer = new unsigned char[in->size]; @@ -3578,7 +3473,7 @@ namespace SoD ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; ibs.size = item->Size; - ibs.slots = SwapBits21and22(item->Slots); + ibs.slots = SwapBits21And22(item->Slots); ibs.price = item->Price; ibs.icon = item->Icon; ibs.unknown1 = 1; @@ -3668,7 +3563,7 @@ namespace SoD isbs.augtype = item->AugType; isbs.augrestrict = item->AugRestrict; - for (int index = 0; index < invaug::ItemAugSize; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { isbs.augslots[index].type = item->AugSlotType[index]; isbs.augslots[index].visible = item->AugSlotVisible[index]; isbs.augslots[index].unknown = item->AugSlotUnk2[index]; @@ -3841,18 +3736,18 @@ namespace SoD ob.write((const char*)&subitem_count, sizeof(uint32)); - for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) { + for (uint32 index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) { EQEmu::ItemInstance* sub = inst->GetItem(index); if (!sub) continue; int SubSlotNumber = INVALID_INDEX; - if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END) - SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1); - else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index); - else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index); + if (slot_id_in >= EQEmu::invslot::GENERAL_BEGIN && slot_id_in <= EQEmu::invslot::GENERAL_END) + SubSlotNumber = (((slot_id_in + 3) * EQEmu::invbag::SLOT_COUNT) + index + 1); + else if (slot_id_in >= EQEmu::invslot::BANK_BEGIN && slot_id_in <= EQEmu::invslot::BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::BANK_BAGS_BEGIN + index); + else if (slot_id_in >= EQEmu::invslot::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::invslot::SHARED_BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::SHARED_BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::SHARED_BANK_BAGS_BEGIN + index); else SubSlotNumber = slot_id_in; @@ -3870,16 +3765,16 @@ namespace SoD { uint32 SoDSlot = 0; - if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots + if (serverSlot >= EQEmu::invslot::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots SoDSlot = serverSlot + 1; - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) SoDSlot = serverSlot + 11; - else if (serverSlot >= EQEmu::legacy::BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::BANK_BAGS_END) + else if (serverSlot >= EQEmu::invbag::BANK_BAGS_BEGIN && serverSlot <= EQEmu::invbag::BANK_BAGS_END) SoDSlot = serverSlot + 1; - else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END) + else if (serverSlot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::invbag::SHARED_BANK_BAGS_END) SoDSlot = serverSlot + 1; - else if (serverSlot == EQEmu::inventory::slotPowerSource) - SoDSlot = invslot::PossessionsPowerSource; + else if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + SoDSlot = invslot::slotPowerSource; else SoDSlot = serverSlot; return SoDSlot; @@ -3895,16 +3790,16 @@ namespace SoD { uint32 ServerSlot = 0; - if (sodSlot >= invslot::PossessionsAmmo && sodSlot <= invslot::CorpseEnd) // Cursor/Ammo/Power Source and Normal Inventory Slots + if (sodSlot >= invslot::slotAmmo && sodSlot <= invslot::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots ServerSlot = sodSlot - 1; - else if (sodSlot >= invbag::GeneralBagsBegin && sodSlot <= invbag::CursorBagEnd) + else if (sodSlot >= invbag::GENERAL_BAGS_BEGIN && sodSlot <= invbag::CURSOR_BAG_END) ServerSlot = sodSlot - 11; - else if (sodSlot >= invbag::BankBagsBegin && sodSlot <= invbag::BankBagsEnd) + else if (sodSlot >= invbag::BANK_BAGS_BEGIN && sodSlot <= invbag::BANK_BAGS_END) ServerSlot = sodSlot - 1; - else if (sodSlot >= invbag::SharedBankBagsBegin && sodSlot <= invbag::SharedBankBagsEnd) + else if (sodSlot >= invbag::SHARED_BANK_BAGS_BEGIN && sodSlot <= invbag::SHARED_BANK_BAGS_END) ServerSlot = sodSlot - 1; - else if (sodSlot == invslot::PossessionsPowerSource) - ServerSlot = EQEmu::inventory::slotPowerSource; + else if (sodSlot == invslot::slotPowerSource) + ServerSlot = EQEmu::invslot::SLOT_POWER_SOURCE; else ServerSlot = sodSlot; return ServerSlot; @@ -3918,7 +3813,7 @@ namespace SoD static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink) { - if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) { + if ((constants::SAY_LINK_BODY_SIZE == EQEmu::constants::SAY_LINK_BODY_SIZE) || (serverSayLink.find('\x12') == std::string::npos)) { sodSayLink = serverSayLink; return; } @@ -3927,7 +3822,7 @@ namespace SoD for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= EQEmu::constants::SAY_LINK_BODY_SIZE) { sodSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; @@ -3958,7 +3853,7 @@ namespace SoD static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink) { - if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sodSayLink.find('\x12') == std::string::npos)) { + if ((EQEmu::constants::SAY_LINK_BODY_SIZE == constants::SAY_LINK_BODY_SIZE) || (sodSayLink.find('\x12') == std::string::npos)) { serverSayLink = sodSayLink; return; } @@ -3967,7 +3862,7 @@ namespace SoD for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= constants::SAY_LINK_BODY_SIZE) { serverSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; diff --git a/common/patches/sod_limits.cpp b/common/patches/sod_limits.cpp index 8ff257665..dc1676d5a 100644 --- a/common/patches/sod_limits.cpp +++ b/common/patches/sod_limits.cpp @@ -22,198 +22,198 @@ #include "../string_util.h" -size_t SoD::invtype::GetInvTypeSize(int inv_type) +int16 SoD::invtype::GetInvTypeSize(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - return invtype::InvTypePossessionsSize; - case invtype::InvTypeBank: - return invtype::InvTypeBankSize; - case invtype::InvTypeSharedBank: - return invtype::InvTypeSharedBankSize; - case invtype::InvTypeTrade: - return invtype::InvTypeTradeSize; - case invtype::InvTypeWorld: - return invtype::InvTypeWorldSize; - case invtype::InvTypeLimbo: - return invtype::InvTypeLimboSize; - case invtype::InvTypeTribute: - return invtype::InvTypeTributeSize; - case invtype::InvTypeGuildTribute: - return invtype::InvTypeGuildTributeSize; - case invtype::InvTypeMerchant: - return invtype::InvTypeMerchantSize; - case invtype::InvTypeCorpse: - return invtype::InvTypeCorpseSize; - case invtype::InvTypeBazaar: - return invtype::InvTypeBazaarSize; - case invtype::InvTypeInspect: - return invtype::InvTypeInspectSize; - case invtype::InvTypeViewMODPC: - return invtype::InvTypeViewMODPCSize; - case invtype::InvTypeViewMODBank: - return invtype::InvTypeViewMODBankSize; - case invtype::InvTypeViewMODSharedBank: - return invtype::InvTypeViewMODSharedBankSize; - case invtype::InvTypeViewMODLimbo: - return invtype::InvTypeViewMODLimboSize; - case invtype::InvTypeAltStorage: - return invtype::InvTypeAltStorageSize; - case invtype::InvTypeArchived: - return invtype::InvTypeArchivedSize; - case invtype::InvTypeOther: - return invtype::InvTypeOtherSize; + case invtype::typePossessions: + return invtype::POSSESSIONS_SIZE; + case invtype::typeBank: + return invtype::BANK_SIZE; + case invtype::typeSharedBank: + return invtype::SHARED_BANK_SIZE; + case invtype::typeTrade: + return invtype::TRADE_SIZE; + case invtype::typeWorld: + return invtype::WORLD_SIZE; + case invtype::typeLimbo: + return invtype::LIMBO_SIZE; + case invtype::typeTribute: + return invtype::TRIBUTE_SIZE; + case invtype::typeGuildTribute: + return invtype::GUILD_TRIBUTE_SIZE; + case invtype::typeMerchant: + return invtype::MERCHANT_SIZE; + case invtype::typeCorpse: + return invtype::CORPSE_SIZE; + case invtype::typeBazaar: + return invtype::BAZAAR_SIZE; + case invtype::typeInspect: + return invtype::INSPECT_SIZE; + case invtype::typeViewMODPC: + return invtype::VIEW_MOD_PC_SIZE; + case invtype::typeViewMODBank: + return invtype::VIEW_MOD_BANK_SIZE; + case invtype::typeViewMODSharedBank: + return invtype::VIEW_MOD_SHARED_BANK_SIZE; + case invtype::typeViewMODLimbo: + return invtype::VIEW_MOD_LIMBO_SIZE; + case invtype::typeAltStorage: + return invtype::ALT_STORAGE_SIZE; + case invtype::typeArchived: + return invtype::ARCHIVED_SIZE; + case invtype::typeOther: + return invtype::OTHER_SIZE; default: - return 0; + return INULL; } } -const char* SoD::invtype::GetInvTypeName(int inv_type) +const char* SoD::invtype::GetInvTypeName(int16 inv_type) { switch (inv_type) { - case invtype::InvTypeInvalid: + case invtype::TYPE_INVALID: return "Invalid Type"; - case invtype::InvTypePossessions: + case invtype::typePossessions: return "Possessions"; - case invtype::InvTypeBank: + case invtype::typeBank: return "Bank"; - case invtype::InvTypeSharedBank: + case invtype::typeSharedBank: return "Shared Bank"; - case invtype::InvTypeTrade: + case invtype::typeTrade: return "Trade"; - case invtype::InvTypeWorld: + case invtype::typeWorld: return "World"; - case invtype::InvTypeLimbo: + case invtype::typeLimbo: return "Limbo"; - case invtype::InvTypeTribute: + case invtype::typeTribute: return "Tribute"; - case invtype::InvTypeGuildTribute: + case invtype::typeGuildTribute: return "Guild Tribute"; - case invtype::InvTypeMerchant: + case invtype::typeMerchant: return "Merchant"; - case invtype::InvTypeCorpse: + case invtype::typeCorpse: return "Corpse"; - case invtype::InvTypeBazaar: + case invtype::typeBazaar: return "Bazaar"; - case invtype::InvTypeInspect: + case invtype::typeInspect: return "Inspect"; - case invtype::InvTypeViewMODPC: + case invtype::typeViewMODPC: return "View MOD PC"; - case invtype::InvTypeViewMODBank: + case invtype::typeViewMODBank: return "View MOD Bank"; - case invtype::InvTypeViewMODSharedBank: + case invtype::typeViewMODSharedBank: return "View MOD Shared Bank"; - case invtype::InvTypeViewMODLimbo: + case invtype::typeViewMODLimbo: return "View MOD Limbo"; - case invtype::InvTypeAltStorage: + case invtype::typeAltStorage: return "Alt Storage"; - case invtype::InvTypeArchived: + case invtype::typeArchived: return "Archived"; - case invtype::InvTypeOther: + case invtype::typeOther: return "Other"; default: return "Unknown Type"; } } -bool SoD::invtype::IsInvTypePersistent(int inv_type) +bool SoD::invtype::IsInvTypePersistent(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - case invtype::InvTypeBank: - case invtype::InvTypeSharedBank: - case invtype::InvTypeTrade: - case invtype::InvTypeWorld: - case invtype::InvTypeLimbo: - case invtype::InvTypeTribute: - case invtype::InvTypeGuildTribute: + case invtype::typePossessions: + case invtype::typeBank: + case invtype::typeSharedBank: + case invtype::typeTrade: + case invtype::typeWorld: + case invtype::typeLimbo: + case invtype::typeTribute: + case invtype::typeGuildTribute: return true; default: return false; } } -const char* SoD::invslot::GetInvPossessionsSlotName(int inv_slot) +const char* SoD::invslot::GetInvPossessionsSlotName(int16 inv_slot) { switch (inv_slot) { - case invslot::InvSlotInvalid: + case invslot::SLOT_INVALID: return "Invalid Slot"; - case invslot::PossessionsCharm: + case invslot::slotCharm: return "Charm"; - case invslot::PossessionsEar1: + case invslot::slotEar1: return "Ear 1"; - case invslot::PossessionsHead: + case invslot::slotHead: return "Head"; - case invslot::PossessionsFace: + case invslot::slotFace: return "Face"; - case invslot::PossessionsEar2: + case invslot::slotEar2: return "Ear 2"; - case invslot::PossessionsNeck: + case invslot::slotNeck: return "Neck"; - case invslot::PossessionsShoulders: + case invslot::slotShoulders: return "Shoulders"; - case invslot::PossessionsArms: + case invslot::slotArms: return "Arms"; - case invslot::PossessionsBack: + case invslot::slotBack: return "Back"; - case invslot::PossessionsWrist1: + case invslot::slotWrist1: return "Wrist 1"; - case invslot::PossessionsWrist2: + case invslot::slotWrist2: return "Wrist 2"; - case invslot::PossessionsRange: + case invslot::slotRange: return "Range"; - case invslot::PossessionsHands: + case invslot::slotHands: return "Hands"; - case invslot::PossessionsPrimary: + case invslot::slotPrimary: return "Primary"; - case invslot::PossessionsSecondary: + case invslot::slotSecondary: return "Secondary"; - case invslot::PossessionsFinger1: + case invslot::slotFinger1: return "Finger 1"; - case invslot::PossessionsFinger2: + case invslot::slotFinger2: return "Finger 2"; - case invslot::PossessionsChest: + case invslot::slotChest: return "Chest"; - case invslot::PossessionsLegs: + case invslot::slotLegs: return "Legs"; - case invslot::PossessionsFeet: + case invslot::slotFeet: return "Feet"; - case invslot::PossessionsWaist: + case invslot::slotWaist: return "Waist"; - case invslot::PossessionsPowerSource: + case invslot::slotPowerSource: return "Power Source"; - case invslot::PossessionsAmmo: + case invslot::slotAmmo: return "Ammo"; - case invslot::PossessionsGeneral1: + case invslot::slotGeneral1: return "General 1"; - case invslot::PossessionsGeneral2: + case invslot::slotGeneral2: return "General 2"; - case invslot::PossessionsGeneral3: + case invslot::slotGeneral3: return "General 3"; - case invslot::PossessionsGeneral4: + case invslot::slotGeneral4: return "General 4"; - case invslot::PossessionsGeneral5: + case invslot::slotGeneral5: return "General 5"; - case invslot::PossessionsGeneral6: + case invslot::slotGeneral6: return "General 6"; - case invslot::PossessionsGeneral7: + case invslot::slotGeneral7: return "General 7"; - case invslot::PossessionsGeneral8: + case invslot::slotGeneral8: return "General 8"; - case invslot::PossessionsCursor: + case invslot::slotCursor: return "Cursor"; default: return "Unknown Slot"; } } -const char* SoD::invslot::GetInvCorpseSlotName(int inv_slot) +const char* SoD::invslot::GetInvCorpseSlotName(int16 inv_slot) { - if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid) + if (!invtype::GetInvTypeSize(invtype::typeCorpse) || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; // needs work - if ((size_t)(inv_slot + 1) < invslot::CorpseBegin || (size_t)(inv_slot + 1) >= invslot::CorpseEnd) + if ((inv_slot + 1) < invslot::CORPSE_BEGIN || (inv_slot + 1) >= invslot::CORPSE_END) return "Unknown Slot"; static std::string ret_str; @@ -222,19 +222,19 @@ const char* SoD::invslot::GetInvCorpseSlotName(int inv_slot) return ret_str.c_str(); } -const char* SoD::invslot::GetInvSlotName(int inv_type, int inv_slot) +const char* SoD::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot) { - if (inv_type == invtype::InvTypePossessions) + if (inv_type == invtype::typePossessions) return invslot::GetInvPossessionsSlotName(inv_slot); - else if (inv_type == invtype::InvTypeCorpse) + else if (inv_type == invtype::typeCorpse) return invslot::GetInvCorpseSlotName(inv_slot); - size_t type_size = invtype::GetInvTypeSize(inv_type); + int16 type_size = invtype::GetInvTypeSize(inv_type); - if (!type_size || inv_slot == invslot::InvSlotInvalid) + if (!type_size || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; - if ((size_t)(inv_slot + 1) >= type_size) + if ((inv_slot + 1) >= type_size) return "Unknown Slot"; static std::string ret_str; @@ -243,12 +243,12 @@ const char* SoD::invslot::GetInvSlotName(int inv_type, int inv_slot) return ret_str.c_str(); } -const char* SoD::invbag::GetInvBagIndexName(int bag_index) +const char* SoD::invbag::GetInvBagIndexName(int16 bag_index) { - if (bag_index == invbag::InvBagInvalid) + if (bag_index == invbag::SLOT_INVALID) return "Invalid Bag"; - if ((size_t)bag_index >= invbag::ItemBagSize) + if (bag_index >= invbag::SLOT_COUNT) return "Unknown Bag"; static std::string ret_str; @@ -257,12 +257,12 @@ const char* SoD::invbag::GetInvBagIndexName(int bag_index) return ret_str.c_str(); } -const char* SoD::invaug::GetInvAugIndexName(int aug_index) +const char* SoD::invaug::GetInvAugIndexName(int16 aug_index) { - if (aug_index == invaug::InvAugInvalid) + if (aug_index == invaug::SOCKET_INVALID) return "Invalid Augment"; - if ((size_t)aug_index >= invaug::ItemAugSize) + if (aug_index >= invaug::SOCKET_COUNT) return "Unknown Augment"; static std::string ret_str; diff --git a/common/patches/sod_limits.h b/common/patches/sod_limits.h index 8f8031a3d..555425cc1 100644 --- a/common/patches/sod_limits.h +++ b/common/patches/sod_limits.h @@ -27,108 +27,218 @@ namespace SoD { - enum : int { Invalid = -1, Null, Safety }; + const int16 IINVALID = -1; + const int16 INULL = 0; - enum : bool { False = false, True = true }; - - // pre-declarations namespace inventory { inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::SoD; } + const bool ConcatenateInvTypeLimbo = true; + + const bool AllowOverLevelEquipment = false; + + const bool AllowEmptyBagInBag = false; + const bool AllowClickCastFromBag = false; + } /*inventory*/ namespace invtype { inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::SoD; } - enum : int { InvTypeInvalid = -1, InvTypeBegin }; + namespace enum_ { + enum InventoryTypes : int16 { + typePossessions = INULL, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, + typeTribute, + typeGuildTribute, + typeMerchant, + typeCorpse, + typeBazaar, + typeInspect, + typeViewMODPC, + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, + typeOther + }; - enum InventoryType : int { - InvTypePossessions = InvTypeBegin, - InvTypeBank, - InvTypeSharedBank, - InvTypeTrade, - InvTypeWorld, - InvTypeLimbo, - InvTypeTribute, - InvTypeGuildTribute, - InvTypeMerchant, - InvTypeCorpse, - InvTypeBazaar, - InvTypeInspect, - InvTypeViewMODPC, - InvTypeViewMODBank, - InvTypeViewMODSharedBank, - InvTypeViewMODLimbo, - InvTypeAltStorage, - InvTypeArchived, - InvTypeOther, - InvTypeCount - }; + } // namespace enum_ + using namespace enum_; + + const int16 POSSESSIONS_SIZE = 32; + const int16 BANK_SIZE = 24; + const int16 SHARED_BANK_SIZE = 2; + const int16 TRADE_SIZE = 8; + const int16 WORLD_SIZE = 10; + const int16 LIMBO_SIZE = 36; + const int16 TRIBUTE_SIZE = 5; + const int16 GUILD_TRIBUTE_SIZE = 2; + const int16 MERCHANT_SIZE = 80; + const int16 CORPSE_SIZE = POSSESSIONS_SIZE; + const int16 BAZAAR_SIZE = 80; + const int16 INSPECT_SIZE = 23; + const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE; + const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE; + const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE; + const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE; + const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank" + const int16 ARCHIVED_SIZE = 0;//unknown + const int16 OTHER_SIZE = 0;//unknown + + const int16 TRADE_NPC_SIZE = 4; // defined by implication + + const int16 TYPE_INVALID = IINVALID; + const int16 TYPE_BEGIN = typePossessions; + const int16 TYPE_END = typeOther; + const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1; + + int16 GetInvTypeSize(int16 inv_type); + const char* GetInvTypeName(int16 inv_type); + + bool IsInvTypePersistent(int16 inv_type); } /*invtype*/ namespace invslot { inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::SoD; } - enum : int { InvSlotInvalid = -1, InvSlotBegin }; + namespace enum_ { + enum InventorySlots : int16 { + slotCharm = INULL, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, + slotPowerSource, + slotAmmo, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotCursor + }; - enum PossessionsSlot : int { - PossessionsCharm = InvSlotBegin, - PossessionsEar1, - PossessionsHead, - PossessionsFace, - PossessionsEar2, - PossessionsNeck, - PossessionsShoulders, - PossessionsArms, - PossessionsBack, - PossessionsWrist1, - PossessionsWrist2, - PossessionsRange, - PossessionsHands, - PossessionsPrimary, - PossessionsSecondary, - PossessionsFinger1, - PossessionsFinger2, - PossessionsChest, - PossessionsLegs, - PossessionsFeet, - PossessionsWaist, - PossessionsPowerSource, - PossessionsAmmo, - PossessionsGeneral1, - PossessionsGeneral2, - PossessionsGeneral3, - PossessionsGeneral4, - PossessionsGeneral5, - PossessionsGeneral6, - PossessionsGeneral7, - PossessionsGeneral8, - PossessionsCursor, - PossessionsCount - }; + } // namespace enum_ + using namespace enum_; - const int EquipmentBegin = PossessionsCharm; - const int EquipmentEnd = PossessionsAmmo; - const int EquipmentCount = (EquipmentEnd - EquipmentBegin + 1); + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; - const int GeneralBegin = PossessionsGeneral1; - const int GeneralEnd = PossessionsGeneral8; - const int GeneralCount = (GeneralEnd - GeneralBegin + 1); + const int16 POSSESSIONS_BEGIN = slotCharm; + const int16 POSSESSIONS_END = slotCursor; + const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; + + const int16 EQUIPMENT_BEGIN = slotCharm; + const int16 EQUIPMENT_END = slotAmmo; + const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN + 1); + + const int16 GENERAL_BEGIN = slotGeneral1; + const int16 GENERAL_END = slotGeneral8; + const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN + 1); + + const int16 BONUS_BEGIN = invslot::slotCharm; + const int16 BONUS_STAT_END = invslot::slotPowerSource; + const int16 BONUS_SKILL_END = invslot::slotAmmo; + + const int16 BANK_BEGIN = 2000; + const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1; + + const int16 SHARED_BANK_BEGIN = 2500; + const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1; + + const int16 TRADE_BEGIN = 3000; + const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1; + + const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication + + const int16 WORLD_BEGIN = 4000; + const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1; + + const int16 TRIBUTE_BEGIN = 400; + const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1; + + const int16 GUILD_TRIBUTE_BEGIN = 450; + const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor; + + const uint64 POSSESSIONS_BITMASK = 0x000000027FFFFFFF; // based on 34-slot count (RoF+) + const uint64 CORPSE_BITMASK = 0x01FFFFFE7F800000; // based on 34-slot count (RoF+) + + const char* GetInvPossessionsSlotName(int16 inv_slot); + const char* GetInvCorpseSlotName(int16 inv_slot); + const char* GetInvSlotName(int16 inv_type, int16 inv_slot); } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::SoD; } - enum : int { InvBagInvalid = -1, InvBagBegin }; + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; + const int16 SLOT_END = 9; + const int16 SLOT_COUNT = 10; + + const int16 GENERAL_BAGS_BEGIN = 262; + const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT; + const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1; + + const int16 CURSOR_BAG_BEGIN = 342; + const int16 CURSOR_BAG_COUNT = SLOT_COUNT; + const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1; + + const int16 BANK_BAGS_BEGIN = 2032; + const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT); + const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1; + + const int16 SHARED_BANK_BAGS_BEGIN = 2532; + const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT; + const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1; + + const int16 TRADE_BAGS_BEGIN = 3031; + const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT; + const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1; + + const char* GetInvBagIndexName(int16 bag_index); } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::SoD; } - enum : int { InvAugInvalid = -1, InvAugBegin }; + const int16 SOCKET_INVALID = IINVALID; + const int16 SOCKET_BEGIN = INULL; + const int16 SOCKET_END = 4; + const int16 SOCKET_COUNT = 5; + + const char* GetInvAugIndexName(int16 aug_index); } /*invaug*/ @@ -153,147 +263,21 @@ namespace SoD namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::SoD; } + const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances + const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance + + const int16 POTION_BELT_SIZE = 5; + + const int16 SKILL_ARRAY_SIZE = 100; + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::SoD; } - } /*constants*/ + const size_t CHARACTER_CREATION_LIMIT = 12; - namespace behavior { - inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::SoD; } - - } /*behavior*/ - - namespace skills { - inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoD; } - - } /*skills*/ - - - // declarations - namespace inventory { - const bool ConcatenateInvTypeLimbo = true; - - const bool AllowOverLevelEquipment = false; - - const bool AllowEmptyBagInBag = false; - const bool AllowClickCastFromBag = false; - - } /*inventory*/ - - namespace invtype { - const size_t InvTypePossessionsSize = invslot::PossessionsCount; - const size_t InvTypeBankSize = 24; - const size_t InvTypeSharedBankSize = 2; - const size_t InvTypeTradeSize = 8; - const size_t InvTypeWorldSize = 10; - const size_t InvTypeLimboSize = 36; - const size_t InvTypeTributeSize = 5; - const size_t InvTypeGuildTributeSize = 2; - const size_t InvTypeMerchantSize = 80; - const size_t InvTypeCorpseSize = InvTypePossessionsSize; - const size_t InvTypeBazaarSize = 80; - const size_t InvTypeInspectSize = invslot::EquipmentCount; - const size_t InvTypeViewMODPCSize = InvTypePossessionsSize; - const size_t InvTypeViewMODBankSize = InvTypeBankSize; - const size_t InvTypeViewMODSharedBankSize = InvTypeSharedBankSize; - const size_t InvTypeViewMODLimboSize = InvTypeLimboSize; - const size_t InvTypeAltStorageSize = 0;//unknown - "Shroud Bank" - const size_t InvTypeArchivedSize = 0;//unknown - const size_t InvTypeOtherSize = 0;//unknown - - extern size_t GetInvTypeSize(int inv_type); - extern const char* GetInvTypeName(int inv_type); - - extern bool IsInvTypePersistent(int inv_type); - - } /*invtype*/ - - namespace invslot { - const int BankBegin = 2000; - const int BankEnd = (BankBegin + invtype::InvTypeBankSize) - 1; - - const int SharedBankBegin = 2500; - const int SharedBankEnd = (SharedBankBegin + invtype::InvTypeSharedBankSize) - 1; - - const int TradeBegin = 3000; - const int TradeEnd = (TradeBegin + invtype::InvTypeTradeSize) - 1; - const int TradeNPCEnd = 3003; - - const int WorldBegin = 4000; - const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1; - - const int TributeBegin = 400; - const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1; - - const int GuildTributeBegin = 450; - const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1; - - const int CorpseBegin = invslot::PossessionsGeneral1; - const int CorpseEnd = invslot::PossessionsGeneral1 + invslot::PossessionsCursor; - - extern const char* GetInvPossessionsSlotName(int inv_slot); - extern const char* GetInvCorpseSlotName(int inv_slot); - extern const char* GetInvSlotName(int inv_type, int inv_slot); - - } /*invslot*/ - - namespace invbag { - const size_t ItemBagSize = 10; - - const int GeneralBagsBegin = 262; - const int GeneralBagsSize = invslot::GeneralCount * ItemBagSize; - const int GeneralBagsEnd = (GeneralBagsBegin + GeneralBagsSize) - 1; - - const int CursorBagBegin = 342; - const int CursorBagSize = ItemBagSize; - const int CursorBagEnd = (CursorBagBegin + CursorBagSize) - 1; - - const int BankBagsBegin = 2032; - const int BankBagsSize = (invtype::InvTypeBankSize * ItemBagSize); - const int BankBagsEnd = (BankBagsBegin + BankBagsSize) - 1; - - const int SharedBankBagsBegin = 2532; - const int SharedBankBagsSize = invtype::InvTypeSharedBankSize * ItemBagSize; - const int SharedBankBagsEnd = (SharedBankBagsBegin + SharedBankBagsSize) - 1; - - const int TradeBagsBegin = 3031; - const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize; - const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1; - - extern const char* GetInvBagIndexName(int bag_index); - - } /*invbag*/ - - namespace invaug { - const size_t ItemAugSize = 5; - - extern const char* GetInvAugIndexName(int aug_index); - - } /*invaug*/ - - namespace item { - - } /*item*/ - - namespace profile { - const size_t TributeSize = invtype::InvTypeTributeSize; - const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize; - - const size_t BandoliersSize = 20; // number of bandolier instances - const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance - - const size_t PotionBeltSize = 5; - - const size_t SkillArraySize = 100; - - } /*profile*/ - - namespace constants { - const size_t CharacterCreationLimit = 12; - - const size_t SayLinkBodySize = 50; + const size_t SAY_LINK_BODY_SIZE = 50; const int LongBuffs = 25; const int ShortBuffs = 15; @@ -306,11 +290,15 @@ namespace SoD } /*constants*/ namespace behavior { + inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::SoD; } + const bool CoinHasWeight = false; } /*behavior*/ namespace skills { + inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoD; } + const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack; } /*skills*/ diff --git a/common/patches/sod_ops.h b/common/patches/sod_ops.h index 7c1109499..6909e1f28 100644 --- a/common/patches/sod_ops.h +++ b/common/patches/sod_ops.h @@ -67,7 +67,6 @@ E(OP_MoveItem) E(OP_NewSpawn) E(OP_NewZone) E(OP_OnLevelMessage) -E(OP_OpenNewTasksWindow) E(OP_PetBuffWindow) E(OP_PlayerProfile) E(OP_RaidJoin) diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index 6b5c2f72c..80d0faae9 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -716,7 +716,7 @@ struct BandolierItem_Struct struct Bandolier_Struct { char Name[32]; - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; //len = 72 @@ -730,7 +730,7 @@ struct PotionBeltItem_Struct //len = 288 struct PotionBelt_Struct { - PotionBeltItem_Struct Items[profile::PotionBeltSize]; + PotionBeltItem_Struct Items[profile::POTION_BELT_SIZE]; }; static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16; @@ -937,7 +937,7 @@ struct PlayerProfile_Struct /*08288*/ uint32 aapoints_spent; // Number of spent AA points /*08292*/ uint32 aapoints; // Unspent AA points /*08296*/ uint8 unknown06160[4]; -/*08300*/ Bandolier_Struct bandoliers[profile::BandoliersSize]; // [6400] bandolier contents +/*08300*/ Bandolier_Struct bandoliers[profile::BANDOLIERS_SIZE]; // [6400] bandolier contents /*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot /*15060*/ uint8 unknown12852[8]; /*15068*/ uint32 available_slots; diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index c16bed086..7051a5eeb 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -1060,118 +1060,6 @@ namespace SoF FINISH_ENCODE(); } - ENCODE(OP_OpenNewTasksWindow) - { - AvailableTaskHeader_Struct* __emu_AvailableTaskHeader; - AvailableTaskData1_Struct* __emu_AvailableTaskData1; - AvailableTaskData2_Struct* __emu_AvailableTaskData2; - AvailableTaskTrailer_Struct* __emu_AvailableTaskTrailer; - - structs::AvailableTaskHeader_Struct* __eq_AvailableTaskHeader; - structs::AvailableTaskData1_Struct* __eq_AvailableTaskData1; - structs::AvailableTaskData2_Struct* __eq_AvailableTaskData2; - structs::AvailableTaskTrailer_Struct* __eq_AvailableTaskTrailer; - - EQApplicationPacket *in = *p; - *p = nullptr; - - unsigned char *__emu_buffer = in->pBuffer; - - __emu_AvailableTaskHeader = (AvailableTaskHeader_Struct*)__emu_buffer; - - // For each task, SoF has an extra uint32 and what appears to be space for a null terminated string. - // - in->size = in->size + (__emu_AvailableTaskHeader->TaskCount * 5); - - in->pBuffer = new unsigned char[in->size]; - - unsigned char *__eq_buffer = in->pBuffer; - - __eq_AvailableTaskHeader = (structs::AvailableTaskHeader_Struct*)__eq_buffer; - - char *__eq_ptr, *__emu_Ptr; - - // Copy Header - // - // - - __eq_AvailableTaskHeader->TaskCount = __emu_AvailableTaskHeader->TaskCount; - __eq_AvailableTaskHeader->unknown1 = __emu_AvailableTaskHeader->unknown1; - __eq_AvailableTaskHeader->TaskGiver = __emu_AvailableTaskHeader->TaskGiver; - - __emu_Ptr = (char *)__emu_AvailableTaskHeader + sizeof(AvailableTaskHeader_Struct); - __eq_ptr = (char *)__eq_AvailableTaskHeader + sizeof(structs::AvailableTaskHeader_Struct); - - for (uint32 i = 0; i<__emu_AvailableTaskHeader->TaskCount; i++) { - - __emu_AvailableTaskData1 = (AvailableTaskData1_Struct*)__emu_Ptr; - __eq_AvailableTaskData1 = (structs::AvailableTaskData1_Struct*)__eq_ptr; - - __eq_AvailableTaskData1->TaskID = __emu_AvailableTaskData1->TaskID; - // This next unknown seems to affect the colour of the task title. 0x3f80000 is what I have seen - // in Live packets. Changing it to 0x3f000000 makes the title red. - __eq_AvailableTaskData1->unknown1 = 0x3f800000; - __eq_AvailableTaskData1->TimeLimit = __emu_AvailableTaskData1->TimeLimit; - __eq_AvailableTaskData1->unknown2 = __emu_AvailableTaskData1->unknown2; - - __emu_Ptr += sizeof(AvailableTaskData1_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData1_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Title - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Description - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __eq_ptr[0] = 0; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskData2 = (AvailableTaskData2_Struct*)__emu_Ptr; - __eq_AvailableTaskData2 = (structs::AvailableTaskData2_Struct*)__eq_ptr; - - __eq_AvailableTaskData2->unknown1 = __emu_AvailableTaskData2->unknown1; - __eq_AvailableTaskData2->unknown2 = __emu_AvailableTaskData2->unknown2; - __eq_AvailableTaskData2->unknown3 = __emu_AvailableTaskData2->unknown3; - __eq_AvailableTaskData2->unknown4 = __emu_AvailableTaskData2->unknown4; - - __emu_Ptr += sizeof(AvailableTaskData2_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData2_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskTrailer = (AvailableTaskTrailer_Struct*)__emu_Ptr; - __eq_AvailableTaskTrailer = (structs::AvailableTaskTrailer_Struct*)__eq_ptr; - - __eq_AvailableTaskTrailer->ItemCount = __emu_AvailableTaskTrailer->ItemCount; - __eq_AvailableTaskTrailer->unknown1 = __emu_AvailableTaskTrailer->unknown1; - __eq_AvailableTaskTrailer->unknown2 = __emu_AvailableTaskTrailer->unknown2; - __eq_AvailableTaskTrailer->StartZone = __emu_AvailableTaskTrailer->StartZone; - - __emu_Ptr += sizeof(AvailableTaskTrailer_Struct); - __eq_ptr += sizeof(structs::AvailableTaskTrailer_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - } - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); - } - ENCODE(OP_PetBuffWindow) { ENCODE_LENGTH_EXACT(PetBuff_Struct); @@ -1303,18 +1191,18 @@ namespace SoF // OUT(unknown06160[4]); // Copy bandoliers where server and client indexes converge - for (r = 0; r < EQEmu::legacy::BANDOLIERS_SIZE && r < profile::BandoliersSize; ++r) { + for (r = 0; r < EQEmu::profile::BANDOLIERS_SIZE && r < profile::BANDOLIERS_SIZE; ++r) { OUT_str(bandoliers[r].Name); - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true OUT(bandoliers[r].Items[k].ID); OUT(bandoliers[r].Items[k].Icon); OUT_str(bandoliers[r].Items[k].Name); } } // Nullify bandoliers where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::BANDOLIERS_SIZE; r < profile::BandoliersSize; ++r) { + for (r = EQEmu::profile::BANDOLIERS_SIZE; r < profile::BANDOLIERS_SIZE; ++r) { eq->bandoliers[r].Name[0] = '\0'; - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true eq->bandoliers[r].Items[k].ID = 0; eq->bandoliers[r].Items[k].Icon = 0; eq->bandoliers[r].Items[k].Name[0] = '\0'; @@ -1324,13 +1212,13 @@ namespace SoF // OUT(unknown07444[5120]); // Copy potion belt where server and client indexes converge - for (r = 0; r < EQEmu::legacy::POTION_BELT_ITEM_COUNT && r < profile::PotionBeltSize; ++r) { + for (r = 0; r < EQEmu::profile::POTION_BELT_SIZE && r < profile::POTION_BELT_SIZE; ++r) { OUT(potionbelt.Items[r].ID); OUT(potionbelt.Items[r].Icon); OUT_str(potionbelt.Items[r].Name); } // Nullify potion belt where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::POTION_BELT_ITEM_COUNT; r < profile::PotionBeltSize; ++r) { + for (r = EQEmu::profile::POTION_BELT_SIZE; r < profile::POTION_BELT_SIZE; ++r) { eq->potionbelt.Items[r].ID = 0; eq->potionbelt.Items[r].Icon = 0; eq->potionbelt.Items[r].Name[0] = '\0'; @@ -1618,8 +1506,8 @@ namespace SoF eq->CharCount = emu->CharCount; eq->TotalChars = emu->TotalChars; - if (eq->TotalChars > constants::CharacterCreationLimit) - eq->TotalChars = constants::CharacterCreationLimit; + if (eq->TotalChars > constants::CHARACTER_CREATION_LIMIT) + eq->TotalChars = constants::CHARACTER_CREATION_LIMIT; FINISH_ENCODE(); return; @@ -1631,7 +1519,7 @@ namespace SoF size_t names_length = 0; size_t character_count = 0; - for (; character_count < emu->CharCount && character_count < constants::CharacterCreationLimit; ++character_count) { + for (; character_count < emu->CharCount && character_count < constants::CHARACTER_CREATION_LIMIT; ++character_count) { emu_cse = (CharacterSelectEntry_Struct *)emu_ptr; names_length += strlen(emu_cse->Name); emu_ptr += sizeof(CharacterSelectEntry_Struct); @@ -1647,8 +1535,8 @@ namespace SoF eq->CharCount = character_count; eq->TotalChars = emu->TotalChars; - if (eq->TotalChars > constants::CharacterCreationLimit) - eq->TotalChars = constants::CharacterCreationLimit; + if (eq->TotalChars > constants::CHARACTER_CREATION_LIMIT) + eq->TotalChars = constants::CHARACTER_CREATION_LIMIT; emu_ptr = __emu_buffer; emu_ptr += sizeof(CharacterSelect_Struct); @@ -1879,13 +1767,16 @@ namespace SoF InBuffer += description_size; InBuffer += sizeof(TaskDescriptionData2_Struct); - std::string old_message = InBuffer; // start 'Reward' as string + uint32 reward_size = strlen(InBuffer) + 1; + InBuffer += reward_size; + + std::string old_message = InBuffer; // start item link string std::string new_message; ServerToSoFSayLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ - title_size + description_size + new_message.length() + 1; + title_size + description_size + reward_size + new_message.length() + 1; in->pBuffer = new unsigned char[in->size]; @@ -2976,7 +2867,7 @@ namespace SoF ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; ibs.size = item->Size; - ibs.slots = SwapBits21and22(item->Slots); + ibs.slots = SwapBits21And22(item->Slots); ibs.price = item->Price; ibs.icon = item->Icon; ibs.unknown1 = 1; @@ -3066,7 +2957,7 @@ namespace SoF isbs.augtype = item->AugType; isbs.augrestrict = item->AugRestrict; - for (int index = 0; index < invaug::ItemAugSize; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { isbs.augslots[index].type = item->AugSlotType[index]; isbs.augslots[index].visible = item->AugSlotVisible[index]; isbs.augslots[index].unknown = item->AugSlotUnk2[index]; @@ -3238,18 +3129,18 @@ namespace SoF ob.write((const char*)&subitem_count, sizeof(uint32)); - for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) { + for (uint32 index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) { EQEmu::ItemInstance* sub = inst->GetItem(index); if (!sub) continue; int SubSlotNumber = INVALID_INDEX; - if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END) - SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1); - else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index); - else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index); + if (slot_id_in >= EQEmu::invslot::GENERAL_BEGIN && slot_id_in <= EQEmu::invslot::GENERAL_END) + SubSlotNumber = (((slot_id_in + 3) * EQEmu::invbag::SLOT_COUNT) + index + 1); + else if (slot_id_in >= EQEmu::invslot::BANK_BEGIN && slot_id_in <= EQEmu::invslot::BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::BANK_BAGS_BEGIN + index); + else if (slot_id_in >= EQEmu::invslot::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::invslot::SHARED_BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::SHARED_BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::SHARED_BANK_BAGS_BEGIN + index); else SubSlotNumber = slot_id_in; @@ -3267,16 +3158,16 @@ namespace SoF { uint32 SoFSlot = 0; - if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots + if (serverSlot >= EQEmu::invslot::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots SoFSlot = serverSlot + 1; - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) SoFSlot = serverSlot + 11; - else if (serverSlot >= EQEmu::legacy::BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::BANK_BAGS_END) + else if (serverSlot >= EQEmu::invbag::BANK_BAGS_BEGIN && serverSlot <= EQEmu::invbag::BANK_BAGS_END) SoFSlot = serverSlot + 1; - else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END) + else if (serverSlot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::invbag::SHARED_BANK_BAGS_END) SoFSlot = serverSlot + 1; - else if (serverSlot == EQEmu::inventory::slotPowerSource) - SoFSlot = invslot::PossessionsPowerSource; + else if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + SoFSlot = invslot::slotPowerSource; else SoFSlot = serverSlot; @@ -3293,16 +3184,16 @@ namespace SoF { uint32 ServerSlot = 0; - if (sofSlot >= invslot::PossessionsAmmo && sofSlot <= invslot::CorpseEnd) // Cursor/Ammo/Power Source and Normal Inventory Slots + if (sofSlot >= invslot::slotAmmo && sofSlot <= invslot::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots ServerSlot = sofSlot - 1; - else if (sofSlot >= invbag::GeneralBagsBegin && sofSlot <= invbag::CursorBagEnd) + else if (sofSlot >= invbag::GENERAL_BAGS_BEGIN && sofSlot <= invbag::CURSOR_BAG_END) ServerSlot = sofSlot - 11; - else if (sofSlot >= invbag::BankBagsBegin && sofSlot <= invbag::BankBagsEnd) + else if (sofSlot >= invbag::BANK_BAGS_BEGIN && sofSlot <= invbag::BANK_BAGS_END) ServerSlot = sofSlot - 1; - else if (sofSlot >= invbag::SharedBankBagsBegin && sofSlot <= invbag::SharedBankBagsEnd) + else if (sofSlot >= invbag::SHARED_BANK_BAGS_BEGIN && sofSlot <= invbag::SHARED_BANK_BAGS_END) ServerSlot = sofSlot - 1; - else if (sofSlot == invslot::PossessionsPowerSource) - ServerSlot = EQEmu::inventory::slotPowerSource; + else if (sofSlot == invslot::slotPowerSource) + ServerSlot = EQEmu::invslot::SLOT_POWER_SOURCE; else ServerSlot = sofSlot; @@ -3317,7 +3208,7 @@ namespace SoF static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink) { - if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) { + if ((constants::SAY_LINK_BODY_SIZE == EQEmu::constants::SAY_LINK_BODY_SIZE) || (serverSayLink.find('\x12') == std::string::npos)) { sofSayLink = serverSayLink; return; } @@ -3326,7 +3217,7 @@ namespace SoF for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= EQEmu::constants::SAY_LINK_BODY_SIZE) { sofSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; @@ -3357,7 +3248,7 @@ namespace SoF static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink) { - if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sofSayLink.find('\x12') == std::string::npos)) { + if ((EQEmu::constants::SAY_LINK_BODY_SIZE == constants::SAY_LINK_BODY_SIZE) || (sofSayLink.find('\x12') == std::string::npos)) { serverSayLink = sofSayLink; return; } @@ -3366,7 +3257,7 @@ namespace SoF for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= constants::SAY_LINK_BODY_SIZE) { serverSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; diff --git a/common/patches/sof_limits.cpp b/common/patches/sof_limits.cpp index b33943905..aa42320c8 100644 --- a/common/patches/sof_limits.cpp +++ b/common/patches/sof_limits.cpp @@ -22,198 +22,198 @@ #include "../string_util.h" -size_t SoF::invtype::GetInvTypeSize(int inv_type) +int16 SoF::invtype::GetInvTypeSize(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - return invtype::InvTypePossessionsSize; - case invtype::InvTypeBank: - return invtype::InvTypeBankSize; - case invtype::InvTypeSharedBank: - return invtype::InvTypeSharedBankSize; - case invtype::InvTypeTrade: - return invtype::InvTypeTradeSize; - case invtype::InvTypeWorld: - return invtype::InvTypeWorldSize; - case invtype::InvTypeLimbo: - return invtype::InvTypeLimboSize; - case invtype::InvTypeTribute: - return invtype::InvTypeTributeSize; - case invtype::InvTypeGuildTribute: - return invtype::InvTypeGuildTributeSize; - case invtype::InvTypeMerchant: - return invtype::InvTypeMerchantSize; - case invtype::InvTypeCorpse: - return invtype::InvTypeCorpseSize; - case invtype::InvTypeBazaar: - return invtype::InvTypeBazaarSize; - case invtype::InvTypeInspect: - return invtype::InvTypeInspectSize; - case invtype::InvTypeViewMODPC: - return invtype::InvTypeViewMODPCSize; - case invtype::InvTypeViewMODBank: - return invtype::InvTypeViewMODBankSize; - case invtype::InvTypeViewMODSharedBank: - return invtype::InvTypeViewMODSharedBankSize; - case invtype::InvTypeViewMODLimbo: - return invtype::InvTypeViewMODLimboSize; - case invtype::InvTypeAltStorage: - return invtype::InvTypeAltStorageSize; - case invtype::InvTypeArchived: - return invtype::InvTypeArchivedSize; - case invtype::InvTypeOther: - return invtype::InvTypeOtherSize; + case invtype::typePossessions: + return invtype::POSSESSIONS_SIZE; + case invtype::typeBank: + return invtype::BANK_SIZE; + case invtype::typeSharedBank: + return invtype::SHARED_BANK_SIZE; + case invtype::typeTrade: + return invtype::TRADE_SIZE; + case invtype::typeWorld: + return invtype::WORLD_SIZE; + case invtype::typeLimbo: + return invtype::LIMBO_SIZE; + case invtype::typeTribute: + return invtype::TRIBUTE_SIZE; + case invtype::typeGuildTribute: + return invtype::GUILD_TRIBUTE_SIZE; + case invtype::typeMerchant: + return invtype::MERCHANT_SIZE; + case invtype::typeCorpse: + return invtype::CORPSE_SIZE; + case invtype::typeBazaar: + return invtype::BAZAAR_SIZE; + case invtype::typeInspect: + return invtype::INSPECT_SIZE; + case invtype::typeViewMODPC: + return invtype::VIEW_MOD_PC_SIZE; + case invtype::typeViewMODBank: + return invtype::VIEW_MOD_BANK_SIZE; + case invtype::typeViewMODSharedBank: + return invtype::VIEW_MOD_SHARED_BANK_SIZE; + case invtype::typeViewMODLimbo: + return invtype::VIEW_MOD_LIMBO_SIZE; + case invtype::typeAltStorage: + return invtype::ALT_STORAGE_SIZE; + case invtype::typeArchived: + return invtype::ARCHIVED_SIZE; + case invtype::typeOther: + return invtype::OTHER_SIZE; default: - return 0; + return INULL; } } -const char* SoF::invtype::GetInvTypeName(int inv_type) +const char* SoF::invtype::GetInvTypeName(int16 inv_type) { switch (inv_type) { - case invtype::InvTypeInvalid: + case invtype::TYPE_INVALID: return "Invalid Type"; - case invtype::InvTypePossessions: + case invtype::typePossessions: return "Possessions"; - case invtype::InvTypeBank: + case invtype::typeBank: return "Bank"; - case invtype::InvTypeSharedBank: + case invtype::typeSharedBank: return "Shared Bank"; - case invtype::InvTypeTrade: + case invtype::typeTrade: return "Trade"; - case invtype::InvTypeWorld: + case invtype::typeWorld: return "World"; - case invtype::InvTypeLimbo: + case invtype::typeLimbo: return "Limbo"; - case invtype::InvTypeTribute: + case invtype::typeTribute: return "Tribute"; - case invtype::InvTypeGuildTribute: + case invtype::typeGuildTribute: return "Guild Tribute"; - case invtype::InvTypeMerchant: + case invtype::typeMerchant: return "Merchant"; - case invtype::InvTypeCorpse: + case invtype::typeCorpse: return "Corpse"; - case invtype::InvTypeBazaar: + case invtype::typeBazaar: return "Bazaar"; - case invtype::InvTypeInspect: + case invtype::typeInspect: return "Inspect"; - case invtype::InvTypeViewMODPC: + case invtype::typeViewMODPC: return "View MOD PC"; - case invtype::InvTypeViewMODBank: + case invtype::typeViewMODBank: return "View MOD Bank"; - case invtype::InvTypeViewMODSharedBank: + case invtype::typeViewMODSharedBank: return "View MOD Shared Bank"; - case invtype::InvTypeViewMODLimbo: + case invtype::typeViewMODLimbo: return "View MOD Limbo"; - case invtype::InvTypeAltStorage: + case invtype::typeAltStorage: return "Alt Storage"; - case invtype::InvTypeArchived: + case invtype::typeArchived: return "Archived"; - case invtype::InvTypeOther: + case invtype::typeOther: return "Other"; default: return "Unknown Type"; } } -bool SoF::invtype::IsInvTypePersistent(int inv_type) +bool SoF::invtype::IsInvTypePersistent(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - case invtype::InvTypeBank: - case invtype::InvTypeSharedBank: - case invtype::InvTypeTrade: - case invtype::InvTypeWorld: - case invtype::InvTypeLimbo: - case invtype::InvTypeTribute: - case invtype::InvTypeGuildTribute: + case invtype::typePossessions: + case invtype::typeBank: + case invtype::typeSharedBank: + case invtype::typeTrade: + case invtype::typeWorld: + case invtype::typeLimbo: + case invtype::typeTribute: + case invtype::typeGuildTribute: return true; default: return false; } } -const char* SoF::invslot::GetInvPossessionsSlotName(int inv_slot) +const char* SoF::invslot::GetInvPossessionsSlotName(int16 inv_slot) { switch (inv_slot) { - case invslot::InvSlotInvalid: + case invslot::SLOT_INVALID: return "Invalid Slot"; - case invslot::PossessionsCharm: + case invslot::slotCharm: return "Charm"; - case invslot::PossessionsEar1: + case invslot::slotEar1: return "Ear 1"; - case invslot::PossessionsHead: + case invslot::slotHead: return "Head"; - case invslot::PossessionsFace: + case invslot::slotFace: return "Face"; - case invslot::PossessionsEar2: + case invslot::slotEar2: return "Ear 2"; - case invslot::PossessionsNeck: + case invslot::slotNeck: return "Neck"; - case invslot::PossessionsShoulders: + case invslot::slotShoulders: return "Shoulders"; - case invslot::PossessionsArms: + case invslot::slotArms: return "Arms"; - case invslot::PossessionsBack: + case invslot::slotBack: return "Back"; - case invslot::PossessionsWrist1: + case invslot::slotWrist1: return "Wrist 1"; - case invslot::PossessionsWrist2: + case invslot::slotWrist2: return "Wrist 2"; - case invslot::PossessionsRange: + case invslot::slotRange: return "Range"; - case invslot::PossessionsHands: + case invslot::slotHands: return "Hands"; - case invslot::PossessionsPrimary: + case invslot::slotPrimary: return "Primary"; - case invslot::PossessionsSecondary: + case invslot::slotSecondary: return "Secondary"; - case invslot::PossessionsFinger1: + case invslot::slotFinger1: return "Finger 1"; - case invslot::PossessionsFinger2: + case invslot::slotFinger2: return "Finger 2"; - case invslot::PossessionsChest: + case invslot::slotChest: return "Chest"; - case invslot::PossessionsLegs: + case invslot::slotLegs: return "Legs"; - case invslot::PossessionsFeet: + case invslot::slotFeet: return "Feet"; - case invslot::PossessionsWaist: + case invslot::slotWaist: return "Waist"; - case invslot::PossessionsPowerSource: + case invslot::slotPowerSource: return "Power Source"; - case invslot::PossessionsAmmo: + case invslot::slotAmmo: return "Ammo"; - case invslot::PossessionsGeneral1: + case invslot::slotGeneral1: return "General 1"; - case invslot::PossessionsGeneral2: + case invslot::slotGeneral2: return "General 2"; - case invslot::PossessionsGeneral3: + case invslot::slotGeneral3: return "General 3"; - case invslot::PossessionsGeneral4: + case invslot::slotGeneral4: return "General 4"; - case invslot::PossessionsGeneral5: + case invslot::slotGeneral5: return "General 5"; - case invslot::PossessionsGeneral6: + case invslot::slotGeneral6: return "General 6"; - case invslot::PossessionsGeneral7: + case invslot::slotGeneral7: return "General 7"; - case invslot::PossessionsGeneral8: + case invslot::slotGeneral8: return "General 8"; - case invslot::PossessionsCursor: + case invslot::slotCursor: return "Cursor"; default: return "Unknown Slot"; } } -const char* SoF::invslot::GetInvCorpseSlotName(int inv_slot) +const char* SoF::invslot::GetInvCorpseSlotName(int16 inv_slot) { - if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid) + if (!invtype::GetInvTypeSize(invtype::typeCorpse) || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; // needs work - if ((size_t)(inv_slot + 1) < invslot::CorpseBegin || (size_t)(inv_slot + 1) >= invslot::CorpseEnd) + if ((inv_slot + 1) < invslot::CORPSE_BEGIN || (inv_slot + 1) >= invslot::CORPSE_END) return "Unknown Slot"; static std::string ret_str; @@ -222,19 +222,19 @@ const char* SoF::invslot::GetInvCorpseSlotName(int inv_slot) return ret_str.c_str(); } -const char* SoF::invslot::GetInvSlotName(int inv_type, int inv_slot) +const char* SoF::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot) { - if (inv_type == invtype::InvTypePossessions) + if (inv_type == invtype::typePossessions) return invslot::GetInvPossessionsSlotName(inv_slot); - else if (inv_type == invtype::InvTypeCorpse) + else if (inv_type == invtype::typeCorpse) return invslot::GetInvCorpseSlotName(inv_slot); - size_t type_size = invtype::GetInvTypeSize(inv_type); + int16 type_size = invtype::GetInvTypeSize(inv_type); - if (!type_size || inv_slot == invslot::InvSlotInvalid) + if (!type_size || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; - if ((size_t)(inv_slot + 1) >= type_size) + if ((inv_slot + 1) >= type_size) return "Unknown Slot"; static std::string ret_str; @@ -243,12 +243,12 @@ const char* SoF::invslot::GetInvSlotName(int inv_type, int inv_slot) return ret_str.c_str(); } -const char* SoF::invbag::GetInvBagIndexName(int bag_index) +const char* SoF::invbag::GetInvBagIndexName(int16 bag_index) { - if (bag_index == invbag::InvBagInvalid) + if (bag_index == invbag::SLOT_INVALID) return "Invalid Bag"; - if ((size_t)bag_index >= invbag::ItemBagSize) + if (bag_index >= invbag::SLOT_COUNT) return "Unknown Bag"; static std::string ret_str; @@ -257,12 +257,12 @@ const char* SoF::invbag::GetInvBagIndexName(int bag_index) return ret_str.c_str(); } -const char* SoF::invaug::GetInvAugIndexName(int aug_index) +const char* SoF::invaug::GetInvAugIndexName(int16 aug_index) { - if (aug_index == invaug::InvAugInvalid) + if (aug_index == invaug::SOCKET_INVALID) return "Invalid Augment"; - if ((size_t)aug_index >= invaug::ItemAugSize) + if (aug_index >= invaug::SOCKET_COUNT) return "Unknown Augment"; static std::string ret_str; diff --git a/common/patches/sof_limits.h b/common/patches/sof_limits.h index d34197a90..fdc688370 100644 --- a/common/patches/sof_limits.h +++ b/common/patches/sof_limits.h @@ -27,108 +27,218 @@ namespace SoF { - enum : int { Invalid = -1, Null, Safety }; + const int16 IINVALID = -1; + const int16 INULL = 0; - enum : bool { False = false, True = true }; - - // pre-declarations namespace inventory { inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::SoF; } + const bool ConcatenateInvTypeLimbo = true; + + const bool AllowOverLevelEquipment = false; + + const bool AllowEmptyBagInBag = false; + const bool AllowClickCastFromBag = false; + } /*inventory*/ namespace invtype { inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::SoF; } - enum : int { InvTypeInvalid = -1, InvTypeBegin }; + namespace enum_ { + enum InventoryTypes : int16 { + typePossessions = INULL, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, + typeTribute, + typeGuildTribute, + typeMerchant, + typeCorpse, + typeBazaar, + typeInspect, + typeViewMODPC, + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, + typeOther + }; - enum InventoryType : int { - InvTypePossessions = InvTypeBegin, - InvTypeBank, - InvTypeSharedBank, - InvTypeTrade, - InvTypeWorld, - InvTypeLimbo, - InvTypeTribute, - InvTypeGuildTribute, - InvTypeMerchant, - InvTypeCorpse, - InvTypeBazaar, - InvTypeInspect, - InvTypeViewMODPC, - InvTypeViewMODBank, - InvTypeViewMODSharedBank, - InvTypeViewMODLimbo, - InvTypeAltStorage, - InvTypeArchived, - InvTypeOther, - InvTypeCount - }; + } // namespace enum_ + using namespace enum_; + + const int16 POSSESSIONS_SIZE = 32; + const int16 BANK_SIZE = 24; + const int16 SHARED_BANK_SIZE = 2; + const int16 TRADE_SIZE = 8; + const int16 WORLD_SIZE = 10; + const int16 LIMBO_SIZE = 36; + const int16 TRIBUTE_SIZE = 5; + const int16 GUILD_TRIBUTE_SIZE = 2; + const int16 MERCHANT_SIZE = 80; + const int16 CORPSE_SIZE = POSSESSIONS_SIZE; + const int16 BAZAAR_SIZE = 80; + const int16 INSPECT_SIZE = 23; + const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE; + const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE; + const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE; + const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE; + const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank" + const int16 ARCHIVED_SIZE = 0;//unknown + const int16 OTHER_SIZE = 0;//unknown + + const int16 TRADE_NPC_SIZE = 4; // defined by implication + + const int16 TYPE_INVALID = IINVALID; + const int16 TYPE_BEGIN = typePossessions; + const int16 TYPE_END = typeOther; + const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1; + + int16 GetInvTypeSize(int16 inv_type); + const char* GetInvTypeName(int16 inv_type); + + bool IsInvTypePersistent(int16 inv_type); } /*invtype*/ namespace invslot { inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::SoF; } - enum : int { InvSlotInvalid = -1, InvSlotBegin }; + namespace enum_ { + enum InventorySlots : int16 { + slotCharm = INULL, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, + slotPowerSource, + slotAmmo, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotCursor + }; - enum PossessionsSlot : int { - PossessionsCharm = InvSlotBegin, - PossessionsEar1, - PossessionsHead, - PossessionsFace, - PossessionsEar2, - PossessionsNeck, - PossessionsShoulders, - PossessionsArms, - PossessionsBack, - PossessionsWrist1, - PossessionsWrist2, - PossessionsRange, - PossessionsHands, - PossessionsPrimary, - PossessionsSecondary, - PossessionsFinger1, - PossessionsFinger2, - PossessionsChest, - PossessionsLegs, - PossessionsFeet, - PossessionsWaist, - PossessionsPowerSource, - PossessionsAmmo, - PossessionsGeneral1, - PossessionsGeneral2, - PossessionsGeneral3, - PossessionsGeneral4, - PossessionsGeneral5, - PossessionsGeneral6, - PossessionsGeneral7, - PossessionsGeneral8, - PossessionsCursor, - PossessionsCount - }; + } // namespace enum_ + using namespace enum_; - const int EquipmentBegin = PossessionsCharm; - const int EquipmentEnd = PossessionsAmmo; - const int EquipmentCount = (EquipmentEnd - EquipmentBegin + 1); + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; - const int GeneralBegin = PossessionsGeneral1; - const int GeneralEnd = PossessionsGeneral8; - const int GeneralCount = (GeneralEnd - GeneralBegin + 1); + const int16 POSSESSIONS_BEGIN = slotCharm; + const int16 POSSESSIONS_END = slotCursor; + const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; + + const int16 EQUIPMENT_BEGIN = slotCharm; + const int16 EQUIPMENT_END = slotAmmo; + const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN + 1); + + const int16 GENERAL_BEGIN = slotGeneral1; + const int16 GENERAL_END = slotGeneral8; + const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN + 1); + + const int16 BONUS_BEGIN = invslot::slotCharm; + const int16 BONUS_STAT_END = invslot::slotPowerSource; + const int16 BONUS_SKILL_END = invslot::slotAmmo; + + const int16 BANK_BEGIN = 2000; + const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1; + + const int16 SHARED_BANK_BEGIN = 2500; + const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1; + + const int16 TRADE_BEGIN = 3000; + const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1; + + const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication + + const int16 WORLD_BEGIN = 4000; + const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1; + + const int16 TRIBUTE_BEGIN = 400; + const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1; + + const int16 GUILD_TRIBUTE_BEGIN = 450; + const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor; + + const uint64 POSSESSIONS_BITMASK = 0x000000027FFFFFFF; // based on 34-slot count (RoF+) + const uint64 CORPSE_BITMASK = 0x01FFFFFE7F800000; // based on 34-slot count (RoF+) + + const char* GetInvPossessionsSlotName(int16 inv_slot); + const char* GetInvCorpseSlotName(int16 inv_slot); + const char* GetInvSlotName(int16 inv_type, int16 inv_slot); } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::SoF; } - enum : int { InvBagInvalid = -1, InvBagBegin }; + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; + const int16 SLOT_END = 9; + const int16 SLOT_COUNT = 10; + + const int16 GENERAL_BAGS_BEGIN = 262; + const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT; + const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1; + + const int16 CURSOR_BAG_BEGIN = 342; + const int16 CURSOR_BAG_COUNT = SLOT_COUNT; + const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1; + + const int16 BANK_BAGS_BEGIN = 2032; + const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT); + const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1; + + const int16 SHARED_BANK_BAGS_BEGIN = 2532; + const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT; + const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1; + + const int16 TRADE_BAGS_BEGIN = 3031; + const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT; + const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1; + + const char* GetInvBagIndexName(int16 bag_index); } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::SoF; } - enum : int { InvAugInvalid = -1, InvAugBegin }; + const int16 SOCKET_INVALID = IINVALID; + const int16 SOCKET_BEGIN = INULL; + const int16 SOCKET_END = 4; + const int16 SOCKET_COUNT = 5; + + const char* GetInvAugIndexName(int16 aug_index); } /*invaug*/ @@ -153,147 +263,21 @@ namespace SoF namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::SoF; } + const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances + const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance + + const int16 POTION_BELT_SIZE = 5; + + const int16 SKILL_ARRAY_SIZE = 100; + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::SoF; } - } /*constants*/ + const size_t CHARACTER_CREATION_LIMIT = 12; - namespace behavior { - inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::SoF; } - - } /*behavior*/ - - namespace skills { - inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoF; } - - } /*skills*/ - - - // declarations - namespace inventory { - const bool ConcatenateInvTypeLimbo = true; - - const bool AllowOverLevelEquipment = false; - - const bool AllowEmptyBagInBag = false; - const bool AllowClickCastFromBag = false; - - } /*inventory*/ - - namespace invtype { - const size_t InvTypePossessionsSize = invslot::PossessionsCount; - const size_t InvTypeBankSize = 24; - const size_t InvTypeSharedBankSize = 2; - const size_t InvTypeTradeSize = 8; - const size_t InvTypeWorldSize = 10; - const size_t InvTypeLimboSize = 36; - const size_t InvTypeTributeSize = 5; - const size_t InvTypeGuildTributeSize = 2; - const size_t InvTypeMerchantSize = 80; - const size_t InvTypeCorpseSize = InvTypePossessionsSize; - const size_t InvTypeBazaarSize = 80; - const size_t InvTypeInspectSize = invslot::EquipmentCount; - const size_t InvTypeViewMODPCSize = InvTypePossessionsSize; - const size_t InvTypeViewMODBankSize = InvTypeBankSize; - const size_t InvTypeViewMODSharedBankSize = InvTypeSharedBankSize; - const size_t InvTypeViewMODLimboSize = InvTypeLimboSize; - const size_t InvTypeAltStorageSize = 0;//unknown - "Shroud Bank" - const size_t InvTypeArchivedSize = 0;//unknown - const size_t InvTypeOtherSize = 0;//unknown - - extern size_t GetInvTypeSize(int inv_type); - extern const char* GetInvTypeName(int inv_type); - - extern bool IsInvTypePersistent(int inv_type); - - } /*invtype*/ - - namespace invslot { - const int BankBegin = 2000; - const int BankEnd = (BankBegin + invtype::InvTypeBankSize) - 1; - - const int SharedBankBegin = 2500; - const int SharedBankEnd = (SharedBankBegin + invtype::InvTypeSharedBankSize) - 1; - - const int TradeBegin = 3000; - const int TradeEnd = (TradeBegin + invtype::InvTypeTradeSize) - 1; - const int TradeNPCEnd = 3003; - - const int WorldBegin = 4000; - const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1; - - const int TributeBegin = 400; - const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1; - - const int GuildTributeBegin = 450; - const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1; - - const int CorpseBegin = PossessionsGeneral1; - const int CorpseEnd = PossessionsGeneral1 + PossessionsCursor; - - extern const char* GetInvPossessionsSlotName(int inv_slot); - extern const char* GetInvCorpseSlotName(int inv_slot); - extern const char* GetInvSlotName(int inv_type, int inv_slot); - - } /*invslot*/ - - namespace invbag { - const size_t ItemBagSize = 10; - - const int GeneralBagsBegin = 262; - const int GeneralBagsSize = invslot::GeneralCount * ItemBagSize; - const int GeneralBagsEnd = (GeneralBagsBegin + GeneralBagsSize) - 1; - - const int CursorBagBegin = 342; - const int CursorBagSize = ItemBagSize; - const int CursorBagEnd = (CursorBagBegin + CursorBagSize) - 1; - - const int BankBagsBegin = 2032; - const int BankBagsSize = (invtype::InvTypeBankSize * ItemBagSize); - const int BankBagsEnd = (BankBagsBegin + BankBagsSize) - 1; - - const int SharedBankBagsBegin = 2532; - const int SharedBankBagsSize = invtype::InvTypeSharedBankSize * ItemBagSize; - const int SharedBankBagsEnd = (SharedBankBagsBegin + SharedBankBagsSize) - 1; - - const int TradeBagsBegin = 3031; - const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize; - const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1; - - extern const char* GetInvBagIndexName(int bag_index); - - } /*invbag*/ - - namespace invaug { - const size_t ItemAugSize = 5; - - extern const char* GetInvAugIndexName(int aug_index); - - } /*invaug*/ - - namespace item { - - } /*item*/ - - namespace profile { - const size_t TributeSize = invtype::InvTypeTributeSize; - const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize; - - const size_t BandoliersSize = 20; // number of bandolier instances - const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance - - const size_t PotionBeltSize = 5; - - const size_t SkillArraySize = 100; - - } /*profile*/ - - namespace constants { - const size_t CharacterCreationLimit = 12; - - const size_t SayLinkBodySize = 50; + const size_t SAY_LINK_BODY_SIZE = 50; const int LongBuffs = 25; const int ShortBuffs = 15; @@ -306,11 +290,15 @@ namespace SoF } /*constants*/ namespace behavior { + inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::SoF; } + const bool CoinHasWeight = true; } /*behavior*/ namespace skills { + inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoF; } + const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack; } /*skills*/ diff --git a/common/patches/sof_ops.h b/common/patches/sof_ops.h index c4e42d8d4..0ff2cfd2f 100644 --- a/common/patches/sof_ops.h +++ b/common/patches/sof_ops.h @@ -62,7 +62,6 @@ E(OP_MoveItem) E(OP_NewSpawn) E(OP_NewZone) E(OP_OnLevelMessage) -E(OP_OpenNewTasksWindow) E(OP_PetBuffWindow) E(OP_PlayerProfile) E(OP_RaidJoin) diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 29272a7a6..a312b48a8 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -717,7 +717,7 @@ struct BandolierItem_Struct struct Bandolier_Struct { char Name[32]; - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; //len = 72 @@ -731,7 +731,7 @@ struct PotionBeltItem_Struct //len = 288 struct PotionBelt_Struct { - PotionBeltItem_Struct Items[profile::PotionBeltSize]; + PotionBeltItem_Struct Items[profile::POTION_BELT_SIZE]; }; static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16; @@ -937,7 +937,7 @@ struct PlayerProfile_Struct //23576 Octets /*08288*/ uint32 aapoints_spent; // Number of spent AA points /*08292*/ uint32 aapoints; // Unspent AA points /*08296*/ uint8 unknown06160[4]; -/*08300*/ Bandolier_Struct bandoliers[profile::BandoliersSize]; // [6400] bandolier contents +/*08300*/ Bandolier_Struct bandoliers[profile::BANDOLIERS_SIZE]; // [6400] bandolier contents /*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot /*15060*/ uint8 unknown12852[8]; /*15068*/ uint32 available_slots; diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index bf3c3d359..339cbb85d 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -1051,18 +1051,18 @@ namespace Titanium // OUT(unknown06160[4]); // Copy bandoliers where server and client indexes converge - for (r = 0; r < EQEmu::legacy::BANDOLIERS_SIZE && r < profile::BandoliersSize; ++r) { + for (r = 0; r < EQEmu::profile::BANDOLIERS_SIZE && r < profile::BANDOLIERS_SIZE; ++r) { OUT_str(bandoliers[r].Name); - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true OUT(bandoliers[r].Items[k].ID); OUT(bandoliers[r].Items[k].Icon); OUT_str(bandoliers[r].Items[k].Name); } } // Nullify bandoliers where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::BANDOLIERS_SIZE; r < profile::BandoliersSize; ++r) { + for (r = EQEmu::profile::BANDOLIERS_SIZE; r < profile::BANDOLIERS_SIZE; ++r) { eq->bandoliers[r].Name[0] = '\0'; - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true eq->bandoliers[r].Items[k].ID = 0; eq->bandoliers[r].Items[k].Icon = 0; eq->bandoliers[r].Items[k].Name[0] = '\0'; @@ -1072,13 +1072,13 @@ namespace Titanium // OUT(unknown07444[5120]); // Copy potion belt where server and client indexes converge - for (r = 0; r < EQEmu::legacy::POTION_BELT_ITEM_COUNT && r < profile::PotionBeltSize; ++r) { + for (r = 0; r < EQEmu::profile::POTION_BELT_SIZE && r < profile::POTION_BELT_SIZE; ++r) { OUT(potionbelt.Items[r].ID); OUT(potionbelt.Items[r].Icon); OUT_str(potionbelt.Items[r].Name); } // Nullify potion belt where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::POTION_BELT_ITEM_COUNT; r < profile::PotionBeltSize; ++r) { + for (r = EQEmu::profile::POTION_BELT_SIZE; r < profile::POTION_BELT_SIZE; ++r) { eq->potionbelt.Items[r].ID = 0; eq->potionbelt.Items[r].Icon = 0; eq->potionbelt.Items[r].Name[0] = '\0'; @@ -1459,13 +1459,16 @@ namespace Titanium InBuffer += description_size; InBuffer += sizeof(TaskDescriptionData2_Struct); - std::string old_message = InBuffer; // start 'Reward' as string + uint32 reward_size = strlen(InBuffer) + 1; + InBuffer += reward_size; + + std::string old_message = InBuffer; // start item link string std::string new_message; ServerToTitaniumSayLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) + sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) + - title_size + description_size + new_message.length() + 1; + title_size + description_size + reward_size + new_message.length() + 1; in->pBuffer = new unsigned char[in->size]; @@ -1479,6 +1482,7 @@ namespace Titanium InBuffer += strlen(InBuffer) + 1; memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct)); + // we have an extra DWORD in the trailer struct, client should ignore it so w/e delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); @@ -2442,7 +2446,7 @@ namespace Titanium ob << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data // Sub data - for (int index = EQEmu::inventory::containerBegin; index < invbag::ItemBagSize; ++index) { + for (int index = EQEmu::invbag::SLOT_BEGIN; index <= invbag::SLOT_END; ++index) { ob << '|'; EQEmu::ItemInstance* sub = inst->GetItem(index); @@ -2490,7 +2494,7 @@ namespace Titanium static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink) { - if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) { + if ((constants::SAY_LINK_BODY_SIZE == EQEmu::constants::SAY_LINK_BODY_SIZE) || (serverSayLink.find('\x12') == std::string::npos)) { titaniumSayLink = serverSayLink; return; } @@ -2499,7 +2503,7 @@ namespace Titanium for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= EQEmu::constants::SAY_LINK_BODY_SIZE) { titaniumSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; @@ -2530,7 +2534,7 @@ namespace Titanium static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink) { - if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (titaniumSayLink.find('\x12') == std::string::npos)) { + if ((EQEmu::constants::SAY_LINK_BODY_SIZE == constants::SAY_LINK_BODY_SIZE) || (titaniumSayLink.find('\x12') == std::string::npos)) { serverSayLink = titaniumSayLink; return; } @@ -2539,7 +2543,7 @@ namespace Titanium for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= constants::SAY_LINK_BODY_SIZE) { serverSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; diff --git a/common/patches/titanium_limits.cpp b/common/patches/titanium_limits.cpp index 3976e8217..2cab723f0 100644 --- a/common/patches/titanium_limits.cpp +++ b/common/patches/titanium_limits.cpp @@ -22,196 +22,196 @@ #include "../string_util.h" -size_t Titanium::invtype::GetInvTypeSize(int inv_type) +int16 Titanium::invtype::GetInvTypeSize(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - return invtype::InvTypePossessionsSize; - case invtype::InvTypeBank: - return invtype::InvTypeBankSize; - case invtype::InvTypeSharedBank: - return invtype::InvTypeSharedBankSize; - case invtype::InvTypeTrade: - return invtype::InvTypeTradeSize; - case invtype::InvTypeWorld: - return invtype::InvTypeWorldSize; - case invtype::InvTypeLimbo: - return invtype::InvTypeLimboSize; - case invtype::InvTypeTribute: - return invtype::InvTypeTributeSize; - case invtype::InvTypeGuildTribute: - return invtype::InvTypeGuildTributeSize; - case invtype::InvTypeMerchant: - return invtype::InvTypeMerchantSize; - case invtype::InvTypeCorpse: - return invtype::InvTypeCorpseSize; - case invtype::InvTypeBazaar: - return invtype::InvTypeBazaarSize; - case invtype::InvTypeInspect: - return invtype::InvTypeInspectSize; - case invtype::InvTypeViewMODPC: - return invtype::InvTypeViewMODPCSize; - case invtype::InvTypeViewMODBank: - return invtype::InvTypeViewMODBankSize; - case invtype::InvTypeViewMODSharedBank: - return invtype::InvTypeViewMODSharedBankSize; - case invtype::InvTypeViewMODLimbo: - return invtype::InvTypeViewMODLimboSize; - case invtype::InvTypeAltStorage: - return invtype::InvTypeAltStorageSize; - case invtype::InvTypeArchived: - return invtype::InvTypeArchivedSize; - case invtype::InvTypeOther: - return invtype::InvTypeOtherSize; + case invtype::typePossessions: + return invtype::POSSESSIONS_SIZE; + case invtype::typeBank: + return invtype::BANK_SIZE; + case invtype::typeSharedBank: + return invtype::SHARED_BANK_SIZE; + case invtype::typeTrade: + return invtype::TRADE_SIZE; + case invtype::typeWorld: + return invtype::WORLD_SIZE; + case invtype::typeLimbo: + return invtype::LIMBO_SIZE; + case invtype::typeTribute: + return invtype::TRIBUTE_SIZE; + case invtype::typeGuildTribute: + return invtype::GUILD_TRIBUTE_SIZE; + case invtype::typeMerchant: + return invtype::MERCHANT_SIZE; + case invtype::typeCorpse: + return invtype::CORPSE_SIZE; + case invtype::typeBazaar: + return invtype::BAZAAR_SIZE; + case invtype::typeInspect: + return invtype::INSPECT_SIZE; + case invtype::typeViewMODPC: + return invtype::VIEW_MOD_PC_SIZE; + case invtype::typeViewMODBank: + return invtype::VIEW_MOD_BANK_SIZE; + case invtype::typeViewMODSharedBank: + return invtype::VIEW_MOD_SHARED_BANK_SIZE; + case invtype::typeViewMODLimbo: + return invtype::VIEW_MOD_LIMBO_SIZE; + case invtype::typeAltStorage: + return invtype::ALT_STORAGE_SIZE; + case invtype::typeArchived: + return invtype::ARCHIVED_SIZE; + case invtype::typeOther: + return invtype::OTHER_SIZE; default: - return 0; + return INULL; } } -const char* Titanium::invtype::GetInvTypeName(int inv_type) +const char* Titanium::invtype::GetInvTypeName(int16 inv_type) { switch (inv_type) { - case invtype::InvTypeInvalid: + case invtype::TYPE_INVALID: return "Invalid Type"; - case invtype::InvTypePossessions: + case invtype::typePossessions: return "Possessions"; - case invtype::InvTypeBank: + case invtype::typeBank: return "Bank"; - case invtype::InvTypeSharedBank: + case invtype::typeSharedBank: return "Shared Bank"; - case invtype::InvTypeTrade: + case invtype::typeTrade: return "Trade"; - case invtype::InvTypeWorld: + case invtype::typeWorld: return "World"; - case invtype::InvTypeLimbo: + case invtype::typeLimbo: return "Limbo"; - case invtype::InvTypeTribute: + case invtype::typeTribute: return "Tribute"; - case invtype::InvTypeGuildTribute: + case invtype::typeGuildTribute: return "Guild Tribute"; - case invtype::InvTypeMerchant: + case invtype::typeMerchant: return "Merchant"; - case invtype::InvTypeCorpse: + case invtype::typeCorpse: return "Corpse"; - case invtype::InvTypeBazaar: + case invtype::typeBazaar: return "Bazaar"; - case invtype::InvTypeInspect: + case invtype::typeInspect: return "Inspect"; - case invtype::InvTypeViewMODPC: + case invtype::typeViewMODPC: return "View MOD PC"; - case invtype::InvTypeViewMODBank: + case invtype::typeViewMODBank: return "View MOD Bank"; - case invtype::InvTypeViewMODSharedBank: + case invtype::typeViewMODSharedBank: return "View MOD Shared Bank"; - case invtype::InvTypeViewMODLimbo: + case invtype::typeViewMODLimbo: return "View MOD Limbo"; - case invtype::InvTypeAltStorage: + case invtype::typeAltStorage: return "Alt Storage"; - case invtype::InvTypeArchived: + case invtype::typeArchived: return "Archived"; - case invtype::InvTypeOther: + case invtype::typeOther: return "Other"; default: return "Unknown Type"; } } -bool Titanium::invtype::IsInvTypePersistent(int inv_type) +bool Titanium::invtype::IsInvTypePersistent(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - case invtype::InvTypeBank: - case invtype::InvTypeSharedBank: - case invtype::InvTypeTrade: - case invtype::InvTypeWorld: - case invtype::InvTypeLimbo: - case invtype::InvTypeTribute: - case invtype::InvTypeGuildTribute: + case invtype::typePossessions: + case invtype::typeBank: + case invtype::typeSharedBank: + case invtype::typeTrade: + case invtype::typeWorld: + case invtype::typeLimbo: + case invtype::typeTribute: + case invtype::typeGuildTribute: return true; default: return false; } } -const char* Titanium::invslot::GetInvPossessionsSlotName(int inv_slot) +const char* Titanium::invslot::GetInvPossessionsSlotName(int16 inv_slot) { switch (inv_slot) { - case invslot::InvSlotInvalid: + case invslot::SLOT_INVALID: return "Invalid Slot"; - case invslot::PossessionsCharm: + case invslot::slotCharm: return "Charm"; - case invslot::PossessionsEar1: + case invslot::slotEar1: return "Ear 1"; - case invslot::PossessionsHead: + case invslot::slotHead: return "Head"; - case invslot::PossessionsFace: + case invslot::slotFace: return "Face"; - case invslot::PossessionsEar2: + case invslot::slotEar2: return "Ear 2"; - case invslot::PossessionsNeck: + case invslot::slotNeck: return "Neck"; - case invslot::PossessionsShoulders: + case invslot::slotShoulders: return "Shoulders"; - case invslot::PossessionsArms: + case invslot::slotArms: return "Arms"; - case invslot::PossessionsBack: + case invslot::slotBack: return "Back"; - case invslot::PossessionsWrist1: + case invslot::slotWrist1: return "Wrist 1"; - case invslot::PossessionsWrist2: + case invslot::slotWrist2: return "Wrist 2"; - case invslot::PossessionsRange: + case invslot::slotRange: return "Range"; - case invslot::PossessionsHands: + case invslot::slotHands: return "Hands"; - case invslot::PossessionsPrimary: + case invslot::slotPrimary: return "Primary"; - case invslot::PossessionsSecondary: + case invslot::slotSecondary: return "Secondary"; - case invslot::PossessionsFinger1: + case invslot::slotFinger1: return "Finger 1"; - case invslot::PossessionsFinger2: + case invslot::slotFinger2: return "Finger 2"; - case invslot::PossessionsChest: + case invslot::slotChest: return "Chest"; - case invslot::PossessionsLegs: + case invslot::slotLegs: return "Legs"; - case invslot::PossessionsFeet: + case invslot::slotFeet: return "Feet"; - case invslot::PossessionsWaist: + case invslot::slotWaist: return "Waist"; - case invslot::PossessionsAmmo: + case invslot::slotAmmo: return "Ammo"; - case invslot::PossessionsGeneral1: + case invslot::slotGeneral1: return "General 1"; - case invslot::PossessionsGeneral2: + case invslot::slotGeneral2: return "General 2"; - case invslot::PossessionsGeneral3: + case invslot::slotGeneral3: return "General 3"; - case invslot::PossessionsGeneral4: + case invslot::slotGeneral4: return "General 4"; - case invslot::PossessionsGeneral5: + case invslot::slotGeneral5: return "General 5"; - case invslot::PossessionsGeneral6: + case invslot::slotGeneral6: return "General 6"; - case invslot::PossessionsGeneral7: + case invslot::slotGeneral7: return "General 7"; - case invslot::PossessionsGeneral8: + case invslot::slotGeneral8: return "General 8"; - case invslot::PossessionsCursor: + case invslot::slotCursor: return "Cursor"; default: return "Unknown Slot"; } } -const char* Titanium::invslot::GetInvCorpseSlotName(int inv_slot) +const char* Titanium::invslot::GetInvCorpseSlotName(int16 inv_slot) { - if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid) + if (!invtype::GetInvTypeSize(invtype::typeCorpse) || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; // needs work - if ((size_t)(inv_slot + 1) < invslot::CorpseBegin || (size_t)(inv_slot + 1) >= invslot::CorpseEnd) + if ((inv_slot + 1) < invslot::CORPSE_BEGIN || (inv_slot + 1) >= invslot::CORPSE_END) return "Unknown Slot"; static std::string ret_str; @@ -220,19 +220,19 @@ const char* Titanium::invslot::GetInvCorpseSlotName(int inv_slot) return ret_str.c_str(); } -const char* Titanium::invslot::GetInvSlotName(int inv_type, int inv_slot) +const char* Titanium::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot) { - if (inv_type == invtype::InvTypePossessions) + if (inv_type == invtype::typePossessions) return invslot::GetInvPossessionsSlotName(inv_slot); - else if (inv_type == invtype::InvTypeCorpse) + else if (inv_type == invtype::typeCorpse) return invslot::GetInvCorpseSlotName(inv_slot); - size_t type_size = invtype::GetInvTypeSize(inv_type); + int16 type_size = invtype::GetInvTypeSize(inv_type); - if (!type_size || inv_slot == invslot::InvSlotInvalid) + if (!type_size || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; - if ((size_t)(inv_slot + 1) >= type_size) + if ((inv_slot + 1) >= type_size) return "Unknown Slot"; static std::string ret_str; @@ -241,12 +241,12 @@ const char* Titanium::invslot::GetInvSlotName(int inv_type, int inv_slot) return ret_str.c_str(); } -const char* Titanium::invbag::GetInvBagIndexName(int bag_index) +const char* Titanium::invbag::GetInvBagIndexName(int16 bag_index) { - if (bag_index == invbag::InvBagInvalid) + if (bag_index == invbag::SLOT_INVALID) return "Invalid Bag"; - if ((size_t)bag_index >= invbag::ItemBagSize) + if (bag_index >= invbag::SLOT_COUNT) return "Unknown Bag"; static std::string ret_str; @@ -255,12 +255,12 @@ const char* Titanium::invbag::GetInvBagIndexName(int bag_index) return ret_str.c_str(); } -const char* Titanium::invaug::GetInvAugIndexName(int aug_index) +const char* Titanium::invaug::GetInvAugIndexName(int16 aug_index) { - if (aug_index == invaug::InvAugInvalid) + if (aug_index == invaug::SOCKET_INVALID) return "Invalid Augment"; - if ((size_t)aug_index >= invaug::ItemAugSize) + if (aug_index >= invaug::SOCKET_COUNT) return "Unknown Augment"; static std::string ret_str; diff --git a/common/patches/titanium_limits.h b/common/patches/titanium_limits.h index 3266ade6f..cd69c21e1 100644 --- a/common/patches/titanium_limits.h +++ b/common/patches/titanium_limits.h @@ -27,107 +27,217 @@ namespace Titanium { - enum : int { Invalid = -1, Null, Safety }; + const int16 IINVALID = -1; + const int16 INULL = 0; - enum : bool { False = false, True = true }; - - // pre-declarations namespace inventory { inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::Titanium; } + const bool ConcatenateInvTypeLimbo = true; + + const bool AllowOverLevelEquipment = false; + + const bool AllowEmptyBagInBag = false; + const bool AllowClickCastFromBag = false; + } /*inventory*/ namespace invtype { inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::Titanium; } - enum : int { InvTypeInvalid = -1, InvTypeBegin }; + namespace enum_ { + enum InventoryTypes : int16 { + typePossessions = INULL, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, + typeTribute, + typeGuildTribute, + typeMerchant, + typeCorpse, + typeBazaar, + typeInspect, + typeViewMODPC, + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, + typeOther + }; - enum InventoryType : int { - InvTypePossessions = InvTypeBegin, - InvTypeBank, - InvTypeSharedBank, - InvTypeTrade, - InvTypeWorld, - InvTypeLimbo, - InvTypeTribute, - InvTypeGuildTribute, - InvTypeMerchant, - InvTypeCorpse, - InvTypeBazaar, - InvTypeInspect, - InvTypeViewMODPC, - InvTypeViewMODBank, - InvTypeViewMODSharedBank, - InvTypeViewMODLimbo, - InvTypeAltStorage, - InvTypeArchived, - InvTypeOther, - InvTypeCount - }; + } // namespace enum_ + using namespace enum_; + + const int16 POSSESSIONS_SIZE = 31; + const int16 BANK_SIZE = 16; + const int16 SHARED_BANK_SIZE = 2; + const int16 TRADE_SIZE = 8; + const int16 WORLD_SIZE = 10; + const int16 LIMBO_SIZE = 36; + const int16 TRIBUTE_SIZE = 5; + const int16 GUILD_TRIBUTE_SIZE = 2; + const int16 MERCHANT_SIZE = 80; + const int16 CORPSE_SIZE = POSSESSIONS_SIZE; + const int16 BAZAAR_SIZE = 80; + const int16 INSPECT_SIZE = 22; + const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE; + const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE; + const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE; + const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE; + const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank" + const int16 ARCHIVED_SIZE = 0;//unknown + const int16 OTHER_SIZE = 0;//unknown + + const int16 TRADE_NPC_SIZE = 4; // defined by implication + + const int16 TYPE_INVALID = IINVALID; + const int16 TYPE_BEGIN = typePossessions; + const int16 TYPE_END = typeOther; + const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1; + + int16 GetInvTypeSize(int16 inv_type); + const char* GetInvTypeName(int16 inv_type); + + bool IsInvTypePersistent(int16 inv_type); } /*invtype*/ namespace invslot { inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::Titanium; } - enum : int { InvSlotInvalid = -1, InvSlotBegin }; + namespace enum_ { + enum InventorySlots : int16 { + slotCharm = INULL, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, + slotAmmo, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotCursor + }; - enum PossessionsSlot : int { - PossessionsCharm = InvSlotBegin, - PossessionsEar1, - PossessionsHead, - PossessionsFace, - PossessionsEar2, - PossessionsNeck, - PossessionsShoulders, - PossessionsArms, - PossessionsBack, - PossessionsWrist1, - PossessionsWrist2, - PossessionsRange, - PossessionsHands, - PossessionsPrimary, - PossessionsSecondary, - PossessionsFinger1, - PossessionsFinger2, - PossessionsChest, - PossessionsLegs, - PossessionsFeet, - PossessionsWaist, - PossessionsAmmo, - PossessionsGeneral1, - PossessionsGeneral2, - PossessionsGeneral3, - PossessionsGeneral4, - PossessionsGeneral5, - PossessionsGeneral6, - PossessionsGeneral7, - PossessionsGeneral8, - PossessionsCursor, - PossessionsCount - }; + } // namespace enum_ + using namespace enum_; - const int EquipmentBegin = PossessionsCharm; - const int EquipmentEnd = PossessionsAmmo; - const int EquipmentCount = (EquipmentEnd - EquipmentBegin + 1); + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; - const int GeneralBegin = PossessionsGeneral1; - const int GeneralEnd = PossessionsGeneral8; - const int GeneralCount = (GeneralEnd - GeneralBegin + 1); + const int16 POSSESSIONS_BEGIN = slotCharm; + const int16 POSSESSIONS_END = slotCursor; + const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; + + const int16 EQUIPMENT_BEGIN = slotCharm; + const int16 EQUIPMENT_END = slotAmmo; + const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN + 1); + + const int16 GENERAL_BEGIN = slotGeneral1; + const int16 GENERAL_END = slotGeneral8; + const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN + 1); + + const int16 BONUS_BEGIN = invslot::slotCharm; + const int16 BONUS_STAT_END = invslot::slotWaist; + const int16 BONUS_SKILL_END = invslot::slotAmmo; + + const int16 BANK_BEGIN = 2000; + const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1; + + const int16 SHARED_BANK_BEGIN = 2500; + const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1; + + const int16 TRADE_BEGIN = 3000; + const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1; + + const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication + + const int16 WORLD_BEGIN = 4000; + const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1; + + const int16 TRIBUTE_BEGIN = 400; + const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1; + + const int16 GUILD_TRIBUTE_BEGIN = 450; + const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor; + + const uint64 POSSESSIONS_BITMASK = 0x000000027FDFFFFF; // based on 34-slot count (RoF+) + const uint64 CORPSE_BITMASK = 0x017FFFFE7F800000; // based on 34-slot count (RoF+) + + const char* GetInvPossessionsSlotName(int16 inv_slot); + const char* GetInvCorpseSlotName(int16 inv_slot); + const char* GetInvSlotName(int16 inv_type, int16 inv_slot); } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::Titanium; } - enum : int { InvBagInvalid = -1, InvBagBegin }; + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; + const int16 SLOT_END = 9; + const int16 SLOT_COUNT = 10; + + const int16 GENERAL_BAGS_BEGIN = 251; + const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT; + const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1; + + const int16 CURSOR_BAG_BEGIN = 331; + const int16 CURSOR_BAG_COUNT = SLOT_COUNT; + const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1; + + const int16 BANK_BAGS_BEGIN = 2031; + const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT); + const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1; + + const int16 SHARED_BANK_BAGS_BEGIN = 2531; + const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT; + const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1; + + const int16 TRADE_BAGS_BEGIN = 3031; + const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT; + const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1; + + const char* GetInvBagIndexName(int16 bag_index); } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::Titanium; } - enum : int { InvAugInvalid = -1, InvAugBegin }; + const int16 SOCKET_INVALID = IINVALID; + const int16 SOCKET_BEGIN = INULL; + const int16 SOCKET_END = 4; + const int16 SOCKET_COUNT = 5; + + const char* GetInvAugIndexName(int16 aug_index); } /*invaug*/ @@ -152,147 +262,21 @@ namespace Titanium namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::Titanium; } + const int16 BANDOLIERS_SIZE = 4; // number of bandolier instances + const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance + + const int16 POTION_BELT_SIZE = 4; + + const int16 SKILL_ARRAY_SIZE = 100; + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::Titanium; } - } /*constants*/ + const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER - namespace behavior { - inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::Titanium; } - - } /*behavior*/ - - namespace skills { - inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::Titanium; } - - } /*skills*/ - - - // declarations - namespace inventory { - const bool ConcatenateInvTypeLimbo = true; - - const bool AllowOverLevelEquipment = false; - - const bool AllowEmptyBagInBag = false; - const bool AllowClickCastFromBag = false; - - } /*inventory*/ - - namespace invtype { - const size_t InvTypePossessionsSize = invslot::PossessionsCount; - const size_t InvTypeBankSize = 16; - const size_t InvTypeSharedBankSize = 2; - const size_t InvTypeTradeSize = 8; - const size_t InvTypeWorldSize = 10; - const size_t InvTypeLimboSize = 36; - const size_t InvTypeTributeSize = 5; - const size_t InvTypeGuildTributeSize = 2; - const size_t InvTypeMerchantSize = 80; - const size_t InvTypeCorpseSize = InvTypePossessionsSize; - const size_t InvTypeBazaarSize = 80; - const size_t InvTypeInspectSize = invslot::EquipmentCount; - const size_t InvTypeViewMODPCSize = InvTypePossessionsSize; - const size_t InvTypeViewMODBankSize = InvTypeBankSize; - const size_t InvTypeViewMODSharedBankSize = InvTypeSharedBankSize; - const size_t InvTypeViewMODLimboSize = InvTypeLimboSize; - const size_t InvTypeAltStorageSize = 0;//unknown - "Shroud Bank" - const size_t InvTypeArchivedSize = 0;//unknown - const size_t InvTypeOtherSize = 0;//unknown - - extern size_t GetInvTypeSize(int inv_type); - extern const char* GetInvTypeName(int inv_type); - - extern bool IsInvTypePersistent(int inv_type); - - } /*invtype*/ - - namespace invslot { - const int BankBegin = 2000; - const int BankEnd = (BankBegin + invtype::InvTypeBankSize) - 1; - - const int SharedBankBegin = 2500; - const int SharedBankEnd = (SharedBankBegin + invtype::InvTypeSharedBankSize) - 1; - - const int TradeBegin = 3000; - const int TradeEnd = (TradeBegin + invtype::InvTypeTradeSize) - 1; - const int TradeNPCEnd = 3003; - - const int WorldBegin = 4000; - const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1; - - const int TributeBegin = 400; - const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1; - - const int GuildTributeBegin = 450; - const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1; - - const int CorpseBegin = PossessionsGeneral1; - const int CorpseEnd = PossessionsGeneral1 + PossessionsCursor; - - extern const char* GetInvPossessionsSlotName(int inv_slot); - extern const char* GetInvCorpseSlotName(int inv_slot); - extern const char* GetInvSlotName(int inv_type, int inv_slot); - - } /*invslot*/ - - namespace invbag { - const size_t ItemBagSize = 10; - - const int GeneralBagsBegin = 251; - const int GeneralBagsSize = invslot::GeneralCount * ItemBagSize; - const int GeneralBagsEnd = (GeneralBagsBegin + GeneralBagsSize) - 1; - - const int CursorBagBegin = 331; - const int CursorBagSize = ItemBagSize; - const int CursorBagEnd = (CursorBagBegin + CursorBagSize) - 1; - - const int BankBagsBegin = 2031; - const int BankBagsSize = (invtype::InvTypeBankSize * ItemBagSize); - const int BankBagsEnd = (BankBagsBegin + BankBagsSize) - 1; - - const int SharedBankBagsBegin = 2531; - const int SharedBankBagsSize = invtype::InvTypeSharedBankSize * ItemBagSize; - const int SharedBankBagsEnd = (SharedBankBagsBegin + SharedBankBagsSize) - 1; - - const int TradeBagsBegin = 3031; - const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize; - const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1; - - extern const char* GetInvBagIndexName(int bag_index); - - } /*invbag*/ - - namespace invaug { - const size_t ItemAugSize = 5; - - extern const char* GetInvAugIndexName(int aug_index); - - } /*invaug*/ - - namespace item { - - } /*item*/ - - namespace profile { - const size_t TributeSize = invtype::InvTypeTributeSize; - const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize; - - const size_t BandoliersSize = 4; // number of bandolier instances - const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance - - const size_t PotionBeltSize = 4; - - const size_t SkillArraySize = 100; - - } /*profile*/ - - namespace constants { - const size_t CharacterCreationLimit = 8; // Hard-coded in client - DO NOT ALTER - - const size_t SayLinkBodySize = 45; + const size_t SAY_LINK_BODY_SIZE = 45; const int LongBuffs = 25; const int ShortBuffs = 12; @@ -305,11 +289,15 @@ namespace Titanium } /*constants*/ namespace behavior { + inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::Titanium; } + const bool CoinHasWeight = true; } /*behavior*/ namespace skills { + inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::Titanium; } + const size_t LastUsableSkill = EQEmu::skills::SkillFrenzy; } /*skills*/ diff --git a/common/patches/titanium_structs.h b/common/patches/titanium_structs.h index 9f2d9423d..8cf202e31 100644 --- a/common/patches/titanium_structs.h +++ b/common/patches/titanium_structs.h @@ -655,7 +655,7 @@ struct BandolierItem_Struct struct Bandolier_Struct { char Name[32]; - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; //len = 72 @@ -669,7 +669,7 @@ struct PotionBeltItem_Struct //len = 288 struct PotionBelt_Struct { - PotionBeltItem_Struct Items[profile::PotionBeltSize]; + PotionBeltItem_Struct Items[profile::POTION_BELT_SIZE]; }; static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16; @@ -875,7 +875,7 @@ struct PlayerProfile_Struct /*06152*/ uint32 aapoints_spent; // Number of spent AA points /*06156*/ uint32 aapoints; // Unspent AA points /*06160*/ uint8 unknown06160[4]; -/*06164*/ Bandolier_Struct bandoliers[profile::BandoliersSize]; // bandolier contents +/*06164*/ Bandolier_Struct bandoliers[profile::BANDOLIERS_SIZE]; // bandolier contents /*07444*/ uint8 unknown07444[5120]; /*12564*/ PotionBelt_Struct potionbelt; // potion belt /*12852*/ uint8 unknown12852[8]; diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 79fdca333..869685e47 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -1609,117 +1609,6 @@ namespace UF FINISH_ENCODE(); } - ENCODE(OP_OpenNewTasksWindow) - { - AvailableTaskHeader_Struct* __emu_AvailableTaskHeader; - AvailableTaskData1_Struct* __emu_AvailableTaskData1; - AvailableTaskData2_Struct* __emu_AvailableTaskData2; - AvailableTaskTrailer_Struct* __emu_AvailableTaskTrailer; - - structs::AvailableTaskHeader_Struct* __eq_AvailableTaskHeader; - structs::AvailableTaskData1_Struct* __eq_AvailableTaskData1; - structs::AvailableTaskData2_Struct* __eq_AvailableTaskData2; - structs::AvailableTaskTrailer_Struct* __eq_AvailableTaskTrailer; - - EQApplicationPacket *in = *p; - *p = nullptr; - - unsigned char *__emu_buffer = in->pBuffer; - - __emu_AvailableTaskHeader = (AvailableTaskHeader_Struct*)__emu_buffer; - - // For each task, SoF has an extra uint32 and what appears to be space for a null terminated string. - // - in->size = in->size + (__emu_AvailableTaskHeader->TaskCount * 5); - in->pBuffer = new unsigned char[in->size]; - - unsigned char *__eq_buffer = in->pBuffer; - - __eq_AvailableTaskHeader = (structs::AvailableTaskHeader_Struct*)__eq_buffer; - - char *__eq_ptr, *__emu_Ptr; - - // Copy Header - // - // - - __eq_AvailableTaskHeader->TaskCount = __emu_AvailableTaskHeader->TaskCount; - __eq_AvailableTaskHeader->unknown1 = __emu_AvailableTaskHeader->unknown1; - __eq_AvailableTaskHeader->TaskGiver = __emu_AvailableTaskHeader->TaskGiver; - - __emu_Ptr = (char *)__emu_AvailableTaskHeader + sizeof(AvailableTaskHeader_Struct); - __eq_ptr = (char *)__eq_AvailableTaskHeader + sizeof(structs::AvailableTaskHeader_Struct); - - for (uint32 i = 0; i<__emu_AvailableTaskHeader->TaskCount; i++) { - - __emu_AvailableTaskData1 = (AvailableTaskData1_Struct*)__emu_Ptr; - __eq_AvailableTaskData1 = (structs::AvailableTaskData1_Struct*)__eq_ptr; - - __eq_AvailableTaskData1->TaskID = __emu_AvailableTaskData1->TaskID; - // This next unknown seems to affect the colour of the task title. 0x3f80000 is what I have seen - // in Underfoot packets. Changing it to 0x3f000000 makes the title red. - __eq_AvailableTaskData1->unknown1 = 0x3f800000; - __eq_AvailableTaskData1->TimeLimit = __emu_AvailableTaskData1->TimeLimit; - __eq_AvailableTaskData1->unknown2 = __emu_AvailableTaskData1->unknown2; - - __emu_Ptr += sizeof(AvailableTaskData1_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData1_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Title - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Description - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __eq_ptr[0] = 0; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskData2 = (AvailableTaskData2_Struct*)__emu_Ptr; - __eq_AvailableTaskData2 = (structs::AvailableTaskData2_Struct*)__eq_ptr; - - __eq_AvailableTaskData2->unknown1 = __emu_AvailableTaskData2->unknown1; - __eq_AvailableTaskData2->unknown2 = __emu_AvailableTaskData2->unknown2; - __eq_AvailableTaskData2->unknown3 = __emu_AvailableTaskData2->unknown3; - __eq_AvailableTaskData2->unknown4 = __emu_AvailableTaskData2->unknown4; - - __emu_Ptr += sizeof(AvailableTaskData2_Struct); - __eq_ptr += sizeof(structs::AvailableTaskData2_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - - __emu_AvailableTaskTrailer = (AvailableTaskTrailer_Struct*)__emu_Ptr; - __eq_AvailableTaskTrailer = (structs::AvailableTaskTrailer_Struct*)__eq_ptr; - - __eq_AvailableTaskTrailer->ItemCount = __emu_AvailableTaskTrailer->ItemCount; - __eq_AvailableTaskTrailer->unknown1 = __emu_AvailableTaskTrailer->unknown1; - __eq_AvailableTaskTrailer->unknown2 = __emu_AvailableTaskTrailer->unknown2; - __eq_AvailableTaskTrailer->StartZone = __emu_AvailableTaskTrailer->StartZone; - - __emu_Ptr += sizeof(AvailableTaskTrailer_Struct); - __eq_ptr += sizeof(structs::AvailableTaskTrailer_Struct); - - strcpy(__eq_ptr, __emu_Ptr); // Unknown string - - __emu_Ptr += strlen(__emu_Ptr) + 1; - __eq_ptr += strlen(__eq_ptr) + 1; - } - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); - } - ENCODE(OP_PetBuffWindow) { EQApplicationPacket *in = *p; @@ -1881,18 +1770,18 @@ namespace UF // OUT(unknown06160[4]); // Copy bandoliers where server and client indexes converge - for (r = 0; r < EQEmu::legacy::BANDOLIERS_SIZE && r < profile::BandoliersSize; ++r) { + for (r = 0; r < EQEmu::profile::BANDOLIERS_SIZE && r < profile::BANDOLIERS_SIZE; ++r) { OUT_str(bandoliers[r].Name); - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true OUT(bandoliers[r].Items[k].ID); OUT(bandoliers[r].Items[k].Icon); OUT_str(bandoliers[r].Items[k].Name); } } // Nullify bandoliers where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::BANDOLIERS_SIZE; r < profile::BandoliersSize; ++r) { + for (r = EQEmu::profile::BANDOLIERS_SIZE; r < profile::BANDOLIERS_SIZE; ++r) { eq->bandoliers[r].Name[0] = '\0'; - for (uint32 k = 0; k < profile::BandolierItemCount; ++k) { // Will need adjusting if 'server != client' is ever true + for (uint32 k = 0; k < profile::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true eq->bandoliers[r].Items[k].ID = 0; eq->bandoliers[r].Items[k].Icon = 0; eq->bandoliers[r].Items[k].Name[0] = '\0'; @@ -1902,13 +1791,13 @@ namespace UF // OUT(unknown07444[5120]); // Copy potion belt where server and client indexes converge - for (r = 0; r < EQEmu::legacy::POTION_BELT_ITEM_COUNT && r < profile::PotionBeltSize; ++r) { + for (r = 0; r < EQEmu::profile::POTION_BELT_SIZE && r < profile::POTION_BELT_SIZE; ++r) { OUT(potionbelt.Items[r].ID); OUT(potionbelt.Items[r].Icon); OUT_str(potionbelt.Items[r].Name); } // Nullify potion belt where server and client indexes diverge, with a client bias - for (r = EQEmu::legacy::POTION_BELT_ITEM_COUNT; r < profile::PotionBeltSize; ++r) { + for (r = EQEmu::profile::POTION_BELT_SIZE; r < profile::POTION_BELT_SIZE; ++r) { eq->potionbelt.Items[r].ID = 0; eq->potionbelt.Items[r].Icon = 0; eq->potionbelt.Items[r].Name[0] = '\0'; @@ -2217,8 +2106,8 @@ namespace UF eq->CharCount = emu->CharCount; eq->TotalChars = emu->TotalChars; - if (eq->TotalChars > constants::CharacterCreationLimit) - eq->TotalChars = constants::CharacterCreationLimit; + if (eq->TotalChars > constants::CHARACTER_CREATION_LIMIT) + eq->TotalChars = constants::CHARACTER_CREATION_LIMIT; // Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars' uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field @@ -2234,7 +2123,7 @@ namespace UF size_t names_length = 0; size_t character_count = 0; - for (; character_count < emu->CharCount && character_count < constants::CharacterCreationLimit; ++character_count) { + for (; character_count < emu->CharCount && character_count < constants::CHARACTER_CREATION_LIMIT; ++character_count) { emu_cse = (CharacterSelectEntry_Struct *)emu_ptr; names_length += strlen(emu_cse->Name); emu_ptr += sizeof(CharacterSelectEntry_Struct); @@ -2250,8 +2139,8 @@ namespace UF eq->CharCount = character_count; eq->TotalChars = emu->TotalChars; - if (eq->TotalChars > constants::CharacterCreationLimit) - eq->TotalChars = constants::CharacterCreationLimit; + if (eq->TotalChars > constants::CHARACTER_CREATION_LIMIT) + eq->TotalChars = constants::CHARACTER_CREATION_LIMIT; // Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars' in this client uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field @@ -2528,13 +2417,16 @@ namespace UF InBuffer += description_size; InBuffer += sizeof(TaskDescriptionData2_Struct); - std::string old_message = InBuffer; // start 'Reward' as string + uint32 reward_size = strlen(InBuffer) + 1; + InBuffer += reward_size; + + std::string old_message = InBuffer; // start item link string std::string new_message; ServerToUFSayLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ - title_size + description_size + new_message.length() + 1; + title_size + description_size + reward_size + new_message.length() + 1; in->pBuffer = new unsigned char[in->size]; @@ -3918,7 +3810,7 @@ namespace UF ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; ibs.size = item->Size; - ibs.slots = SwapBits21and22(item->Slots); + ibs.slots = SwapBits21And22(item->Slots); ibs.price = item->Price; ibs.icon = item->Icon; ibs.unknown1 = 1; @@ -4008,7 +3900,7 @@ namespace UF isbs.augtype = item->AugType; isbs.augrestrict = item->AugRestrict; - for (int index = 0; index < invaug::ItemAugSize; ++index) { + for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) { isbs.augslots[index].type = item->AugSlotType[index]; isbs.augslots[index].visible = item->AugSlotVisible[index]; isbs.augslots[index].unknown = item->AugSlotUnk2[index]; @@ -4204,18 +4096,18 @@ namespace UF ob.write((const char*)&subitem_count, sizeof(uint32)); - for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) { + for (uint32 index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) { EQEmu::ItemInstance* sub = inst->GetItem(index); if (!sub) continue; int SubSlotNumber = INVALID_INDEX; - if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END) - SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1); - else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index); - else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END) - SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index); + if (slot_id_in >= EQEmu::invslot::GENERAL_BEGIN && slot_id_in <= EQEmu::invslot::GENERAL_END) + SubSlotNumber = (((slot_id_in + 3) * EQEmu::invbag::SLOT_COUNT) + index + 1); + else if (slot_id_in >= EQEmu::invslot::BANK_BEGIN && slot_id_in <= EQEmu::invslot::BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::BANK_BAGS_BEGIN + index); + else if (slot_id_in >= EQEmu::invslot::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::invslot::SHARED_BANK_END) + SubSlotNumber = (((slot_id_in - EQEmu::invslot::SHARED_BANK_BEGIN) * EQEmu::invbag::SLOT_COUNT) + EQEmu::invbag::SHARED_BANK_BAGS_BEGIN + index); else SubSlotNumber = slot_id_in; @@ -4233,16 +4125,16 @@ namespace UF { uint32 UnderfootSlot = 0; - if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots + if (serverSlot >= EQEmu::invslot::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots UnderfootSlot = serverSlot + 1; - else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) + else if (serverSlot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::invbag::CURSOR_BAG_END) UnderfootSlot = serverSlot + 11; - else if (serverSlot >= EQEmu::legacy::BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::BANK_BAGS_END) + else if (serverSlot >= EQEmu::invbag::BANK_BAGS_BEGIN && serverSlot <= EQEmu::invbag::BANK_BAGS_END) UnderfootSlot = serverSlot + 1; - else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END) + else if (serverSlot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::invbag::SHARED_BANK_BAGS_END) UnderfootSlot = serverSlot + 1; - else if (serverSlot == EQEmu::inventory::slotPowerSource) - UnderfootSlot = invslot::PossessionsPowerSource; + else if (serverSlot == EQEmu::invslot::SLOT_POWER_SOURCE) + UnderfootSlot = invslot::slotPowerSource; else UnderfootSlot = serverSlot; @@ -4259,16 +4151,16 @@ namespace UF { uint32 ServerSlot = 0; - if (ufSlot >= invslot::PossessionsAmmo && ufSlot <= invslot::CorpseEnd) // Cursor/Ammo/Power Source and Normal Inventory Slots + if (ufSlot >= invslot::slotAmmo && ufSlot <= invslot::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots ServerSlot = ufSlot - 1; - else if (ufSlot >= invbag::GeneralBagsBegin && ufSlot <= invbag::CursorBagEnd) + else if (ufSlot >= invbag::GENERAL_BAGS_BEGIN && ufSlot <= invbag::CURSOR_BAG_END) ServerSlot = ufSlot - 11; - else if (ufSlot >= invbag::BankBagsBegin && ufSlot <= invbag::BankBagsEnd) + else if (ufSlot >= invbag::BANK_BAGS_BEGIN && ufSlot <= invbag::BANK_BAGS_END) ServerSlot = ufSlot - 1; - else if (ufSlot >= invbag::SharedBankBagsBegin && ufSlot <= invbag::SharedBankBagsEnd) + else if (ufSlot >= invbag::SHARED_BANK_BAGS_BEGIN && ufSlot <= invbag::SHARED_BANK_BAGS_END) ServerSlot = ufSlot - 1; - else if (ufSlot == invslot::PossessionsPowerSource) - ServerSlot = EQEmu::inventory::slotPowerSource; + else if (ufSlot == invslot::slotPowerSource) + ServerSlot = EQEmu::invslot::SLOT_POWER_SOURCE; else ServerSlot = ufSlot; @@ -4283,7 +4175,7 @@ namespace UF static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink) { - if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) { + if ((constants::SAY_LINK_BODY_SIZE == EQEmu::constants::SAY_LINK_BODY_SIZE) || (serverSayLink.find('\x12') == std::string::npos)) { ufSayLink = serverSayLink; return; } @@ -4292,7 +4184,7 @@ namespace UF for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= EQEmu::constants::SAY_LINK_BODY_SIZE) { ufSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; @@ -4323,7 +4215,7 @@ namespace UF static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink) { - if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (ufSayLink.find('\x12') == std::string::npos)) { + if ((EQEmu::constants::SAY_LINK_BODY_SIZE == constants::SAY_LINK_BODY_SIZE) || (ufSayLink.find('\x12') == std::string::npos)) { serverSayLink = ufSayLink; return; } @@ -4332,7 +4224,7 @@ namespace UF for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { - if (segments[segment_iter].length() <= constants::SayLinkBodySize) { + if (segments[segment_iter].length() <= constants::SAY_LINK_BODY_SIZE) { serverSayLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; diff --git a/common/patches/uf_limits.cpp b/common/patches/uf_limits.cpp index ae415ddd8..7cf5ec63e 100644 --- a/common/patches/uf_limits.cpp +++ b/common/patches/uf_limits.cpp @@ -22,198 +22,198 @@ #include "../string_util.h" -size_t UF::invtype::GetInvTypeSize(int inv_type) +int16 UF::invtype::GetInvTypeSize(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - return invtype::InvTypePossessionsSize; - case invtype::InvTypeBank: - return invtype::InvTypeBankSize; - case invtype::InvTypeSharedBank: - return invtype::InvTypeSharedBankSize; - case invtype::InvTypeTrade: - return invtype::InvTypeTradeSize; - case invtype::InvTypeWorld: - return invtype::InvTypeWorldSize; - case invtype::InvTypeLimbo: - return invtype::InvTypeLimboSize; - case invtype::InvTypeTribute: - return invtype::InvTypeTributeSize; - case invtype::InvTypeGuildTribute: - return invtype::InvTypeGuildTributeSize; - case invtype::InvTypeMerchant: - return invtype::InvTypeMerchantSize; - case invtype::InvTypeCorpse: - return invtype::InvTypeCorpseSize; - case invtype::InvTypeBazaar: - return invtype::InvTypeBazaarSize; - case invtype::InvTypeInspect: - return invtype::InvTypeInspectSize; - case invtype::InvTypeViewMODPC: - return invtype::InvTypeViewMODPCSize; - case invtype::InvTypeViewMODBank: - return invtype::InvTypeViewMODBankSize; - case invtype::InvTypeViewMODSharedBank: - return invtype::InvTypeViewMODSharedBankSize; - case invtype::InvTypeViewMODLimbo: - return invtype::InvTypeViewMODLimboSize; - case invtype::InvTypeAltStorage: - return invtype::InvTypeAltStorageSize; - case invtype::InvTypeArchived: - return invtype::InvTypeArchivedSize; - case invtype::InvTypeOther: - return invtype::InvTypeOtherSize; + case invtype::typePossessions: + return invtype::POSSESSIONS_SIZE; + case invtype::typeBank: + return invtype::BANK_SIZE; + case invtype::typeSharedBank: + return invtype::SHARED_BANK_SIZE; + case invtype::typeTrade: + return invtype::TRADE_SIZE; + case invtype::typeWorld: + return invtype::WORLD_SIZE; + case invtype::typeLimbo: + return invtype::LIMBO_SIZE; + case invtype::typeTribute: + return invtype::TRIBUTE_SIZE; + case invtype::typeGuildTribute: + return invtype::GUILD_TRIBUTE_SIZE; + case invtype::typeMerchant: + return invtype::MERCHANT_SIZE; + case invtype::typeCorpse: + return invtype::CORPSE_SIZE; + case invtype::typeBazaar: + return invtype::BAZAAR_SIZE; + case invtype::typeInspect: + return invtype::INSPECT_SIZE; + case invtype::typeViewMODPC: + return invtype::VIEW_MOD_PC_SIZE; + case invtype::typeViewMODBank: + return invtype::VIEW_MOD_BANK_SIZE; + case invtype::typeViewMODSharedBank: + return invtype::VIEW_MOD_SHARED_BANK_SIZE; + case invtype::typeViewMODLimbo: + return invtype::VIEW_MOD_LIMBO_SIZE; + case invtype::typeAltStorage: + return invtype::ALT_STORAGE_SIZE; + case invtype::typeArchived: + return invtype::ARCHIVED_SIZE; + case invtype::typeOther: + return invtype::OTHER_SIZE; default: - return 0; + return INULL; } } -const char* UF::invtype::GetInvTypeName(int inv_type) +const char* UF::invtype::GetInvTypeName(int16 inv_type) { switch (inv_type) { - case invtype::InvTypeInvalid: + case invtype::TYPE_INVALID: return "Invalid Type"; - case invtype::InvTypePossessions: + case invtype::typePossessions: return "Possessions"; - case invtype::InvTypeBank: + case invtype::typeBank: return "Bank"; - case invtype::InvTypeSharedBank: + case invtype::typeSharedBank: return "Shared Bank"; - case invtype::InvTypeTrade: + case invtype::typeTrade: return "Trade"; - case invtype::InvTypeWorld: + case invtype::typeWorld: return "World"; - case invtype::InvTypeLimbo: + case invtype::typeLimbo: return "Limbo"; - case invtype::InvTypeTribute: + case invtype::typeTribute: return "Tribute"; - case invtype::InvTypeGuildTribute: + case invtype::typeGuildTribute: return "Guild Tribute"; - case invtype::InvTypeMerchant: + case invtype::typeMerchant: return "Merchant"; - case invtype::InvTypeCorpse: + case invtype::typeCorpse: return "Corpse"; - case invtype::InvTypeBazaar: + case invtype::typeBazaar: return "Bazaar"; - case invtype::InvTypeInspect: + case invtype::typeInspect: return "Inspect"; - case invtype::InvTypeViewMODPC: + case invtype::typeViewMODPC: return "View MOD PC"; - case invtype::InvTypeViewMODBank: + case invtype::typeViewMODBank: return "View MOD Bank"; - case invtype::InvTypeViewMODSharedBank: + case invtype::typeViewMODSharedBank: return "View MOD Shared Bank"; - case invtype::InvTypeViewMODLimbo: + case invtype::typeViewMODLimbo: return "View MOD Limbo"; - case invtype::InvTypeAltStorage: + case invtype::typeAltStorage: return "Alt Storage"; - case invtype::InvTypeArchived: + case invtype::typeArchived: return "Archived"; - case invtype::InvTypeOther: + case invtype::typeOther: return "Other"; default: return "Unknown Type"; } } -bool UF::invtype::IsInvTypePersistent(int inv_type) +bool UF::invtype::IsInvTypePersistent(int16 inv_type) { switch (inv_type) { - case invtype::InvTypePossessions: - case invtype::InvTypeBank: - case invtype::InvTypeSharedBank: - case invtype::InvTypeTrade: - case invtype::InvTypeWorld: - case invtype::InvTypeLimbo: - case invtype::InvTypeTribute: - case invtype::InvTypeGuildTribute: + case invtype::typePossessions: + case invtype::typeBank: + case invtype::typeSharedBank: + case invtype::typeTrade: + case invtype::typeWorld: + case invtype::typeLimbo: + case invtype::typeTribute: + case invtype::typeGuildTribute: return true; default: return false; } } -const char* UF::invslot::GetInvPossessionsSlotName(int inv_slot) +const char* UF::invslot::GetInvPossessionsSlotName(int16 inv_slot) { switch (inv_slot) { - case invslot::InvSlotInvalid: + case invslot::SLOT_INVALID: return "Invalid Slot"; - case invslot::PossessionsCharm: + case invslot::slotCharm: return "Charm"; - case invslot::PossessionsEar1: + case invslot::slotEar1: return "Ear 1"; - case invslot::PossessionsHead: + case invslot::slotHead: return "Head"; - case invslot::PossessionsFace: + case invslot::slotFace: return "Face"; - case invslot::PossessionsEar2: + case invslot::slotEar2: return "Ear 2"; - case invslot::PossessionsNeck: + case invslot::slotNeck: return "Neck"; - case invslot::PossessionsShoulders: + case invslot::slotShoulders: return "Shoulders"; - case invslot::PossessionsArms: + case invslot::slotArms: return "Arms"; - case invslot::PossessionsBack: + case invslot::slotBack: return "Back"; - case invslot::PossessionsWrist1: + case invslot::slotWrist1: return "Wrist 1"; - case invslot::PossessionsWrist2: + case invslot::slotWrist2: return "Wrist 2"; - case invslot::PossessionsRange: + case invslot::slotRange: return "Range"; - case invslot::PossessionsHands: + case invslot::slotHands: return "Hands"; - case invslot::PossessionsPrimary: + case invslot::slotPrimary: return "Primary"; - case invslot::PossessionsSecondary: + case invslot::slotSecondary: return "Secondary"; - case invslot::PossessionsFinger1: + case invslot::slotFinger1: return "Finger 1"; - case invslot::PossessionsFinger2: + case invslot::slotFinger2: return "Finger 2"; - case invslot::PossessionsChest: + case invslot::slotChest: return "Chest"; - case invslot::PossessionsLegs: + case invslot::slotLegs: return "Legs"; - case invslot::PossessionsFeet: + case invslot::slotFeet: return "Feet"; - case invslot::PossessionsWaist: + case invslot::slotWaist: return "Waist"; - case invslot::PossessionsPowerSource: + case invslot::slotPowerSource: return "Power Source"; - case invslot::PossessionsAmmo: + case invslot::slotAmmo: return "Ammo"; - case invslot::PossessionsGeneral1: + case invslot::slotGeneral1: return "General 1"; - case invslot::PossessionsGeneral2: + case invslot::slotGeneral2: return "General 2"; - case invslot::PossessionsGeneral3: + case invslot::slotGeneral3: return "General 3"; - case invslot::PossessionsGeneral4: + case invslot::slotGeneral4: return "General 4"; - case invslot::PossessionsGeneral5: + case invslot::slotGeneral5: return "General 5"; - case invslot::PossessionsGeneral6: + case invslot::slotGeneral6: return "General 6"; - case invslot::PossessionsGeneral7: + case invslot::slotGeneral7: return "General 7"; - case invslot::PossessionsGeneral8: + case invslot::slotGeneral8: return "General 8"; - case invslot::PossessionsCursor: + case invslot::slotCursor: return "Cursor"; default: return "Unknown Slot"; } } -const char* UF::invslot::GetInvCorpseSlotName(int inv_slot) +const char* UF::invslot::GetInvCorpseSlotName(int16 inv_slot) { - if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid) + if (!invtype::GetInvTypeSize(invtype::typeCorpse) || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; // needs work - if ((size_t)(inv_slot + 1) < invslot::CorpseBegin || (size_t)(inv_slot + 1) >= invslot::CorpseEnd) + if ((inv_slot + 1) < invslot::CORPSE_BEGIN || (inv_slot + 1) >= invslot::CORPSE_END) return "Unknown Slot"; static std::string ret_str; @@ -222,19 +222,19 @@ const char* UF::invslot::GetInvCorpseSlotName(int inv_slot) return ret_str.c_str(); } -const char* UF::invslot::GetInvSlotName(int inv_type, int inv_slot) +const char* UF::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot) { - if (inv_type == invtype::InvTypePossessions) + if (inv_type == invtype::typePossessions) return invslot::GetInvPossessionsSlotName(inv_slot); - else if (inv_type == invtype::InvTypeCorpse) + else if (inv_type == invtype::typeCorpse) return invslot::GetInvCorpseSlotName(inv_slot); - size_t type_size = invtype::GetInvTypeSize(inv_type); + int16 type_size = invtype::GetInvTypeSize(inv_type); - if (!type_size || inv_slot == invslot::InvSlotInvalid) + if (!type_size || inv_slot == invslot::SLOT_INVALID) return "Invalid Slot"; - if ((size_t)(inv_slot + 1) >= type_size) + if ((inv_slot + 1) >= type_size) return "Unknown Slot"; static std::string ret_str; @@ -243,12 +243,12 @@ const char* UF::invslot::GetInvSlotName(int inv_type, int inv_slot) return ret_str.c_str(); } -const char* UF::invbag::GetInvBagIndexName(int bag_index) +const char* UF::invbag::GetInvBagIndexName(int16 bag_index) { - if (bag_index == invbag::InvBagInvalid) + if (bag_index == invbag::SLOT_INVALID) return "Invalid Bag"; - if ((size_t)bag_index >= invbag::ItemBagSize) + if (bag_index >= invbag::SLOT_COUNT) return "Unknown Bag"; static std::string ret_str; @@ -257,12 +257,12 @@ const char* UF::invbag::GetInvBagIndexName(int bag_index) return ret_str.c_str(); } -const char* UF::invaug::GetInvAugIndexName(int aug_index) +const char* UF::invaug::GetInvAugIndexName(int16 aug_index) { - if (aug_index == invaug::InvAugInvalid) + if (aug_index == invaug::SOCKET_INVALID) return "Invalid Augment"; - if ((size_t)aug_index >= invaug::ItemAugSize) + if (aug_index >= invaug::SOCKET_COUNT) return "Unknown Augment"; static std::string ret_str; diff --git a/common/patches/uf_limits.h b/common/patches/uf_limits.h index 719fcc394..52924f94d 100644 --- a/common/patches/uf_limits.h +++ b/common/patches/uf_limits.h @@ -27,109 +27,219 @@ namespace UF { - enum : int { Invalid = -1, Null, Safety }; + const int16 IINVALID = -1; + const int16 INULL = 0; - enum : bool { False = false, True = true }; - - // pre-declarations namespace inventory { inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::UF; } + const bool ConcatenateInvTypeLimbo = true; + + const bool AllowOverLevelEquipment = true; + + const bool AllowEmptyBagInBag = false; + const bool AllowClickCastFromBag = false; + } /*inventory*/ namespace invtype { inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::UF; } - enum : int { InvTypeInvalid = -1, InvTypeBegin }; + namespace enum_ { + enum InventoryTypes : int16 { + typePossessions = INULL, + typeBank, + typeSharedBank, + typeTrade, + typeWorld, + typeLimbo, + typeTribute, + typeGuildTribute, + typeMerchant, + typeCorpse, + typeBazaar, + typeInspect, + typeViewMODPC, + typeViewMODBank, + typeViewMODSharedBank, + typeViewMODLimbo, + typeAltStorage, + typeArchived, + typeOther + }; - enum InventoryType : int { - InvTypePossessions = InvTypeBegin, - InvTypeBank, - InvTypeSharedBank, - InvTypeTrade, - InvTypeWorld, - InvTypeLimbo, - InvTypeTribute, - InvTypeGuildTribute, - InvTypeMerchant, - InvTypeCorpse, - InvTypeBazaar, - InvTypeInspect, - InvTypeViewMODPC, - InvTypeViewMODBank, - InvTypeViewMODSharedBank, - InvTypeViewMODLimbo, - InvTypeAltStorage, - InvTypeArchived, - InvTypeOther, - InvTypeCount - }; + } // namespace enum_ + using namespace enum_; + + const int16 POSSESSIONS_SIZE = 32; + const int16 BANK_SIZE = 24; + const int16 SHARED_BANK_SIZE = 2; + const int16 TRADE_SIZE = 8; + const int16 WORLD_SIZE = 10; + const int16 LIMBO_SIZE = 36; + const int16 TRIBUTE_SIZE = 5; + const int16 GUILD_TRIBUTE_SIZE = 2; + const int16 MERCHANT_SIZE = 80; + const int16 CORPSE_SIZE = POSSESSIONS_SIZE; + const int16 BAZAAR_SIZE = 80; + const int16 INSPECT_SIZE = 23; + const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE; + const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE; + const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE; + const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE; + const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank" + const int16 ARCHIVED_SIZE = 0;//unknown + const int16 OTHER_SIZE = 0;//unknown + + const int16 TRADE_NPC_SIZE = 4; // defined by implication + + const int16 TYPE_INVALID = IINVALID; + const int16 TYPE_BEGIN = typePossessions; + const int16 TYPE_END = typeOther; + const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1; + + int16 GetInvTypeSize(int16 inv_type); + const char* GetInvTypeName(int16 inv_type); + + bool IsInvTypePersistent(int16 inv_type); } /*invtype*/ namespace invslot { inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::UF; } - enum : int { InvSlotInvalid = -1, InvSlotBegin }; + namespace enum_ { + enum InventorySlots : int16 { + slotCharm = INULL, + slotEar1, + slotHead, + slotFace, + slotEar2, + slotNeck, + slotShoulders, + slotArms, + slotBack, + slotWrist1, + slotWrist2, + slotRange, + slotHands, + slotPrimary, + slotSecondary, + slotFinger1, + slotFinger2, + slotChest, + slotLegs, + slotFeet, + slotWaist, + slotPowerSource, + slotAmmo, + slotGeneral1, + slotGeneral2, + slotGeneral3, + slotGeneral4, + slotGeneral5, + slotGeneral6, + slotGeneral7, + slotGeneral8, + slotCursor + }; - enum PossessionsSlot : int { - PossessionsCharm = InvSlotBegin, - PossessionsEar1, - PossessionsHead, - PossessionsFace, - PossessionsEar2, - PossessionsNeck, - PossessionsShoulders, - PossessionsArms, - PossessionsBack, - PossessionsWrist1, - PossessionsWrist2, - PossessionsRange, - PossessionsHands, - PossessionsPrimary, - PossessionsSecondary, - PossessionsFinger1, - PossessionsFinger2, - PossessionsChest, - PossessionsLegs, - PossessionsFeet, - PossessionsWaist, - PossessionsPowerSource, - PossessionsAmmo, - PossessionsGeneral1, - PossessionsGeneral2, - PossessionsGeneral3, - PossessionsGeneral4, - PossessionsGeneral5, - PossessionsGeneral6, - PossessionsGeneral7, - PossessionsGeneral8, - PossessionsCursor, - PossessionsCount - }; + } // namespace enum_ + using namespace enum_; - const int EquipmentBegin = PossessionsCharm; - const int EquipmentEnd = PossessionsAmmo; - const int EquipmentCount = (EquipmentEnd - EquipmentBegin + 1); + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; - const int GeneralBegin = PossessionsGeneral1; - const int GeneralEnd = PossessionsGeneral8; - const int GeneralCount = (GeneralEnd - GeneralBegin + 1); + const int16 POSSESSIONS_BEGIN = slotCharm; + const int16 POSSESSIONS_END = slotCursor; + const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; + + const int16 EQUIPMENT_BEGIN = slotCharm; + const int16 EQUIPMENT_END = slotAmmo; + const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN + 1); + + const int16 GENERAL_BEGIN = slotGeneral1; + const int16 GENERAL_END = slotGeneral8; + const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN + 1); + + const int16 BONUS_BEGIN = invslot::slotCharm; + const int16 BONUS_STAT_END = invslot::slotPowerSource; + const int16 BONUS_SKILL_END = invslot::slotAmmo; + + const int16 BANK_BEGIN = 2000; + const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1; + + const int16 SHARED_BANK_BEGIN = 2500; + const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1; + + const int16 TRADE_BEGIN = 3000; + const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1; + + const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication + + const int16 WORLD_BEGIN = 4000; + const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1; + + const int16 TRIBUTE_BEGIN = 400; + const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1; + + const int16 GUILD_TRIBUTE_BEGIN = 450; + const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1; + + const int16 CORPSE_BEGIN = invslot::slotGeneral1; + const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor; + + const uint64 POSSESSIONS_BITMASK = 0x000000027FFFFFFF; // based on 34-slot count (RoF+) + const uint64 CORPSE_BITMASK = 0x01FFFFFE7F800000; // based on 34-slot count (RoF+) + + const char* GetInvPossessionsSlotName(int16 inv_slot); + const char* GetInvCorpseSlotName(int16 inv_slot); + const char* GetInvSlotName(int16 inv_type, int16 inv_slot); } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::UF; } - enum : int { InvBagInvalid = -1, InvBagBegin }; + const int16 SLOT_INVALID = IINVALID; + const int16 SLOT_BEGIN = INULL; + const int16 SLOT_END = 9; + const int16 SLOT_COUNT = 10; + + const int16 GENERAL_BAGS_BEGIN = 262; + const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT; + const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1; + + const int16 CURSOR_BAG_BEGIN = 342; + const int16 CURSOR_BAG_COUNT = SLOT_COUNT; + const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1; + + const int16 BANK_BAGS_BEGIN = 2032; + const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT); + const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1; + + const int16 SHARED_BANK_BAGS_BEGIN = 2532; + const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT; + const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1; + + const int16 TRADE_BAGS_BEGIN = 3031; + const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT; + const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1; + + const char* GetInvBagIndexName(int16 bag_index); } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::UF; } - enum : int { InvAugInvalid = -1, InvAugBegin }; + const int16 SOCKET_INVALID = IINVALID; + const int16 SOCKET_BEGIN = INULL; + const int16 SOCKET_END = 4; + const int16 SOCKET_COUNT = 5; + const char* GetInvAugIndexName(int16 aug_index); + } /*invaug*/ namespace item { @@ -154,147 +264,21 @@ namespace UF namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::UF; } + const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances + const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance + + const int16 POTION_BELT_SIZE = 5; + + const int16 SKILL_ARRAY_SIZE = 100; + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::UF; } - } /*constants*/ + const size_t CHARACTER_CREATION_LIMIT = 12; - namespace behavior { - inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::UF; } - - } /*behavior*/ - - namespace skills { - inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; } - - } /*skills*/ - - - // declarations - namespace inventory { - const bool ConcatenateInvTypeLimbo = true; - - const bool AllowOverLevelEquipment = true; - - const bool AllowEmptyBagInBag = false; - const bool AllowClickCastFromBag = false; - - } /*inventory*/ - - namespace invtype { - const size_t InvTypePossessionsSize = invslot::PossessionsCount; - const size_t InvTypeBankSize = 24; - const size_t InvTypeSharedBankSize = 2; - const size_t InvTypeTradeSize = 8; - const size_t InvTypeWorldSize = 10; - const size_t InvTypeLimboSize = 36; - const size_t InvTypeTributeSize = 5; - const size_t InvTypeGuildTributeSize = 2; - const size_t InvTypeMerchantSize = 80; - const size_t InvTypeCorpseSize = InvTypePossessionsSize; - const size_t InvTypeBazaarSize = 80; - const size_t InvTypeInspectSize = invslot::EquipmentCount; - const size_t InvTypeViewMODPCSize = InvTypePossessionsSize; - const size_t InvTypeViewMODBankSize = InvTypeBankSize; - const size_t InvTypeViewMODSharedBankSize = InvTypeSharedBankSize; - const size_t InvTypeViewMODLimboSize = InvTypeLimboSize; - const size_t InvTypeAltStorageSize = 0;//unknown - "Shroud Bank" - const size_t InvTypeArchivedSize = 0;//unknown - const size_t InvTypeOtherSize = 0;//unknown - - extern size_t GetInvTypeSize(int inv_type); - extern const char* GetInvTypeName(int inv_type); - - extern bool IsInvTypePersistent(int inv_type); - - } /*invtype*/ - - namespace invslot { - const int BankBegin = 2000; - const int BankEnd = (BankBegin + invtype::InvTypeBankSize) - 1; - - const int SharedBankBegin = 2500; - const int SharedBankEnd = (SharedBankBegin + invtype::InvTypeSharedBankSize) - 1; - - const int TradeBegin = 3000; - const int TradeEnd = (TradeBegin + invtype::InvTypeTradeSize) - 1; - const int TradeNPCEnd = 3003; - - const int WorldBegin = 4000; - const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1; - - const int TributeBegin = 400; - const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1; - - const int GuildTributeBegin = 450; - const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1; - - const int CorpseBegin = invslot::PossessionsGeneral1; - const int CorpseEnd = invslot::PossessionsGeneral1 + invslot::PossessionsCursor; - - extern const char* GetInvPossessionsSlotName(int inv_slot); - extern const char* GetInvCorpseSlotName(int inv_slot); - extern const char* GetInvSlotName(int inv_type, int inv_slot); - - } /*invslot*/ - - namespace invbag { - const size_t ItemBagSize = 10; - - const int GeneralBagsBegin = 262; - const int GeneralBagsSize = invslot::GeneralCount * ItemBagSize; - const int GeneralBagsEnd = (GeneralBagsBegin + GeneralBagsSize) - 1; - - const int CursorBagBegin = 342; - const int CursorBagSize = ItemBagSize; - const int CursorBagEnd = (CursorBagBegin + CursorBagSize) - 1; - - const int BankBagsBegin = 2032; - const int BankBagsSize = (invtype::InvTypeBankSize * ItemBagSize); - const int BankBagsEnd = (BankBagsBegin + BankBagsSize) - 1; - - const int SharedBankBagsBegin = 2532; - const int SharedBankBagsSize = invtype::InvTypeSharedBankSize * ItemBagSize; - const int SharedBankBagsEnd = (SharedBankBagsBegin + SharedBankBagsSize) - 1; - - const int TradeBagsBegin = 3031; - const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize; - const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1; - - extern const char* GetInvBagIndexName(int bag_index); - - } /*invbag*/ - - namespace invaug { - const size_t ItemAugSize = 5; - - extern const char* GetInvAugIndexName(int aug_index); - - } /*invaug*/ - - namespace item { - - } /*item*/ - - namespace profile { - const size_t TributeSize = invtype::InvTypeTributeSize; - const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize; - - const size_t BandoliersSize = 20; // number of bandolier instances - const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance - - const size_t PotionBeltSize = 5; - - const size_t SkillArraySize = 100; - - } /*profile*/ - - namespace constants { - const size_t CharacterCreationLimit = 12; - - const size_t SayLinkBodySize = 50; + const size_t SAY_LINK_BODY_SIZE = 50; const int LongBuffs = 30; const int ShortBuffs = 20; @@ -307,11 +291,15 @@ namespace UF } /*constants*/ namespace behavior { + inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::UF; } + const bool CoinHasWeight = false; } /*behavior*/ namespace skills { + inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; } + const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack; } /*skills*/ diff --git a/common/patches/uf_ops.h b/common/patches/uf_ops.h index 2287f0cd1..9d7742cf0 100644 --- a/common/patches/uf_ops.h +++ b/common/patches/uf_ops.h @@ -72,7 +72,6 @@ E(OP_MoveItem) E(OP_NewSpawn) E(OP_NewZone) E(OP_OnLevelMessage) -E(OP_OpenNewTasksWindow) E(OP_PetBuffWindow) E(OP_PlayerProfile) E(OP_RaidJoin) diff --git a/common/patches/uf_structs.h b/common/patches/uf_structs.h index dc66afd43..02361cf1f 100644 --- a/common/patches/uf_structs.h +++ b/common/patches/uf_structs.h @@ -746,7 +746,7 @@ struct BandolierItem_Struct struct Bandolier_Struct { char Name[32]; - BandolierItem_Struct Items[profile::BandolierItemCount]; + BandolierItem_Struct Items[profile::BANDOLIER_ITEM_COUNT]; }; //len = 72 @@ -760,7 +760,7 @@ struct PotionBeltItem_Struct //len = 288 struct PotionBelt_Struct { - PotionBeltItem_Struct Items[profile::PotionBeltSize]; + PotionBeltItem_Struct Items[profile::POTION_BELT_SIZE]; }; static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16; @@ -969,7 +969,7 @@ struct PlayerProfile_Struct /*11236*/ uint32 aapoints_spent; // Number of spent AA points /*11240*/ uint32 aapoints; // Unspent AA points /*11244*/ uint8 unknown11244[4]; -/*11248*/ Bandolier_Struct bandoliers[profile::BandoliersSize]; // [6400] bandolier contents +/*11248*/ Bandolier_Struct bandoliers[profile::BANDOLIERS_SIZE]; // [6400] bandolier contents /*17648*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot /*18008*/ uint8 unknown18008[8]; /*18016*/ uint32 available_slots; diff --git a/common/perl_eqdb.cpp b/common/perl_eqdb.cpp index 2cd9fa38d..06fb7f958 100644 --- a/common/perl_eqdb.cpp +++ b/common/perl_eqdb.cpp @@ -28,9 +28,9 @@ typedef const char Const_char; #ifdef EMBPERL -#include "../common/global_define.h" -#include "../common/useperl.h" +#include "global_define.h" #include "eqdb.h" +#include "useperl.h" #ifdef THIS /* this macro seems to leak out on some systems */ #undef THIS diff --git a/common/perl_eqdb_res.cpp b/common/perl_eqdb_res.cpp index 2782a6f05..61b2f4043 100644 --- a/common/perl_eqdb_res.cpp +++ b/common/perl_eqdb_res.cpp @@ -28,9 +28,9 @@ typedef const char Const_char; #ifdef EMBPERL -#include "../common/global_define.h" -#include "../common/useperl.h" +#include "global_define.h" #include "eqdb_res.h" +#include "useperl.h" XS(XS_EQDBRes_num_rows); /* prototype to pass -Wmissing-prototypes */ diff --git a/common/races.cpp b/common/races.cpp index 1e4d88664..68f4717b6 100644 --- a/common/races.cpp +++ b/common/races.cpp @@ -1349,102 +1349,99 @@ const char* GetPlayerRaceName(uint32 player_race_value) return GetRaceIDName(GetRaceIDFromPlayerRaceValue(player_race_value)); } -uint32 GetPlayerRaceValue(uint16 race_id) -{ +uint32 GetPlayerRaceValue(uint16 race_id) { switch (race_id) { - case HUMAN: - case BARBARIAN: - case ERUDITE: - case WOOD_ELF: - case HIGH_ELF: - case DARK_ELF: - case HALF_ELF: - case DWARF: - case TROLL: - case OGRE: - case HALFLING: - case GNOME: - return race_id; - case IKSAR: - return PLAYER_RACE_IKSAR; - case VAHSHIR: - return PLAYER_RACE_VAHSHIR; - case FROGLOK: - case FROGLOK2: - return PLAYER_RACE_FROGLOK; - case DRAKKIN: - return PLAYER_RACE_DRAKKIN; - default: - return PLAYER_RACE_UNKNOWN; // watch + case HUMAN: + case BARBARIAN: + case ERUDITE: + case WOOD_ELF: + case HIGH_ELF: + case DARK_ELF: + case HALF_ELF: + case DWARF: + case TROLL: + case OGRE: + case HALFLING: + case GNOME: + return race_id; + case IKSAR: + return PLAYER_RACE_IKSAR; + case VAHSHIR: + return PLAYER_RACE_VAHSHIR; + case FROGLOK: + case FROGLOK2: + return PLAYER_RACE_FROGLOK; + case DRAKKIN: + return PLAYER_RACE_DRAKKIN; + default: + return PLAYER_RACE_UNKNOWN; // watch } } -uint32 GetPlayerRaceBit(uint16 race_id) -{ +uint32 GetPlayerRaceBit(uint16 race_id) { switch (race_id) { - case HUMAN: - return PLAYER_RACE_HUMAN_BIT; - case BARBARIAN: - return PLAYER_RACE_BARBARIAN_BIT; - case ERUDITE: - return PLAYER_RACE_ERUDITE_BIT; - case WOOD_ELF: - return PLAYER_RACE_WOOD_ELF_BIT; - case HIGH_ELF: - return PLAYER_RACE_HIGH_ELF_BIT; - case DARK_ELF: - return PLAYER_RACE_DARK_ELF_BIT; - case HALF_ELF: - return PLAYER_RACE_HALF_ELF_BIT; - case DWARF: - return PLAYER_RACE_DWARF_BIT; - case TROLL: - return PLAYER_RACE_TROLL_BIT; - case OGRE: - return PLAYER_RACE_OGRE_BIT; - case HALFLING: - return PLAYER_RACE_HALFLING_BIT; - case GNOME: - return PLAYER_RACE_GNOME_BIT; - case IKSAR: - return PLAYER_RACE_IKSAR_BIT; - case VAHSHIR: - return PLAYER_RACE_VAHSHIR_BIT; - case FROGLOK: - return PLAYER_RACE_FROGLOK_BIT; - case DRAKKIN: - return PLAYER_RACE_DRAKKIN_BIT; - default: - return PLAYER_RACE_UNKNOWN_BIT; + case HUMAN: + return PLAYER_RACE_HUMAN_BIT; + case BARBARIAN: + return PLAYER_RACE_BARBARIAN_BIT; + case ERUDITE: + return PLAYER_RACE_ERUDITE_BIT; + case WOOD_ELF: + return PLAYER_RACE_WOOD_ELF_BIT; + case HIGH_ELF: + return PLAYER_RACE_HIGH_ELF_BIT; + case DARK_ELF: + return PLAYER_RACE_DARK_ELF_BIT; + case HALF_ELF: + return PLAYER_RACE_HALF_ELF_BIT; + case DWARF: + return PLAYER_RACE_DWARF_BIT; + case TROLL: + return PLAYER_RACE_TROLL_BIT; + case OGRE: + return PLAYER_RACE_OGRE_BIT; + case HALFLING: + return PLAYER_RACE_HALFLING_BIT; + case GNOME: + return PLAYER_RACE_GNOME_BIT; + case IKSAR: + return PLAYER_RACE_IKSAR_BIT; + case VAHSHIR: + return PLAYER_RACE_VAHSHIR_BIT; + case FROGLOK: + return PLAYER_RACE_FROGLOK_BIT; + case DRAKKIN: + return PLAYER_RACE_DRAKKIN_BIT; + default: + return PLAYER_RACE_UNKNOWN_BIT; } } -uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value) -{ +uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value) { switch (player_race_value) { - case PLAYER_RACE_HUMAN: - case PLAYER_RACE_BARBARIAN: - case PLAYER_RACE_ERUDITE: - case PLAYER_RACE_WOOD_ELF: - case PLAYER_RACE_HIGH_ELF: - case PLAYER_RACE_DARK_ELF: - case PLAYER_RACE_HALF_ELF: - case PLAYER_RACE_DWARF: - case PLAYER_RACE_TROLL: - case PLAYER_RACE_OGRE: - case PLAYER_RACE_HALFLING: - case PLAYER_RACE_GNOME: - return player_race_value; - case PLAYER_RACE_IKSAR: - return IKSAR; - case PLAYER_RACE_VAHSHIR: - return VAHSHIR; - case PLAYER_RACE_FROGLOK: - return FROGLOK; - case PLAYER_RACE_DRAKKIN: - return DRAKKIN; - default: - return PLAYER_RACE_UNKNOWN; // watch + case PLAYER_RACE_HUMAN: + case PLAYER_RACE_BARBARIAN: + case PLAYER_RACE_ERUDITE: + case PLAYER_RACE_WOOD_ELF: + case PLAYER_RACE_HIGH_ELF: + case PLAYER_RACE_DARK_ELF: + case PLAYER_RACE_HALF_ELF: + case PLAYER_RACE_DWARF: + case PLAYER_RACE_TROLL: + case PLAYER_RACE_OGRE: + case PLAYER_RACE_HALFLING: + case PLAYER_RACE_GNOME: + return player_race_value; + case PLAYER_RACE_IKSAR: + return IKSAR; + case PLAYER_RACE_VAHSHIR: + return VAHSHIR; + case PLAYER_RACE_FROGLOK: + return FROGLOK; + case PLAYER_RACE_DRAKKIN: + return DRAKKIN; + default: + return PLAYER_RACE_UNKNOWN; // watch } } @@ -1596,7 +1593,7 @@ float GetRaceGenderDefaultHeight(int race, int gender) const auto size = sizeof(male_height) / sizeof(male_height[0]); - if (race > size) + if (race >= size) return 6.0f; if (gender == 1) diff --git a/common/races.h b/common/races.h index 4f4eea1cc..5e7411a25 100644 --- a/common/races.h +++ b/common/races.h @@ -878,415 +878,732 @@ namespace PlayerAppearance bool IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_value, bool use_luclin = true); } -/* - -//pulled from the client by ksmith: -$races_table = array( - 1 => "Human", - 2 => "Barbarian", - 3 => "Erudite", - 4 => "Wood Elf", - 5 => "High Elf", - 6 => "Dark Elf", - 7 => "Half Elf", - 8 => "Dwarf", - 9 => "Troll", - 10 => "Ogre", - 11 => "Halfling", - 12 => "Gnome", - 13 => "Aviak", - 14 => "Were Wolf", - 15 => "Brownie", - 16 => "Centaur", - 17 => "Golem", - 18 => "Giant / Cyclops", - 19 => "Trakenon", - 20 => "Doppleganger", - 21 => "Evil Eye", - 22 => "Beetle", - 23 => "Kerra", - 24 => "Fish", - 25 => "Fairy", - 26 => "Old Froglok", - 27 => "Old Froglok Ghoul", - 28 => "Fungusman", - 29 => "Gargoyle", - 30 => "Gasbag", - 31 => "Gelatinous Cube", - 32 => "Ghost", - 33 => "Ghoul", - 34 => "Giant Bat", - 35 => "Giant Eel", - 36 => "Giant Rat", - 37 => "Giant Snake", - 38 => "Giant Spider", - 39 => "Gnoll", - 40 => "Goblin", - 41 => "Gorilla", - 42 => "Wolf", - 43 => "Bear", - 44 => "Freeport Guards", - 45 => "Demi Lich", - 46 => "Imp", - 47 => "Griffin", - 48 => "Kobold", - 49 => "Lava Dragon", - 50 => "Lion", - 51 => "Lizard Man", - 52 => "Mimic", - 53 => "Minotaur", - 54 => "Orc", - 55 => "Human Beggar", - 56 => "Pixie", - 57 => "Dracnid", - 58 => "Solusek Ro", - 59 => "Bloodgills", - 60 => "Skeleton", - 61 => "Shark", - 62 => "Tunare", - 63 => "Tiger", - 64 => "Treant", - 65 => "Vampire", - 66 => "Rallos Zek", - 67 => "Highpass Citizen", - 68 => "Tentacle", - 69 => "Will 'O Wisp", - 70 => "Zombie", - 71 => "Qeynos Citizen", - 72 => "Ship", - 73 => "Launch", - 74 => "Piranha", - 75 => "Elemental", - 76 => "Puma", - 77 => "Neriak Citizen", - 78 => "Erudite Citizen", - 79 => "Bixie", - 80 => "Reanimated Hand", - 81 => "Rivervale Citizen", - 82 => "Scarecrow", - 83 => "Skunk", - 84 => "Snake Elemental", - 85 => "Spectre", - 86 => "Sphinx", - 87 => "Armadillo", - 88 => "Clockwork Gnome", - 89 => "Drake", - 90 => "Halas Citizen", - 91 => "Alligator", - 92 => "Grobb Citizen", - 93 => "Oggok Citizen", - 94 => "Kaladim Citizen", - 95 => "Cazic Thule", - 96 => "Cockatrice", - 97 => "Daisy Man", - 98 => "Elf Vampire", - 99 => "Denizen", - 100 => "Dervish", - 101 => "Efreeti", - 102 => "Old Froglok Tadpole", - 103 => "Kedge", - 104 => "Leech", - 105 => "Swordfish", - 106 => "Felguard", - 107 => "Mammoth", - 108 => "Eye of Zomm", - 109 => "Wasp", - 110 => "Mermaid", - 111 => "Harpie", - 112 => "Fayguard", - 113 => "Drixie", - 114 => "Ghost Ship", - 115 => "Clam", - 116 => "Sea Horse", - 117 => "Ghost Dwarf", - 118 => "Erudite Ghost", - 119 => "Sabertooth Cat", - 120 => "Wolf Elemental", - 121 => "Gorgon", - 122 => "Dragon Skeleton", - 123 => "Innoruuk", - 124 => "Unicorn", - 125 => "Pegasus", - 126 => "Djinn", - 127 => "Invisible Man", - 128 => "Iksar", - 129 => "Scorpion", - 130 => "Vah Shir", - 131 => "Sarnak", - 132 => "Draglock", - 133 => "Lycanthrope", - 134 => "Mosquito", - 135 => "Rhino", - 136 => "Xalgoz", - 137 => "Kunark Goblin", - 138 => "Yeti", - 139 => "Iksar Citizen", - 140 => "Forest Giant", - 141 => "Boat", - 142 => "UNKNOWN RACE", - 143 => "UNKNOWN RACE", - 144 => "Burynai", - 145 => "Goo", - 146 => "Spectral Sarnak", - 147 => "Spectral Iksar", - 148 => "Kunark Fish", - 149 => "Iksar Scorpion", - 150 => "Erollisi", - 151 => "Tribunal", - 152 => "Bertoxxulous", - 153 => "Bristlebane", - 154 => "Fay Drake", - 155 => "Sarnak Skeleton", - 156 => "Ratman", - 157 => "Wyvern", - 158 => "Wurm", - 159 => "Devourer", - 160 => "Iksar Golem", - 161 => "Iksar Skeleton", - 162 => "Man Eating Plant", - 163 => "Raptor", - 164 => "Sarnak Golem", - 165 => "Water Dragon", - 166 => "Iksar Hand", - 167 => "Succulent", - 168 => "Flying Monkey", - 169 => "Brontotherium", - 170 => "Snow Dervish", - 171 => "Dire Wolf", - 172 => "Manticore", - 173 => "Totem", - 174 => "Cold Spectre", - 175 => "Enchanted Armor", - 176 => "Snow Bunny", - 177 => "Walrus", - 178 => "Rock-gem Men", - 179 => "UNKNOWN RACE", - 180 => "UNKNOWN RACE", - 181 => "Yak Man", - 182 => "Faun", - 183 => "Coldain", - 184 => "Velious Dragons", - 185 => "Hag", - 186 => "Hippogriff", - 187 => "Siren", - 188 => "Frost Giant", - 189 => "Storm Giant", - 190 => "Ottermen", - 191 => "Walrus Man", - 192 => "Clockwork Dragon", - 193 => "Abhorent", - 194 => "Sea Turtle", - 195 => "Black and White Dragons", - 196 => "Ghost Dragon", - 197 => "Ronnie Test", - 198 => "Prismatic Dragon", - 199 => "ShikNar", - 200 => "Rockhopper", - 201 => "Underbulk", - 202 => "Grimling", - 203 => "Vacuum Worm", - 204 => "Evan Test", - 205 => "Kahli Shah", - 206 => "Owlbear", - 207 => "Rhino Beetle", - 208 => "Vampyre", - 209 => "Earth Elemental", - 210 => "Air Elemental", - 211 => "Water Elemental", - 212 => "Fire Elemental", - 213 => "Wetfang Minnow", - 214 => "Thought Horror", - 215 => "Tegi", - 216 => "Horse", - 217 => "Shissar", - 218 => "Fungal Fiend", - 219 => "Vampire Volatalis", - 220 => "StoneGrabber", - 221 => "Scarlet Cheetah", - 222 => "Zelniak", - 223 => "Lightcrawler", - 224 => "Shade", - 225 => "Sunflower", - 226 => "Sun Revenant", - 227 => "Shrieker", - 228 => "Galorian", - 229 => "Netherbian", - 230 => "Akheva", - 231 => "Spire Spirit", - 232 => "Sonic Wolf", - 233 => "Ground Shaker", - 234 => "Vah Shir Skeleton", - 235 => "Mutant Humanoid", - 236 => "Seru", - 237 => "Recuso", - 238 => "Vah Shir King", - 239 => "Vah Shir Guard", - 240 => "Teleport Man", - 241 => "Lujein", - 242 => "Naiad", - 243 => "Nymph", - 244 => "Ent", - 245 => "Fly Man", - 246 => "Tarew Marr", - 247 => "Sol Ro", - 248 => "Clockwork Golem", - 249 => "Clockwork Brain", - 250 => "Spectral Banshee", - 251 => "Guard of Justice", - 252 => "UNKNOWN RACE", - 253 => "Disease Boss", - 254 => "Sol Ro Guard", - 255 => "New Bertox", - 256 => "New Tribunal", - 257 => "Terris Thule", - 258 => "Vegerog", - 259 => "Crocodile", - 260 => "Bat", - 261 => "Slarghilug", - 262 => "Tranquilion", - 263 => "Tin Soldier", - 264 => "Nightmare Wraith", - 265 => "Malarian", - 266 => "Knight of Pestilence", - 267 => "Lepertoloth", - 268 => "Bubonian Boss", - 269 => "Bubonian Underling", - 270 => "Pusling", - 271 => "Water Mephit", - 272 => "Stormrider", - 273 => "Junk Beast", - 274 => "Broken Clockwork", - 275 => "Giant Clockwork", - 276 => "Clockwork Beetle", - 277 => "Nightmare Goblin", - 278 => "Karana", - 279 => "Blood Raven", - 280 => "Nightmare Gargoyle", - 281 => "Mouths of Insanity", - 282 => "Skeletal Horse", - 283 => "Saryn", - 284 => "Fennin Ro", - 285 => "Tormentor", - 286 => "Necro Priest", - 287 => "Nightmare", - 288 => "New Rallos Zek", - 289 => "Vallon Zek", - 290 => "Tallon Zek", - 291 => "Air Mephit", - 292 => "Earth Mephit", - 293 => "Fire Mephit", - 294 => "Nightmare Mephit", - 295 => "Zebuxoruk", - 296 => "Mithaniel Marr", - 297 => "Undead Knight", - 298 => "The Rathe", - 299 => "Xegony", - 300 => "Fiend", - 301 => "Test Object", - 302 => "Crab", - 303 => "Phoenix", - 304 => "PoP Dragon", - 305 => "PoP Bear", - 306 => "Storm Taarid", - 307 => "Storm Satuur", - 308 => "Storm Kuraaln", - 309 => "Storm Volaas", - 310 => "Storm Mana", - 311 => "Storm Fire", - 312 => "Storm Celestial", - 313 => "War Wraith", - 314 => "Wrulon", - 315 => "Kraken", - 316 => "Poison Frog", - 317 => "Queztocoatal", - 318 => "Valorian", - 319 => "War Boar", - 320 => "PoP Efreeti", - 321 => "War Boar Unarmored", - 322 => "Black Knight", - 323 => "Animated Armor", - 324 => "Undead Footman", - 325 => "Rallos Zek Minion", - 326 => "Arachnid", - 327 => "Crystal Spider", - 328 => "Zeb Cage", - 329 => "BoT Portal", - 330 => "Froglok", - 331 => "Troll Buccaneer", - 332 => "Troll Freebooter", - 333 => "Troll Sea Rover", - 334 => "Spectre Pirate Boss", - 335 => "Pirate Boss", - 336 => "Pirate Dark Shaman", - 337 => "Pirate Officer", - 338 => "Gnome Pirate", - 339 => "Dark Elf Pirate", - 340 => "Ogre Pirate", - 341 => "Human Pirate", - 342 => "Erudite Pirate", - 343 => "Poison Dart Frog", - 344 => "Troll Zombie", - 345 => "Luggald Land", - 346 => "Luggald Armored", - 347 => "Luggald Robed", - 348 => "Froglok Mount", - 349 => "Froglok Skeleton", - 350 => "Undead Froglok", - 351 => "Chosen Warrior", - 352 => "Chosen Wizard", - 353 => "Veksar", - 354 => "Greater Veksar", - 355 => "Veksar Boss", - 356 => "Chokadai", - 357 => "Undead Chokadai", - 358 => "Undead Veksar", - 359 => "Vampire Lesser", - 360 => "Vampire Elite", - 361 => "Rujakian Orc", - 362 => "Bone Golem", - 363 => "Synarcana", - 364 => "Sand Elf", - 365 => "Vampire Master", - 366 => "Rujakian Orc Elite", - 367 => "Skeleton New", - 368 => "Mummy New", - 369 => "Goblin New", - 370 => "Insect", - 371 => "Froglok Ghost", - 372 => "Dervish New", - 373 => "Shadow Creatue", - 374 => "Golem New", - 375 => "Evil Eye New", - 376 => "Box", - 377 => "Barrel", - 378 => "Chest", - 379 => "Vase", - 380 => "Table", - 381 => "Weapons Rack", - 382 => "Coffin", - 383 => "Bones", - 384 => "Jokester", - 385 => "Talosian Nihil", - 386 => "Talosian Exile", - 387 => "Talosian Golem", - 388 => "Talosian Wolf", - 389 => "Talosian Amphibian", - 390 => "Talosian Mountain Beast", - 391 => "Talosian Trilobyte", - 392 => "Invader War Hound", - 393 => "Invader Elite Centaur", - 394 => "Invader Lamia", - 395 => "Invader Cyclops", - 396 => "Kyv", - 397 => "Invader Soldier", - 398 => "Invader Brute", - 399 => "Invader Force Commander", - 400 => "Invader Lieutenant Boss", - 401 => "Invader War Beast", - 402 => "Invader Soldier Elite", - 403 => "UNKNOWN RACE", - 404 => "Discord Ship", -*/ +#define RACE_DOUG_0 0 +#define RACE_HUMAN_1 1 +#define RACE_BARBARIAN_2 2 +#define RACE_ERUDITE_3 3 +#define RACE_WOOD_ELF_4 4 +#define RACE_HIGH_ELF_5 5 +#define RACE_DARK_ELF_6 6 +#define RACE_HALF_ELF_7 7 +#define RACE_DWARF_8 8 +#define RACE_TROLL_9 9 +#define RACE_OGRE_10 10 +#define RACE_HALFLING_11 11 +#define RACE_GNOME_12 12 +#define RACE_AVIAK_13 13 +#define RACE_WEREWOLF_14 14 +#define RACE_BROWNIE_15 15 +#define RACE_CENTAUR_16 16 +#define RACE_GOLEM_17 17 +#define RACE_GIANT_18 18 +#define RACE_TRAKANON_19 19 +#define RACE_VENRIL_SATHIR_20 20 +#define RACE_EVIL_EYE_21 21 +#define RACE_BEETLE_22 22 +#define RACE_KERRAN_23 23 +#define RACE_FISH_24 24 +#define RACE_FAIRY_25 25 +#define RACE_FROGLOK_26 26 +#define RACE_FROGLOK_GHOUL_27 27 +#define RACE_FUNGUSMAN_28 28 +#define RACE_GARGOYLE_29 29 +#define RACE_GASBAG_30 30 +#define RACE_GELATINOUS_CUBE_31 31 +#define RACE_GHOST_32 32 +#define RACE_GHOUL_33 33 +#define RACE_GIANT_BAT_34 34 +#define RACE_GIANT_EEL_35 35 +#define RACE_GIANT_RAT_36 36 +#define RACE_GIANT_SNAKE_37 37 +#define RACE_GIANT_SPIDER_38 38 +#define RACE_GNOLL_39 39 +#define RACE_GOBLIN_40 40 +#define RACE_GORILLA_41 41 +#define RACE_WOLF_42 42 +#define RACE_BEAR_43 43 +#define RACE_FREEPORT_GUARD_44 44 +#define RACE_DEMI_LICH_45 45 +#define RACE_IMP_46 46 +#define RACE_GRIFFIN_47 47 +#define RACE_KOBOLD_48 48 +#define RACE_LAVA_DRAGON_49 49 +#define RACE_LION_50 50 +#define RACE_LIZARD_MAN_51 51 +#define RACE_MIMIC_52 52 +#define RACE_MINOTAUR_53 53 +#define RACE_ORC_54 54 +#define RACE_HUMAN_BEGGAR_55 55 +#define RACE_PIXIE_56 56 +#define RACE_DRACNID_57 57 +#define RACE_SOLUSEK_RO_58 58 +#define RACE_BLOODGILL_59 59 +#define RACE_SKELETON_60 60 +#define RACE_SHARK_61 61 +#define RACE_TUNARE_62 62 +#define RACE_TIGER_63 63 +#define RACE_TREANT_64 64 +#define RACE_VAMPIRE_65 65 +#define RACE_STATUE_OF_RALLOS_ZEK_66 66 +#define RACE_HIGHPASS_CITIZEN_67 67 +#define RACE_TENTACLE_68 68 +#define RACE_WISP_69 69 +#define RACE_ZOMBIE_70 70 +#define RACE_QEYNOS_CITIZEN_71 71 +#define RACE_SHIP_72 72 +#define RACE_LAUNCH_73 73 +#define RACE_PIRANHA_74 74 +#define RACE_ELEMENTAL_75 75 +#define RACE_PUMA_76 76 +#define RACE_NERIAK_CITIZEN_77 77 +#define RACE_ERUDITE_CITIZEN_78 78 +#define RACE_BIXIE_79 79 +#define RACE_REANIMATED_HAND_80 80 +#define RACE_RIVERVALE_CITIZEN_81 81 +#define RACE_SCARECROW_82 82 +#define RACE_SKUNK_83 83 +#define RACE_SNAKE_ELEMENTAL_84 84 +#define RACE_SPECTRE_85 85 +#define RACE_SPHINX_86 86 +#define RACE_ARMADILLO_87 87 +#define RACE_CLOCKWORK_GNOME_88 88 +#define RACE_DRAKE_89 89 +#define RACE_HALAS_CITIZEN_90 90 +#define RACE_ALLIGATOR_91 91 +#define RACE_GROBB_CITIZEN_92 92 +#define RACE_OGGOK_CITIZEN_93 93 +#define RACE_KALADIM_CITIZEN_94 94 +#define RACE_CAZIC_THULE_95 95 +#define RACE_COCKATRICE_96 96 +#define RACE_DAISY_MAN_97 97 +#define RACE_ELF_VAMPIRE_98 98 +#define RACE_DENIZEN_99 99 +#define RACE_DERVISH_100 100 +#define RACE_EFREETI_101 101 +#define RACE_FROGLOK_TADPOLE_102 102 +#define RACE_PHINIGEL_AUTROPOS_103 103 +#define RACE_LEECH_104 104 +#define RACE_SWORDFISH_105 105 +#define RACE_FELGUARD_106 106 +#define RACE_MAMMOTH_107 107 +#define RACE_EYE_OF_ZOMM_108 108 +#define RACE_WASP_109 109 +#define RACE_MERMAID_110 110 +#define RACE_HARPIE_111 111 +#define RACE_FAYGUARD_112 112 +#define RACE_DRIXIE_113 113 +#define RACE_GHOST_SHIP_114 114 +#define RACE_CLAM_115 115 +#define RACE_SEA_HORSE_116 116 +#define RACE_DWARF_GHOST_117 117 +#define RACE_ERUDITE_GHOST_118 118 +#define RACE_SABERTOOTH_119 119 +#define RACE_WOLF_ELEMENTAL_120 120 +#define RACE_GORGON_121 121 +#define RACE_DRAGON_SKELETON_122 122 +#define RACE_INNORUUK_123 123 +#define RACE_UNICORN_124 124 +#define RACE_PEGASUS_125 125 +#define RACE_DJINN_126 126 +#define RACE_INVISIBLE_MAN_127 127 +#define RACE_IKSAR_128 128 +#define RACE_SCORPION_129 129 +#define RACE_VAH_SHIR_130 130 +#define RACE_SARNAK_131 131 +#define RACE_DRAGLOCK_132 132 +#define RACE_LYCANTHROPE_133 133 +#define RACE_MOSQUITO_134 134 +#define RACE_RHINO_135 135 +#define RACE_XALGOZ_136 136 +#define RACE_KUNARK_GOBLIN_137 137 +#define RACE_YETI_138 138 +#define RACE_IKSAR_CITIZEN_139 139 +#define RACE_FOREST_GIANT_140 140 +#define RACE_BOAT_141 141 +#define RACE_MINOR_ILLUSION_142 142 +#define RACE_TREE_ILLUSION_143 143 +#define RACE_BURYNAI_144 144 +#define RACE_GOO_145 145 +#define RACE_SPECTRAL_SARNAK_146 146 +#define RACE_SPECTRAL_IKSAR_147 147 +#define RACE_KUNARK_FISH_148 148 +#define RACE_IKSAR_SCORPION_149 149 +#define RACE_EROLLISI_150 150 +#define RACE_TRIBUNAL_151 151 +#define RACE_BERTOXXULOUS_152 152 +#define RACE_BRISTLEBANE_153 153 +#define RACE_FAY_DRAKE_154 154 +#define RACE_SARNAK_SKELETON_155 155 +#define RACE_RATMAN_156 156 +#define RACE_WYVERN_157 157 +#define RACE_WURM_158 158 +#define RACE_DEVOURER_159 159 +#define RACE_IKSAR_GOLEM_160 160 +#define RACE_IKSAR_SKELETON_161 161 +#define RACE_MAN_EATING_PLANT_162 162 +#define RACE_RAPTOR_163 163 +#define RACE_SARNAK_GOLEM_164 164 +#define RACE_WATER_DRAGON_165 165 +#define RACE_IKSAR_HAND_166 166 +#define RACE_SUCCULENT_167 167 +#define RACE_HOLGRESH_168 168 +#define RACE_BRONTOTHERIUM_169 169 +#define RACE_SNOW_DERVISH_170 170 +#define RACE_DIRE_WOLF_171 171 +#define RACE_MANTICORE_172 172 +#define RACE_TOTEM_173 173 +#define RACE_COLD_SPECTRE_174 174 +#define RACE_ENCHANTED_ARMOR_175 175 +#define RACE_SNOW_BUNNY_176 176 +#define RACE_WALRUS_177 177 +#define RACE_ROCK_GEM_MAN_178 178 +#define RACE_UNKNOWN179_179 179 +#define RACE_UNKNOWN180_180 180 +#define RACE_YAK_MAN_181 181 +#define RACE_FAUN_182 182 +#define RACE_COLDAIN_183 183 +#define RACE_VELIOUS_DRAGON_184 184 +#define RACE_HAG_185 185 +#define RACE_HIPPOGRIFF_186 186 +#define RACE_SIREN_187 187 +#define RACE_FROST_GIANT_188 188 +#define RACE_STORM_GIANT_189 189 +#define RACE_OTTERMAN_190 190 +#define RACE_WALRUS_MAN_191 191 +#define RACE_CLOCKWORK_DRAGON_192 192 +#define RACE_ABHORRENT_193 193 +#define RACE_SEA_TURTLE_194 194 +#define RACE_BLACK_AND_WHITE_DRAGON_195 195 +#define RACE_GHOST_DRAGON_196 196 +#define RACE_RONNIE_TEST_197 197 +#define RACE_PRISMATIC_DRAGON_198 198 +#define RACE_SHIKNAR_199 199 +#define RACE_ROCKHOPPER_200 200 +#define RACE_UNDERBULK_201 201 +#define RACE_GRIMLING_202 202 +#define RACE_VACUUM_WORM_203 203 +#define RACE_EVAN_TEST_204 204 +#define RACE_KAHLI_SHAH_205 205 +#define RACE_OWLBEAR_206 206 +#define RACE_RHINO_BEETLE_207 207 +#define RACE_VAMPYRE_208 208 +#define RACE_EARTH_ELEMENTAL_209 209 +#define RACE_AIR_ELEMENTAL_210 210 +#define RACE_WATER_ELEMENTAL_211 211 +#define RACE_FIRE_ELEMENTAL_212 212 +#define RACE_WETFANG_MINNOW_213 213 +#define RACE_THOUGHT_HORROR_214 214 +#define RACE_TEGI_215 215 +#define RACE_HORSE_216 216 +#define RACE_SHISSAR_217 217 +#define RACE_FUNGAL_FIEND_218 218 +#define RACE_VAMPIRE_VOLATALIS_219 219 +#define RACE_STONEGRABBER_220 220 +#define RACE_SCARLET_CHEETAH_221 221 +#define RACE_ZELNIAK_222 222 +#define RACE_LIGHTCRAWLER_223 223 +#define RACE_SHADE_224 224 +#define RACE_SUNFLOWER_225 225 +#define RACE_KHATI_SHA_226 226 +#define RACE_SHRIEKER_227 227 +#define RACE_GALORIAN_228 228 +#define RACE_NETHERBIAN_229 229 +#define RACE_AKHEVAN_230 230 +#define RACE_SPIRE_SPIRIT_231 231 +#define RACE_SONIC_WOLF_232 232 +#define RACE_GROUND_SHAKER_233 233 +#define RACE_VAH_SHIR_SKELETON_234 234 +#define RACE_MUTANT_HUMANOID_235 235 +#define RACE_LORD_INQUISITOR_SERU_236 236 +#define RACE_RECUSO_237 237 +#define RACE_VAH_SHIR_KING_238 238 +#define RACE_VAH_SHIR_GUARD_239 239 +#define RACE_TELEPORT_MAN_240 240 +#define RACE_LUJEIN_241 241 +#define RACE_NAIAD_242 242 +#define RACE_NYMPH_243 243 +#define RACE_ENT_244 244 +#define RACE_WRINNFLY_245 245 +#define RACE_COIRNAV_246 246 +#define RACE_SOLUSEK_RO_247 247 +#define RACE_CLOCKWORK_GOLEM_248 248 +#define RACE_CLOCKWORK_BRAIN_249 249 +#define RACE_SPECTRAL_BANSHEE_250 250 +#define RACE_GUARD_OF_JUSTICE_251 251 +#define RACE_POM_CASTLE_252 252 +#define RACE_DISEASE_BOSS_253 253 +#define RACE_SOLUSEK_RO_GUARD_254 254 +#define RACE_BERTOXXULOUS_NEW_255 255 +#define RACE_TRIBUNAL_NEW_256 256 +#define RACE_TERRIS_THULE_257 257 +#define RACE_VEGEROG_258 258 +#define RACE_CROCODILE_259 259 +#define RACE_BAT_260 260 +#define RACE_SLARGHILUG_261 261 +#define RACE_TRANQUILION_262 262 +#define RACE_TIN_SOLDIER_263 263 +#define RACE_NIGHTMARE_WRAITH_264 264 +#define RACE_MALARIAN_265 265 +#define RACE_KNIGHT_OF_PESTILENCE_266 266 +#define RACE_LEPERTOLOTH_267 267 +#define RACE_BUBONIAN_BOSS_268 268 +#define RACE_BUBONIAN_UNDERLING_269 269 +#define RACE_PUSLING_270 270 +#define RACE_WATER_MEPHIT_271 271 +#define RACE_STORMRIDER_272 272 +#define RACE_JUNK_BEAST_273 273 +#define RACE_BROKEN_CLOCKWORK_274 274 +#define RACE_GIANT_CLOCKWORK_275 275 +#define RACE_CLOCKWORK_BEETLE_276 276 +#define RACE_NIGHTMARE_GOBLIN_277 277 +#define RACE_KARANA_278 278 +#define RACE_BLOOD_RAVEN_279 279 +#define RACE_NIGHTMARE_GARGOYLE_280 280 +#define RACE_MOUTH_OF_INSANITY_281 281 +#define RACE_SKELETAL_HORSE_282 282 +#define RACE_SARYRN_283 283 +#define RACE_FENNIN_RO_284 284 +#define RACE_TORMENTOR_285 285 +#define RACE_NECROMANCER_PRIEST_286 286 +#define RACE_NIGHTMARE_287 287 +#define RACE_NEW_RALLOS_ZEK_288 288 +#define RACE_VALLON_ZEK_289 289 +#define RACE_TALLON_ZEK_290 290 +#define RACE_AIR_MEPHIT_291 291 +#define RACE_EARTH_MEPHIT_292 292 +#define RACE_FIRE_MEPHIT_293 293 +#define RACE_NIGHTMARE_MEPHIT_294 294 +#define RACE_ZEBUXORUK_295 295 +#define RACE_MITHANIEL_MARR_296 296 +#define RACE_KNIGHTMARE_RIDER_297 297 +#define RACE_RATHE_COUNCILMAN_298 298 +#define RACE_XEGONY_299 299 +#define RACE_DEMON_300 300 +#define RACE_TEST_OBJECT_301 301 +#define RACE_LOBSTER_MONSTER_302 302 +#define RACE_PHOENIX_303 303 +#define RACE_QUARM_304 304 +#define RACE_NEW_BEAR_305 305 +#define RACE_EARTH_GOLEM_306 306 +#define RACE_IRON_GOLEM_307 307 +#define RACE_STORM_GOLEM_308 308 +#define RACE_AIR_GOLEM_309 309 +#define RACE_WOOD_GOLEM_310 310 +#define RACE_FIRE_GOLEM_311 311 +#define RACE_WATER_GOLEM_312 312 +#define RACE_VEILED_GARGOYLE_313 313 +#define RACE_LYNX_314 314 +#define RACE_SQUID_315 315 +#define RACE_FROG_316 316 +#define RACE_FLYING_SERPENT_317 317 +#define RACE_TACTICS_SOLDIER_318 318 +#define RACE_ARMORED_BOAR_319 319 +#define RACE_DJINNI_320 320 +#define RACE_BOAR_321 321 +#define RACE_KNIGHT_OF_MARR_322 322 +#define RACE_ARMOR_OF_MARR_323 323 +#define RACE_NIGHTMARE_KNIGHT_324 324 +#define RACE_RALLOS_OGRE_325 325 +#define RACE_ARACHNID_326 326 +#define RACE_CRYSTAL_ARACHNID_327 327 +#define RACE_TOWER_MODEL_328 328 +#define RACE_PORTAL_329 329 +#define RACE_FROGLOK_330 330 +#define RACE_TROLL_CREW_MEMBER_331 331 +#define RACE_PIRATE_DECKHAND_332 332 +#define RACE_BROKEN_SKULL_PIRATE_333 333 +#define RACE_PIRATE_GHOST_334 334 +#define RACE_ONE_ARMED_PIRATE_335 335 +#define RACE_SPIRITMASTER_NADOX_336 336 +#define RACE_BROKEN_SKULL_TASKMASTER_337 337 +#define RACE_GNOME_PIRATE_338 338 +#define RACE_DARK_ELF_PIRATE_339 339 +#define RACE_OGRE_PIRATE_340 340 +#define RACE_HUMAN_PIRATE_341 341 +#define RACE_ERUDITE_PIRATE_342 342 +#define RACE_FROG_343 343 +#define RACE_UNDEAD_PIRATE_344 344 +#define RACE_LUGGALD_WORKER_345 345 +#define RACE_LUGGALD_SOLDIER_346 346 +#define RACE_LUGGALD_DISCIPLE_347 347 +#define RACE_DROGMOR_348 348 +#define RACE_FROGLOK_SKELETON_349 349 +#define RACE_UNDEAD_FROGLOK_350 350 +#define RACE_KNIGHT_OF_HATE_351 351 +#define RACE_WARLOCK_OF_HATE_352 352 +#define RACE_HIGHBORN_353 353 +#define RACE_HIGHBORN_DIVINER_354 354 +#define RACE_HIGHBORN_CRUSADER_355 355 +#define RACE_CHOKIDAI_356 356 +#define RACE_UNDEAD_CHOKIDAI_357 357 +#define RACE_UNDEAD_VEKSAR_358 358 +#define RACE_UNDEAD_VAMPIRE_359 359 +#define RACE_VAMPIRE_360 360 +#define RACE_RUJARKIAN_ORC_361 361 +#define RACE_BONE_GOLEM_362 362 +#define RACE_SYNARCANA_363 363 +#define RACE_SAND_ELF_364 364 +#define RACE_MASTER_VAMPIRE_365 365 +#define RACE_MASTER_ORC_366 366 +#define RACE_NEW_SKELETON_367 367 +#define RACE_CRYPT_CREEPER_368 368 +#define RACE_NEW_GOBLIN_369 369 +#define RACE_BURROWER_BUG_370 370 +#define RACE_FROGLOK_GHOST_371 371 +#define RACE_VORTEX_372 372 +#define RACE_SHADOW_373 373 +#define RACE_GOLEM_BEAST_374 374 +#define RACE_WATCHFUL_EYE_375 375 +#define RACE_BOX_376 376 +#define RACE_BARREL_377 377 +#define RACE_CHEST_378 378 +#define RACE_VASE_379 379 +#define RACE_FROZEN_TABLE_380 380 +#define RACE_WEAPON_RACK_381 381 +#define RACE_COFFIN_382 382 +#define RACE_SKULL_AND_BONES_383 383 +#define RACE_JESTER_384 384 +#define RACE_TAELOSIAN_NATIVE_385 385 +#define RACE_TAELOSIAN_EVOKER_386 386 +#define RACE_TAELOSIAN_GOLEM_387 387 +#define RACE_TAELOSIAN_WOLF_388 388 +#define RACE_TAELOSIAN_AMPHIBIAN_CREATURE_389 389 +#define RACE_TAELOSIAN_MOUNTAIN_BEAST_390 390 +#define RACE_TAELOSIAN_STONEMITE_391 391 +#define RACE_UKUN_WAR_HOUND_392 392 +#define RACE_IXT_CENTAUR_393 393 +#define RACE_IKAAV_SNAKEWOMAN_394 394 +#define RACE_ANEUK_395 395 +#define RACE_KYV_HUNTER_396 396 +#define RACE_NOC_SPRAYBLOOD_397 397 +#define RACE_RATUK_BRUTE_398 398 +#define RACE_IXT_399 399 +#define RACE_HUVUL_400 400 +#define RACE_MASTRUQ_WARFIEND_401 401 +#define RACE_MASTRUQ_402 402 +#define RACE_TAELOSIAN_403 403 +#define RACE_SHIP_404 404 +#define RACE_NEW_GOLEM_405 405 +#define RACE_OVERLORD_MATA_MURAM_406 406 +#define RACE_LIGHTING_WARRIOR_407 407 +#define RACE_SUCCUBUS_408 408 +#define RACE_BAZU_409 409 +#define RACE_FERAN_410 410 +#define RACE_PYRILEN_411 411 +#define RACE_CHIMERA_412 412 +#define RACE_DRAGORN_413 413 +#define RACE_MURKGLIDER_414 414 +#define RACE_RAT_415 415 +#define RACE_BAT_416 416 +#define RACE_GELIDRAN_417 417 +#define RACE_DISCORDLING_418 418 +#define RACE_GIRPLAN_419 419 +#define RACE_MINOTAUR_420 420 +#define RACE_DRAGORN_BOX_421 421 +#define RACE_RUNED_ORB_422 422 +#define RACE_DRAGON_BONES_423 423 +#define RACE_MURAMITE_ARMOR_PILE_424 424 +#define RACE_CRYSTAL_SHARD_425 425 +#define RACE_PORTAL_426 426 +#define RACE_COIN_PURSE_427 427 +#define RACE_ROCK_PILE_428 428 +#define RACE_MURKGLIDER_EGG_SACK_429 429 +#define RACE_DRAKE_430 430 +#define RACE_DERVISH_431 431 +#define RACE_DRAKE_432 432 +#define RACE_GOBLIN_433 433 +#define RACE_KIRIN_434 434 +#define RACE_DRAGON_435 435 +#define RACE_BASILISK_436 436 +#define RACE_DRAGON_437 437 +#define RACE_DRAGON_438 438 +#define RACE_PUMA_439 439 +#define RACE_SPIDER_440 440 +#define RACE_SPIDER_QUEEN_441 441 +#define RACE_ANIMATED_STATUE_442 442 +#define RACE_UNKNOWN443_443 443 +#define RACE_UNKNOWN444_444 444 +#define RACE_DRAGON_EGG_445 445 +#define RACE_DRAGON_STATUE_446 446 +#define RACE_LAVA_ROCK_447 447 +#define RACE_ANIMATED_STATUE_448 448 +#define RACE_SPIDER_EGG_SACK_449 449 +#define RACE_LAVA_SPIDER_450 450 +#define RACE_LAVA_SPIDER_QUEEN_451 451 +#define RACE_DRAGON_452 452 +#define RACE_GIANT_453 453 +#define RACE_WEREWOLF_454 454 +#define RACE_KOBOLD_455 455 +#define RACE_SPORALI_456 456 +#define RACE_GNOMEWORK_457 457 +#define RACE_ORC_458 458 +#define RACE_CORATHUS_459 459 +#define RACE_CORAL_460 460 +#define RACE_DRACHNID_461 461 +#define RACE_DRACHNID_COCOON_462 462 +#define RACE_FUNGUS_PATCH_463 463 +#define RACE_GARGOYLE_464 464 +#define RACE_WITHERAN_465 465 +#define RACE_DARK_LORD_466 466 +#define RACE_SHILISKIN_467 467 +#define RACE_SNAKE_468 468 +#define RACE_EVIL_EYE_469 469 +#define RACE_MINOTAUR_470 470 +#define RACE_ZOMBIE_471 471 +#define RACE_CLOCKWORK_BOAR_472 472 +#define RACE_FAIRY_473 473 +#define RACE_WITHERAN_474 474 +#define RACE_AIR_ELEMENTAL_475 475 +#define RACE_EARTH_ELEMENTAL_476 476 +#define RACE_FIRE_ELEMENTAL_477 477 +#define RACE_WATER_ELEMENTAL_478 478 +#define RACE_ALLIGATOR_479 479 +#define RACE_BEAR_480 480 +#define RACE_SCALED_WOLF_481 481 +#define RACE_WOLF_482 482 +#define RACE_SPIRIT_WOLF_483 483 +#define RACE_SKELETON_484 484 +#define RACE_SPECTRE_485 485 +#define RACE_BOLVIRK_486 486 +#define RACE_BANSHEE_487 487 +#define RACE_BANSHEE_488 488 +#define RACE_ELDDAR_489 489 +#define RACE_FOREST_GIANT_490 490 +#define RACE_BONE_GOLEM_491 491 +#define RACE_HORSE_492 492 +#define RACE_PEGASUS_493 493 +#define RACE_SHAMBLING_MOUND_494 494 +#define RACE_SCRYKIN_495 495 +#define RACE_TREANT_496 496 +#define RACE_VAMPIRE_497 497 +#define RACE_AYONAE_RO_498 498 +#define RACE_SULLON_ZEK_499 499 +#define RACE_BANNER_500 500 +#define RACE_FLAG_501 501 +#define RACE_ROWBOAT_502 502 +#define RACE_BEAR_TRAP_503 503 +#define RACE_CLOCKWORK_BOMB_504 504 +#define RACE_DYNAMITE_KEG_505 505 +#define RACE_PRESSURE_PLATE_506 506 +#define RACE_PUFFER_SPORE_507 507 +#define RACE_STONE_RING_508 508 +#define RACE_ROOT_TENTACLE_509 509 +#define RACE_RUNIC_SYMBOL_510 510 +#define RACE_SALTPETTER_BOMB_511 511 +#define RACE_FLOATING_SKULL_512 512 +#define RACE_SPIKE_TRAP_513 513 +#define RACE_TOTEM_514 514 +#define RACE_WEB_515 515 +#define RACE_WICKER_BASKET_516 516 +#define RACE_NIGHTMARE_517 517 +#define RACE_HORSE_518 518 +#define RACE_UNICORN_519 519 +#define RACE_BIXIE_520 520 +#define RACE_CENTAUR_521 521 +#define RACE_DRAKKIN_522 522 +#define RACE_GIANT_523 523 +#define RACE_GNOLL_524 524 +#define RACE_GRIFFIN_525 525 +#define RACE_GIANT_SHADE_526 526 +#define RACE_HARPY_527 527 +#define RACE_MAMMOTH_528 528 +#define RACE_SATYR_529 529 +#define RACE_DRAGON_530 530 +#define RACE_DRAGON_531 531 +#define RACE_DYNLETH_532 532 +#define RACE_BOAT_533 533 +#define RACE_WEAPON_RACK_534 534 +#define RACE_ARMOR_RACK_535 535 +#define RACE_HONEY_POT_536 536 +#define RACE_JUM_JUM_BUCKET_537 537 +#define RACE_PLANT_538 538 +#define RACE_PLANT_539 539 +#define RACE_PLANT_540 540 +#define RACE_TOOLBOX_541 541 +#define RACE_WINE_CASK_542 542 +#define RACE_STONE_JUG_543 543 +#define RACE_ELVEN_BOAT_544 544 +#define RACE_GNOMISH_BOAT_545 545 +#define RACE_BARREL_BARGE_SHIP_546 546 +#define RACE_GOO_547 547 +#define RACE_GOO_548 548 +#define RACE_GOO_549 549 +#define RACE_MERCHANT_SHIP_550 550 +#define RACE_PIRATE_SHIP_551 551 +#define RACE_GHOST_SHIP_552 552 +#define RACE_BANNER_553 553 +#define RACE_BANNER_554 554 +#define RACE_BANNER_555 555 +#define RACE_BANNER_556 556 +#define RACE_BANNER_557 557 +#define RACE_AVIAK_558 558 +#define RACE_BEETLE_559 559 +#define RACE_GORILLA_560 560 +#define RACE_KEDGE_561 561 +#define RACE_KERRAN_562 562 +#define RACE_SHISSAR_563 563 +#define RACE_SIREN_564 564 +#define RACE_SPHINX_565 565 +#define RACE_HUMAN_566 566 +#define RACE_CAMPFIRE_567 567 +#define RACE_BROWNIE_568 568 +#define RACE_DRAGON_569 569 +#define RACE_EXOSKELETON_570 570 +#define RACE_GHOUL_571 571 +#define RACE_CLOCKWORK_GUARDIAN_572 572 +#define RACE_MANTRAP_573 573 +#define RACE_MINOTAUR_574 574 +#define RACE_SCARECROW_575 575 +#define RACE_SHADE_576 576 +#define RACE_ROTOCOPTER_577 577 +#define RACE_TENTACLE_TERROR_578 578 +#define RACE_WEREORC_579 579 +#define RACE_WORG_580 580 +#define RACE_WYVERN_581 581 +#define RACE_CHIMERA_582 582 +#define RACE_KIRIN_583 583 +#define RACE_PUMA_584 584 +#define RACE_BOULDER_585 585 +#define RACE_BANNER_586 586 +#define RACE_ELVEN_GHOST_587 587 +#define RACE_HUMAN_GHOST_588 588 +#define RACE_CHEST_589 589 +#define RACE_CHEST_590 590 +#define RACE_CRYSTAL_591 591 +#define RACE_COFFIN_592 592 +#define RACE_GUARDIAN_CPU_593 593 +#define RACE_WORG_594 594 +#define RACE_MANSION_595 595 +#define RACE_FLOATING_ISLAND_596 596 +#define RACE_CRAGSLITHER_597 597 +#define RACE_WRULON_598 598 +#define RACE_SPELL_PARTICLE_1_599 599 +#define RACE_INVISIBLE_MAN_OF_ZOMM_600 600 +#define RACE_ROBOCOPTER_OF_ZOMM_601 601 +#define RACE_BURYNAI_602 602 +#define RACE_FROG_603 603 +#define RACE_DRACOLICH_604 604 +#define RACE_IKSAR_GHOST_605 605 +#define RACE_IKSAR_SKELETON_606 606 +#define RACE_MEPHIT_607 607 +#define RACE_MUDDITE_608 608 +#define RACE_RAPTOR_609 609 +#define RACE_SARNAK_610 610 +#define RACE_SCORPION_611 611 +#define RACE_TSETSIAN_612 612 +#define RACE_WURM_613 613 +#define RACE_BALROG_614 614 +#define RACE_HYDRA_CRYSTAL_615 615 +#define RACE_CRYSTAL_SPHERE_616 616 +#define RACE_GNOLL_617 617 +#define RACE_SOKOKAR_618 618 +#define RACE_STONE_PYLON_619 619 +#define RACE_DEMON_VULTURE_620 620 +#define RACE_WAGON_621 621 +#define RACE_GOD_OF_DISCORD_622 622 +#define RACE_WRULON_MOUNT_623 623 +#define RACE_OGRE_NPC_MALE_624 624 +#define RACE_SOKOKAR_MOUNT_625 625 +#define RACE_GIANT_626 626 +#define RACE_SOKOKAR_MOUNT_627 627 +#define RACE_10TH_ANNIVERSARY_BANNER_628 628 +#define RACE_10TH_ANNIVERSARY_CAKE_629 629 +#define RACE_WINE_CASK_630 630 +#define RACE_HYDRA_MOUNT_631 631 +#define RACE_HYDRA_NPC_632 632 +#define RACE_WEDDING_FLOWERS_633 633 +#define RACE_WEDDING_ARBOR_634 634 +#define RACE_WEDDING_ALTAR_635 635 +#define RACE_POWDER_KEG_636 636 +#define RACE_APEXUS_637 637 +#define RACE_BELLIKOS_638 638 +#define RACE_BRELLS_FIRST_CREATION_639 639 +#define RACE_BRELL_640 640 +#define RACE_CRYSTALSKIN_AMBULOID_641 641 +#define RACE_CLIKNAR_QUEEN_642 642 +#define RACE_CLIKNAR_SOLDIER_643 643 +#define RACE_CLIKNAR_WORKER_644 644 +#define RACE_COLDAIN_645 645 +#define RACE_COLDAIN_646 646 +#define RACE_CRYSTALSKIN_SESSILOID_647 647 +#define RACE_GENARI_648 648 +#define RACE_GIGYN_649 649 +#define RACE_GREKEN_YOUNG_ADULT_650 650 +#define RACE_GREKEN_YOUNG_651 651 +#define RACE_CLIKNAR_MOUNT_652 652 +#define RACE_TELMIRA_653 653 +#define RACE_SPIDER_MOUNT_654 654 +#define RACE_BEAR_MOUNT_655 655 +#define RACE_RAT_MOUNT_656 656 +#define RACE_SESSILOID_MOUNT_657 657 +#define RACE_MORELL_THULE_658 658 +#define RACE_MARIONETTE_659 659 +#define RACE_BOOK_DERVISH_660 660 +#define RACE_TOPIARY_LION_661 661 +#define RACE_ROTDOG_662 662 +#define RACE_AMYGDALAN_663 663 +#define RACE_SANDMAN_664 664 +#define RACE_GRANDFATHER_CLOCK_665 665 +#define RACE_GINGERBREAD_MAN_666 666 +#define RACE_BEEFEATER_667 667 +#define RACE_RABBIT_668 668 +#define RACE_BLIND_DREAMER_669 669 +#define RACE_CAZIC_THULE_670 670 +#define RACE_TOPIARY_LION_MOUNT_671 671 +#define RACE_ROT_DOG_MOUNT_672 672 +#define RACE_GORAL_MOUNT_673 673 +#define RACE_SELYRAN_MOUNT_674 674 +#define RACE_SCLERA_MOUNT_675 675 +#define RACE_BRAXY_MOUNT_676 676 +#define RACE_KANGON_MOUNT_677 677 +#define RACE_ERUDITE_678 678 +#define RACE_WURM_MOUNT_679 679 +#define RACE_RAPTOR_MOUNT_680 680 +#define RACE_INVISIBLE_MAN_681 681 +#define RACE_WHIRLIGIG_682 682 +#define RACE_GNOMISH_BALLOON_683 683 +#define RACE_GNOMISH_ROCKET_PACK_684 684 +#define RACE_GNOMISH_HOVERING_TRANSPORT_685 685 +#define RACE_SELYRAH_686 686 +#define RACE_GORAL_687 687 +#define RACE_BRAXI_688 688 +#define RACE_KANGON_689 689 +#define RACE_INVISIBLE_MAN_690 690 +#define RACE_FLOATING_TOWER_691 691 +#define RACE_EXPLOSIVE_CART_692 692 +#define RACE_BLIMP_SHIP_693 693 +#define RACE_TUMBLEWEED_694 694 +#define RACE_ALARAN_695 695 +#define RACE_SWINETOR_696 696 +#define RACE_TRIUMVIRATE_697 697 +#define RACE_HADAL_698 698 +#define RACE_HOVERING_PLATFORM_699 699 +#define RACE_PARASITIC_SCAVENGER_700 700 +#define RACE_GRENDLAEN_701 701 +#define RACE_SHIP_IN_A_BOTTLE_702 702 +#define RACE_ALARAN_SENTRY_STONE_703 703 +#define RACE_DERVISH_704 704 +#define RACE_REGENERATION_POOL_705 705 +#define RACE_TELEPORTATION_STAND_706 706 +#define RACE_RELIC_CASE_707 707 +#define RACE_ALARAN_GHOST_708 708 +#define RACE_SKYSTRIDER_709 709 +#define RACE_WATER_SPOUT_710 710 +#define RACE_AVIAK_PULL_ALONG_711 711 +#define RACE_GELATINOUS_CUBE_712 712 +#define RACE_CAT_713 713 +#define RACE_ELK_HEAD_714 714 +#define RACE_HOLGRESH_715 715 +#define RACE_BEETLE_716 716 +#define RACE_VINE_MAW_717 717 +#define RACE_RATMAN_718 718 +#define RACE_FALLEN_KNIGHT_719 719 +#define RACE_FLYING_CARPET_720 720 +#define RACE_CARRIER_HAND_721 721 +#define RACE_FALLEN_KNIGHT_722 722 +#define RACE_SERVANT_OF_SHADOW_723 723 +#define RACE_LUCLIN_724 724 +#define RACE_INTERACTIVE_OBJECT_2250 2250 #endif diff --git a/common/rulesys.cpp b/common/rulesys.cpp index 82d471745..3ce748fb9 100644 --- a/common/rulesys.cpp +++ b/common/rulesys.cpp @@ -236,46 +236,51 @@ void RuleManager::SaveRules(Database *database, const char *ruleset_name) { } bool RuleManager::LoadRules(Database *database, const char *ruleset_name) { - - int ruleset_id = GetRulesetID(database, ruleset_name); + + int ruleset_id = this->GetRulesetID(database, ruleset_name); if (ruleset_id < 0) { Log(Logs::Detail, Logs::Rules, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset_name); - return(false); + return (false); } Log(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", ruleset_name, ruleset_id); m_activeRuleset = ruleset_id; - m_activeName = ruleset_name; + m_activeName = ruleset_name; /* Load default ruleset values first if we're loading something other than default */ - if (strcasecmp(ruleset_name, "default") != 0){ + if (strcasecmp(ruleset_name, "default") != 0) { std::string default_ruleset_name = "default"; - int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str()); + int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str()); if (default_ruleset_id < 0) { - Log(Logs::Detail, Logs::Rules, "Failed to find default ruleset '%s' for load operation. Canceling.", default_ruleset_name.c_str()); - return(false); + Log(Logs::Detail, Logs::Rules, "Failed to find default ruleset '%s' for load operation. Canceling.", + default_ruleset_name.c_str()); + return (false); } Log(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", default_ruleset_name.c_str(), default_ruleset_id); - std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id = %d", default_ruleset_id); + std::string query = StringFormat( + "SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id = %d", + default_ruleset_id + ); + auto results = database->QueryDatabase(query); if (!results.Success()) return false; for (auto row = results.begin(); row != results.end(); ++row) - if (!SetRule(row[0], row[1], nullptr, false)) - Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]); + if (!SetRule(row[0], row[1], nullptr, false)) + Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]); } - std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id); - auto results = database->QueryDatabase(query); + std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id); + auto results = database->QueryDatabase(query); if (!results.Success()) return false; for (auto row = results.begin(); row != results.end(); ++row) - if (!SetRule(row[0], row[1], nullptr, false)) - Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]); + if (!SetRule(row[0], row[1], nullptr, false)) + Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]); return true; } @@ -283,7 +288,7 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) { void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) { char value_string[100]; - switch(type) { + switch (type) { case IntRule: sprintf(value_string, "%d", m_RuleIntValues[index]); break; @@ -291,22 +296,26 @@ void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) { sprintf(value_string, "%.13f", m_RuleRealValues[index]); break; case BoolRule: - sprintf(value_string, "%s", m_RuleBoolValues[index]?"true":"false"); + sprintf(value_string, "%s", m_RuleBoolValues[index] ? "true" : "false"); break; } - std::string query = StringFormat("REPLACE INTO rule_values " - "(ruleset_id, rule_name, rule_value) " - " VALUES(%d, '%s', '%s')", - m_activeRuleset, _GetRuleName(type, index), value_string); - auto results = database->QueryDatabase(query); + std::string query = StringFormat( + "REPLACE INTO rule_values " + "(ruleset_id, rule_name, rule_value) " + " VALUES(%d, '%s', '%s')", + m_activeRuleset, + _GetRuleName(type, index), + value_string + ); + database->QueryDatabase(query); } int RuleManager::GetRulesetID(Database *database, const char *ruleset_name) { - uint32 len = strlen(ruleset_name); + uint32 len = static_cast(strlen(ruleset_name)); auto rst = new char[2 * len + 1]; database->DoEscapeString(rst, ruleset_name, len); diff --git a/common/ruletypes.h b/common/ruletypes.h index 9846273bf..c89213368 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -156,7 +156,9 @@ RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound beh RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server +RULE_BOOL(Character, AllowCrossClassTrainers, false) RULE_BOOL(Character, PetsUseReagents, true) //Pets use reagent on spells +RULE_BOOL(Character, DismountWater, true) // Dismount horses when entering water RULE_CATEGORY_END() RULE_CATEGORY(Mercs) @@ -548,6 +550,7 @@ RULE_BOOL(Aggro, AllowTickPulling, false) // tick pulling is an exploit in an NP RULE_BOOL(Aggro, UseLevelAggro, true) // Level 18+ and Undead will aggro regardless of level difference. (this will disabled Rule:IntAggroThreshold if set to true) RULE_INT(Aggro, ClientAggroCheckInterval, 6) // Interval in which clients actually check for aggro - in seconds RULE_REAL(Aggro, PetAttackRange, 40000.0) // max squared range /pet attack works at default is 200 +RULE_BOOL(Aggro, NPCAggroMaxDistanceEnabled, true) /* If enabled, NPC's will drop aggro beyond 600 units or what is defined at the zone level */ RULE_CATEGORY_END() RULE_CATEGORY(TaskSystem) diff --git a/common/say_link.cpp b/common/say_link.cpp index e2b43c107..a215bdc46 100644 --- a/common/say_link.cpp +++ b/common/say_link.cpp @@ -29,7 +29,7 @@ bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body) { memset(&say_link_body_struct, 0, sizeof(say_link_body_struct)); - if (say_link_body.length() != EQEmu::constants::SayLinkBodySize) + if (say_link_body.length() != EQEmu::constants::SAY_LINK_BODY_SIZE) return false; say_link_body_struct.action_id = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16); @@ -68,7 +68,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB (0xFFFFFFFF & say_link_body_struct.hash) ); - if (say_link_body.length() != EQEmu::constants::SayLinkBodySize) + if (say_link_body.length() != EQEmu::constants::SAY_LINK_BODY_SIZE) return false; return true; @@ -88,25 +88,25 @@ const std::string& EQEmu::SayLinkEngine::GenerateLink() generate_body(); generate_text(); - if ((m_LinkBody.length() == EQEmu::constants::SayLinkBodySize) && (m_LinkText.length() > 0)) { + if ((m_LinkBody.length() == EQEmu::constants::SAY_LINK_BODY_SIZE) && (m_LinkText.length() > 0)) { m_Link.push_back(0x12); m_Link.append(m_LinkBody); m_Link.append(m_LinkText); m_Link.push_back(0x12); } - if ((m_Link.length() == 0) || (m_Link.length() > (EQEmu::constants::SayLinkMaximumSize))) { + if ((m_Link.length() == 0) || (m_Link.length() > (EQEmu::constants::SAY_LINK_MAXIMUM_SIZE))) { m_Error = true; m_Link = ""; Log(Logs::General, Logs::Error, "SayLinkEngine::GenerateLink() failed to generate a useable say link"); Log(Logs::General, Logs::Error, ">> LinkType: %i, Lengths: {link: %u(%u), body: %u(%u), text: %u(%u)}", m_LinkType, m_Link.length(), - EQEmu::constants::SayLinkMaximumSize, + EQEmu::constants::SAY_LINK_MAXIMUM_SIZE, m_LinkBody.length(), - EQEmu::constants::SayLinkBodySize, + EQEmu::constants::SAY_LINK_BODY_SIZE, m_LinkText.length(), - EQEmu::constants::SayLinkTextSize + EQEmu::constants::SAY_LINK_TEXT_SIZE ); Log(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str()); Log(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str()); diff --git a/common/serialize_buffer.cpp b/common/serialize_buffer.cpp new file mode 100644 index 000000000..065bd9f2d --- /dev/null +++ b/common/serialize_buffer.cpp @@ -0,0 +1,23 @@ +#include "serialize_buffer.h" + +void SerializeBuffer::Grow(size_t new_size) +{ + assert(new_size > m_capacity); + auto new_buffer = new unsigned char[new_size * 2]; + memset(new_buffer, 0, new_size * 2); + + if (m_buffer) + memcpy(new_buffer, m_buffer, m_capacity); + m_capacity = new_size * 2; + delete[] m_buffer; + m_buffer = new_buffer; +} + +void SerializeBuffer::Reset() +{ + delete[] m_buffer; + m_buffer = nullptr; + m_capacity = 0; + m_pos = 0; +} + diff --git a/common/serialize_buffer.h b/common/serialize_buffer.h new file mode 100644 index 000000000..9b350b4fa --- /dev/null +++ b/common/serialize_buffer.h @@ -0,0 +1,199 @@ +#ifndef SERIALIZE_BUFFER_H +#define SERIALIZE_BUFFER_H + +#include +#include +#include +#include + +class SerializeBuffer +{ +public: + SerializeBuffer() : m_buffer(nullptr), m_capacity(0), m_pos(0) {} + + explicit SerializeBuffer(size_t size) : m_capacity(size), m_pos(0) + { + m_buffer = new unsigned char[size]; + memset(m_buffer, 0, size); + } + + SerializeBuffer(const SerializeBuffer &rhs) + : m_buffer(new unsigned char[rhs.m_capacity]), m_capacity(rhs.m_capacity), m_pos(rhs.m_pos) + { + memcpy(m_buffer, rhs.m_buffer, rhs.m_capacity); + } + + SerializeBuffer &operator=(const SerializeBuffer &rhs) + { + if (this != &rhs) { + delete[] m_buffer; + m_buffer = new unsigned char[rhs.m_capacity]; + m_capacity = rhs.m_capacity; + m_pos = rhs.m_pos; + memcpy(m_buffer, rhs.m_buffer, m_capacity); + } + return *this; + } + + SerializeBuffer(SerializeBuffer &&rhs) : m_buffer(rhs.m_buffer), m_capacity(rhs.m_capacity), m_pos(rhs.m_pos) + { + rhs.m_buffer = nullptr; + rhs.m_capacity = 0; + rhs.m_pos = 0; + } + + SerializeBuffer &operator=(SerializeBuffer &&rhs) + { + if (this != &rhs) { + delete[] m_buffer; + + m_buffer = rhs.m_buffer; + m_capacity = rhs.m_capacity; + m_pos = rhs.m_pos; + + rhs.m_buffer = nullptr; + rhs.m_capacity = 0; + rhs.m_pos = 0; + } + return *this; + } + + ~SerializeBuffer() { delete[] m_buffer; } + + void WriteUInt8(uint8_t v) + { + if (m_pos + sizeof(uint8_t) > m_capacity) + Grow(m_capacity + sizeof(uint8_t)); + *(uint8_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(uint8_t); + } + + void WriteUInt16(uint16_t v) + { + if (m_pos + sizeof(uint16_t) > m_capacity) + Grow(m_capacity + sizeof(uint16_t)); + *(uint16_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(uint16_t); + } + + void WriteUInt32(uint32_t v) + { + if (m_pos + sizeof(uint32_t) > m_capacity) + Grow(m_capacity + sizeof(uint32_t)); + *(uint32_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(uint32_t); + } + + void WriteUInt64(uint64_t v) + { + if (m_pos + sizeof(uint64_t) > m_capacity) + Grow(m_capacity + sizeof(uint64_t)); + *(uint64_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(uint64_t); + } + + void WriteInt8(int8_t v) + { + if (m_pos + sizeof(int8_t) > m_capacity) + Grow(m_capacity + sizeof(int8_t)); + *(int8_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(int8_t); + } + + void WriteInt16(int16_t v) + { + if (m_pos + sizeof(int16_t) > m_capacity) + Grow(m_capacity + sizeof(int16_t)); + *(int16_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(int16_t); + } + + void WriteInt32(int32_t v) + { + if (m_pos + sizeof(int32_t) > m_capacity) + Grow(m_capacity + sizeof(int32_t)); + *(int32_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(int32_t); + } + + void WriteInt64(int64_t v) + { + if (m_pos + sizeof(int64_t) > m_capacity) + Grow(m_capacity + sizeof(int64_t)); + *(int64_t *)(m_buffer + m_pos) = v; + m_pos += sizeof(int64_t); + } + + void WriteFloat(float v) + { + if (m_pos + sizeof(float) > m_capacity) + Grow(m_capacity + sizeof(float)); + *(float *)(m_buffer + m_pos) = v; + m_pos += sizeof(float); + } + + void WriteDouble(double v) + { + if (m_pos + sizeof(double) > m_capacity) + Grow(m_capacity + sizeof(double)); + *(double *)(m_buffer + m_pos) = v; + m_pos += sizeof(double); + } + + void WriteString(const char *str) + { + assert(str != nullptr); + auto len = strlen(str) + 1; + if (m_pos + len > m_capacity) + Grow(m_capacity + len); + memcpy(m_buffer + m_pos, str, len); + m_pos += len; + } + + void WriteString(const std::string &str) + { + auto len = str.length() + 1; + if (m_pos + len > m_capacity) + Grow(m_capacity + len); + memcpy(m_buffer + m_pos, str.c_str(), len); + m_pos += len; + } + + void WriteLengthString(uint32_t len, const char *str) + { + assert(str != nullptr); + if (m_pos + len + sizeof(uint32_t) > m_capacity) + Grow(m_capacity + len + sizeof(uint32_t)); + *(uint32_t *)(m_buffer + m_pos) = len; + m_pos += sizeof(uint32_t); + memcpy(m_buffer + m_pos, str, len); + m_pos += len; + } + + void WriteLengthString(const std::string &str) + { + uint32_t len = str.length(); + if (m_pos + len + sizeof(uint32_t) > m_capacity) + Grow(m_capacity + len + sizeof(uint32_t)); + *(uint32_t *)(m_buffer + m_pos) = len; + m_pos += sizeof(uint32_t); + memcpy(m_buffer + m_pos, str.c_str(), len); + m_pos += len; + } + + size_t size() const { return m_pos; } + size_t length() const { return size(); } + size_t capacity() const { return m_capacity; } + const unsigned char *buffer() const { return m_buffer; } + + friend class BasePacket; + +private: + void Grow(size_t new_size); + void Reset(); + unsigned char *m_buffer; + size_t m_capacity; + size_t m_pos; +}; + +#endif /* !SERIALIZE_BUFFER_H */ diff --git a/common/shareddb.cpp b/common/shareddb.cpp index a4c6e54d1..00fdaea96 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -151,8 +151,8 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list: std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i " "AND ((slotid >= 8000 AND slotid <= 8999) " "OR slotid = %i OR (slotid >= %i AND slotid <= %i) )", - char_id, EQEmu::inventory::slotCursor, - EQEmu::legacy::CURSOR_BAG_BEGIN, EQEmu::legacy::CURSOR_BAG_END); + char_id, EQEmu::invslot::slotCursor, + EQEmu::invbag::CURSOR_BAG_BEGIN, EQEmu::invbag::CURSOR_BAG_END); auto results = QueryDatabase(query); if (!results.Success()) { std::cout << "Clearing cursor failed: " << results.ErrorMessage() << std::endl; @@ -163,7 +163,7 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list: for(auto it = start; it != end; ++it, i++) { if (i > 8999) { break; } // shouldn't be anything in the queue that indexes this high EQEmu::ItemInstance *inst = *it; - int16 use_slot = (i == 8000) ? EQEmu::inventory::slotCursor : i; + int16 use_slot = (i == 8000) ? EQEmu::invslot::slotCursor : i; if (!SaveInventory(char_id, inst, use_slot)) { return false; } @@ -208,10 +208,12 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const EQE bool SharedDatabase::SaveInventory(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) { //never save tribute slots: - if (slot_id >= EQEmu::legacy::TRIBUTE_BEGIN && slot_id <= EQEmu::legacy::TRIBUTE_END) + if (slot_id >= EQEmu::invslot::TRIBUTE_BEGIN && slot_id <= EQEmu::invslot::TRIBUTE_END) + return true; + if (slot_id >= EQEmu::invslot::GUILD_TRIBUTE_BEGIN && slot_id <= EQEmu::invslot::GUILD_TRIBUTE_END) return true; - if (slot_id >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id <= EQEmu::legacy::SHARED_BANK_BAGS_END) { + if (slot_id >= EQEmu::invslot::SHARED_BANK_BEGIN && slot_id <= EQEmu::invbag::SHARED_BANK_BAGS_END) { // Shared bank inventory if (!inst) { return DeleteSharedBankSlot(char_id, slot_id); @@ -238,9 +240,9 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const EQEmu::ItemInstance* in bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) { // need to check 'inst' argument for valid pointer - uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 }; + uint32 augslot[EQEmu::invaug::SOCKET_COUNT] = { 0, 0, 0, 0, 0, 0 }; if (inst->IsClassCommon()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { EQEmu::ItemInstance *auginst = inst->GetItem(i); augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0; } @@ -270,7 +272,7 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstan if (inst->IsClassBag() && EQEmu::InventoryProfile::SupportsContainers(slot_id)) // Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID' // messages through attrition (and the modded code in SaveInventory) - for (uint8 idx = EQEmu::inventory::containerBegin; idx < inst->GetItem()->BagSlots && idx < EQEmu::inventory::ContainerCount; idx++) { + for (uint8 idx = EQEmu::invbag::SLOT_BEGIN; idx < inst->GetItem()->BagSlots && idx <= EQEmu::invbag::SLOT_END; idx++) { const EQEmu::ItemInstance* baginst = inst->GetItem(idx); SaveInventory(char_id, baginst, EQEmu::InventoryProfile::CalcSlotId(slot_id, idx)); } @@ -285,9 +287,9 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstan bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) { // need to check 'inst' argument for valid pointer - uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 }; + uint32 augslot[EQEmu::invaug::SOCKET_COUNT] = { 0, 0, 0, 0, 0, 0 }; if (inst->IsClassCommon()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { EQEmu::ItemInstance *auginst = inst->GetItem(i); augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0; } @@ -316,7 +318,7 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInsta if (inst->IsClassBag() && EQEmu::InventoryProfile::SupportsContainers(slot_id)) { // Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID' // messages through attrition (and the modded code in SaveInventory) - for (uint8 idx = EQEmu::inventory::containerBegin; idx < inst->GetItem()->BagSlots && idx < EQEmu::inventory::ContainerCount; idx++) { + for (uint8 idx = EQEmu::invbag::SLOT_BEGIN; idx < inst->GetItem()->BagSlots && idx <= EQEmu::invbag::SLOT_END; idx++) { const EQEmu::ItemInstance* baginst = inst->GetItem(idx); SaveInventory(char_id, baginst, EQEmu::InventoryProfile::CalcSlotId(slot_id, idx)); } @@ -342,7 +344,7 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) { if (!EQEmu::InventoryProfile::SupportsContainers(slot_id)) return true; - int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::inventory::containerBegin); + int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::invbag::SLOT_BEGIN); query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid >= %i AND slotid < %i", char_id, base_slot_id, (base_slot_id+10)); results = QueryDatabase(query); @@ -368,7 +370,7 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) { if (!EQEmu::InventoryProfile::SupportsContainers(slot_id)) return true; - int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::inventory::containerBegin); + int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::invbag::SLOT_BEGIN); query = StringFormat("DELETE FROM sharedbank WHERE acctid = %i " "AND slotid >= %i AND slotid < %i", account_id, base_slot_id, (base_slot_id+10)); @@ -474,7 +476,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool uint32 item_id = (uint32)atoi(row[1]); int8 charges = (int8)atoi(row[2]); - uint32 aug[EQEmu::inventory::SocketCount]; + uint32 aug[EQEmu::invaug::SOCKET_COUNT]; aug[0] = (uint32)atoi(row[3]); aug[1] = (uint32)atoi(row[4]); aug[2] = (uint32)atoi(row[5]); @@ -495,7 +497,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool EQEmu::ItemInstance *inst = CreateBaseItem(item, charges); if (inst && item->IsClassCommon()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { if (aug[i]) inst->PutAugment(this, i, aug[i]); } @@ -570,7 +572,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv) uint16 charges = atoi(row[2]); uint32 color = atoul(row[3]); - uint32 aug[EQEmu::inventory::SocketCount]; + uint32 aug[EQEmu::invaug::SOCKET_COUNT]; aug[0] = (uint32)atoul(row[4]); aug[1] = (uint32)atoul(row[5]); @@ -632,8 +634,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv) inst->SetOrnamentHeroModel(item->HerosForgeModel); if (instnodrop || - (((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN && slot_id <= EQEmu::legacy::EQUIPMENT_END) || - slot_id == EQEmu::inventory::slotPowerSource) && + (((slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN && slot_id <= EQEmu::invslot::EQUIPMENT_END) || + slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) && inst->GetItem()->Attuneable)) inst->SetAttuned(true); @@ -655,7 +657,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv) } if (item->IsClassCommon()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { if (aug[i]) inst->PutAugment(this, i, aug[i]); } @@ -712,7 +714,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::Inventor int8 charges = atoi(row[2]); uint32 color = atoul(row[3]); - uint32 aug[EQEmu::inventory::SocketCount]; + uint32 aug[EQEmu::invaug::SOCKET_COUNT]; aug[0] = (uint32)atoi(row[4]); aug[1] = (uint32)atoi(row[5]); aug[2] = (uint32)atoi(row[6]); @@ -773,7 +775,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::Inventor inst->SetCharges(charges); if (item->IsClassCommon()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { if (aug[i]) inst->PutAugment(this, i, aug[i]); } diff --git a/common/spdat.cpp b/common/spdat.cpp index 064b8fb61..a5764a625 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -244,8 +244,7 @@ bool IsBeneficialSpell(uint16 spell_id) } else { // If the resisttype is not magic and spell is Bind Sight or Cast Sight // It's not beneficial - if (sai == SAI_Dispell_Sight && spells[spell_id].skill == 18 && - !IsEffectInSpell(spell_id, SE_VoiceGraft)) + if ((sai == SAI_Calm && IsEffectInSpell(spell_id, SE_Harmony)) || (sai == SAI_Calm_Song && IsEffectInSpell(spell_id, SE_BindSight)) || (sai == SAI_Dispell_Sight && spells[spell_id].skill == 18 && !IsEffectInSpell(spell_id, SE_VoiceGraft))) return false; } } diff --git a/common/timer.cpp b/common/timer.cpp index d5a90a0f2..120e3dea7 100644 --- a/common/timer.cpp +++ b/common/timer.cpp @@ -129,14 +129,13 @@ void Timer::SetTimer(uint32 set_timer_time) { } } -uint32 Timer::GetRemainingTime() { +uint32 Timer::GetRemainingTime() const { if (enabled) { - if (current_time-start_time > timer_time) + if (current_time - start_time > timer_time) return 0; else return (start_time + timer_time) - current_time; - } - else { + } else { return 0xFFFFFFFF; } } diff --git a/common/timer.h b/common/timer.h index f06f5bbe4..6678be952 100644 --- a/common/timer.h +++ b/common/timer.h @@ -40,7 +40,7 @@ public: void Disable(); void Start(uint32 set_timer_time=0, bool ChangeResetTimer = true); void SetTimer(uint32 set_timer_time=0); - uint32 GetRemainingTime(); + uint32 GetRemainingTime() const; inline const uint32& GetTimerTime() { return timer_time; } inline const uint32& GetSetAtTrigger() { return set_at_trigger; } void Trigger(); diff --git a/common/version.h b/common/version.h index a222c057c..b95c8ec1d 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9122 +#define CURRENT_BINARY_DATABASE_VERSION 9125 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9019 #else diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index cb5a25998..801f5fdd9 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -3,4 +3,5 @@ IF(EQEMU_BUILD_LUA) ENDIF(EQEMU_BUILD_LUA) ADD_SUBDIRECTORY(libuv) -ADD_SUBDIRECTORY(format) \ No newline at end of file +ADD_SUBDIRECTORY(format) +ADD_SUBDIRECTORY(recast) \ No newline at end of file diff --git a/libs/format/.github/pull_request_template b/libs/format/.github/pull_request_template new file mode 100644 index 000000000..dcfc0fdb0 --- /dev/null +++ b/libs/format/.github/pull_request_template @@ -0,0 +1,3 @@ + diff --git a/libs/format/.gitignore b/libs/format/.gitignore new file mode 100644 index 000000000..c57070c5f --- /dev/null +++ b/libs/format/.gitignore @@ -0,0 +1,19 @@ +bin/ +/_CPack_Packages +/doc/doxyxml +/doc/html +virtualenv +/Testing +/install_manifest.txt +*~ +*.a +*.so* +*.zip +cmake_install.cmake +CPack*.cmake +fmt-*.cmake +CTestTestfile.cmake +CMakeCache.txt +CMakeFiles +Makefile +run-msbuild.bat diff --git a/libs/format/.travis.yml b/libs/format/.travis.yml index d6b81a2a6..c359852e4 100644 --- a/libs/format/.travis.yml +++ b/libs/format/.travis.yml @@ -1,4 +1,5 @@ language: cpp +dist: trusty sudo: required # the doc target uses sudo to install dependencies os: @@ -22,12 +23,5 @@ matrix: - os: osx env: BUILD=Doc -addons: - apt: - sources: - - kubuntu-backports # cmake 2.8.12 - packages: - - cmake - script: - support/travis-build.py diff --git a/libs/format/CMakeLists.txt b/libs/format/CMakeLists.txt index 789b7e122..b08f9cbe9 100644 --- a/libs/format/CMakeLists.txt +++ b/libs/format/CMakeLists.txt @@ -1,6 +1,6 @@ message(STATUS "CMake version: ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) # Determine if fmt is built as a subproject (using add_subdirectory) # or if it is the master project. @@ -9,12 +9,22 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(MASTER_PROJECT ON) endif () +# Joins arguments and places the results in ${result_var}. +function(join result_var) + set(result ) + foreach (arg ${ARGN}) + set(result "${result}${arg}") + endforeach () + set(${result_var} "${result}" PARENT_SCOPE) +endfunction() + # Set the default CMAKE_BUILD_TYPE to Release. # This should be done before the project command since the latter can set # CMAKE_BUILD_TYPE itself (it does so for nmake). if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING - "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") + join(doc "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " + "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") + set(CMAKE_BUILD_TYPE Release CACHE STRING ${doc}) endif () option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) @@ -28,13 +38,17 @@ option(FMT_USE_CPP11 "Enable the addition of C++11 compiler flags." ON) project(FMT) # Starting with cmake 3.0 VERSION is part of the project command. -set(FMT_VERSION 3.0.0) -if (NOT FMT_VERSION MATCHES "^([0-9]+).([0-9]+).([0-9]+)$") - message(FATAL_ERROR "Invalid version format ${FMT_VERSION}.") +file(READ fmt/format.h format_h) +if (NOT format_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])") + message(FATAL_ERROR "Cannot get FMT_VERSION from format.h.") endif () -set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) -set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) -set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3}) +# Use math to skip leading zeros if any. +math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) +math(EXPR CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) +math(EXPR CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3}) +join(FMT_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}. + ${CPACK_PACKAGE_VERSION_PATCH}) +message(STATUS "Version: ${FMT_VERSION}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") diff --git a/libs/format/CONTRIBUTING.rst b/libs/format/CONTRIBUTING.rst new file mode 100644 index 000000000..506811d4a --- /dev/null +++ b/libs/format/CONTRIBUTING.rst @@ -0,0 +1,11 @@ +Contributing to fmt +=================== + +All C++ code must adhere to `Google C++ Style Guide +`_ with the following +exceptions: + +* Exceptions are permitted +* snake_case should be used instead of UpperCamelCase for function names + +Thanks for contributing! diff --git a/libs/format/ChangeLog.rst b/libs/format/ChangeLog.rst index 0e065451d..4a16be951 100644 --- a/libs/format/ChangeLog.rst +++ b/libs/format/ChangeLog.rst @@ -1,3 +1,113 @@ +4.0.0 - 2017-06-27 +------------------ + +* Removed old compatibility headers ``cppformat/*.h`` and CMake options (`#527 `_). Thanks `@maddinat0r (Alex Martin) `_. + +* Added ``string.h`` containing ``fmt::to_string()`` as alternative to ``std::to_string()`` as well as other string writer functionality (`#326 `_ and `#441 `_): + + .. code:: c++ + + #include "fmt/string.h" + + std::string answer = fmt::to_string(42); + + Thanks to `@glebov-andrey (Andrey Glebov) `_. + +* Moved ``fmt::printf()`` to new ``printf.h`` header and allowed ``%s`` as generic specifier (`#453 `_), made ``%.f`` more conformant to regular ``printf()`` (`#490 `_), added custom writer support (`#476 `_) and implemented missing custom argument formatting (`#339 `_ and `#340 `_): + + .. code:: c++ + + #include "fmt/printf.h" + + // %s format specifier can be used with any argument type. + fmt::printf("%s", 42); + + Thanks `@mojoBrendan `_, `@manylegged (Arthur Danskin) `_ and `@spacemoose (Glen Stark) `_. See also `#360 `_, `#335 `_ and `#331 `_. + +* Added ``container.h`` containing a ``BasicContainerWriter`` to write to containers like ``std::vector`` (`#450 `_). Thanks `@polyvertex (Jean-Charles Lefebvre) `_. + +* Added ``fmt::join()`` function that takes a range and formats its elements separated by a given string (`#466 `_): + + .. code:: c++ + + #include "fmt/format.h" + + std::vector v = {1.2, 3.4, 5.6}; + // Prints "(+01.20, +03.40, +05.60)". + fmt::print("({:+06.2f})", fmt::join(v.begin(), v.end(), ", ")); + + Thanks `@olivier80 `_. + +* Added support for custom formatting specifications to simplify customization of built-in formatting (`#444 `_). Thanks `@polyvertex (Jean-Charles Lefebvre) `_. See also `#439 `_. + +* Added ``fmt::format_system_error()`` for error code formatting (`#323 `_ and `#526 `_). Thanks `@maddinat0r (Alex Martin) `_. + +* Added thread-safe ``fmt::localtime()`` and ``fmt::gmtime()`` as replacement for the standard version to ``time.h`` (`#396 `_). Thanks `@codicodi `_. + +* Internal improvements to ``NamedArg`` and ``ArgLists`` (`#389 `_ and `#390 `_). Thanks `@chronoxor `_. + +* Fixed crash due to bug in ``FormatBuf`` (`#493 `_). Thanks `@effzeh `_. See also `#480 `_ and `#491 `_. + +* Fixed handling of wide strings in ``fmt::StringWriter``. + +* Improved compiler error messages (`#357 `_). + +* Fixed various warnings and issues with various compilers (`#494 `_, `#499 `_, `#483 `_, `#519 `_, `#485 `_, `#482 `_, `#475 `_, `#473 `_ and `#414 `_). Thanks `@chronoxor `_, `@zhaohuaxishi `_, `@pkestene (Pierre Kestener) `_, `@dschmidt (Dominik Schmidt) `_ and `@0x414c (Alexey Gorishny) `_ . + +* Improved CMake: targets are now namespaced (`#511 `_ and `#513 `_), supported header-only ``printf.h`` (`#354 `_), fixed issue with minimal supported library subset (`#418 `_, `#419 `_ and `#420 `_). Thanks `@bjoernthiel (Bjoern Thiel) `_, + `@niosHD (Mario Werner) `_, `@LogicalKnight (Sean LK) `_ and `@alabuzhev (Alex Alabuzhev) `_. + +* Improved documentation. Thanks to `@pwm1234 (Phil) `_ for `#393 `_. + +3.0.2 - 2017-06-14 +------------------ + +* Added ``FMT_VERSION`` macro (`#411 `_). + +* Used ``FMT_NULL`` instead of literal ``0`` (`#409 `_). Thanks `@alabuzhev (Alex Alabuzhev) `_. + +* Added extern templates for ``format_float`` (`#413 `_). + +* Fixed implicit conversion issue (`#507 `_). + +* Fixed signbit detection (`#423 `_). + +* Fixed naming collision (`#425 `_). + +* Fixed missing intrinsic for C++/CLI (`#457 `_). Thanks `@calumr (Calum Robinson) `_ + +* Fixed Android detection (`#458 `_). Thanks `@Gachapen (Magnus Bjerke Vik) `_. + +* Use lean ``windows.h`` if not in header-only mode (`#503 `_). Thanks `@Quentin01 (Quentin Buathier) `_. + +* Fixed issue with CMake exporting C++11 flag (`#445 `_). Thanks `@EricWF (Eric) `_. + +* Fixed issue with nvcc and MSVC compiler bug and MinGW (`#505 `_). + +* Fixed DLL issues (`#469 `_ and `#502 `_). Thanks `@richardeakin (Richard Eakin) `_ and `@AndreasSchoenle (Andreas Schönle) `_. + +* Fixed test compilation under FreeBSD (`#433 `_). + +* Fixed various warnings (`#403 `_, `#410 `_ and `#510 `_). Thanks `@Lecetem `_, `@chenhayat (Chen Hayat) `_ and `@trozen `_. + +* Removed redundant include (`#479 `_). + +* Fixed documentation issues. + +3.0.1 - 2016-11-01 +------------------ +* Fixed handling of thousands seperator (`#353 `_) + +* Fixed handling of ``unsigned char`` strings (`#373 `_) + +* Corrected buffer growth when formatting time (`#367 `_) + +* Removed warnings under MSVC and clang (`#318 `_, `#250 `_, also merged `#385 `_ and `#361 `_). Thanks `@jcelerier (Jean-Michaël Celerier) `_ and `@nmoehrle (Nils Moehrle) `_. + +* Fixed compilation issues under Android (`#327 `_, `#345 `_ and `#381 `_), FreeBSD (`#358 `_), Cygwin (`#388 `_), MinGW (`#355 `_) as well as other issues (`#350 `_, `#366 `_, `#348 `_, `#402 `_, `#405 `_). Thanks to `@dpantele (Dmitry) `_, `@hghwng (Hugh Wang) `_, `@arvedarved (Tilman Keskinöz) `_, `@LogicalKnight (Sean) `_ and `@JanHellwig (Jan Hellwig) `_. + +* Fixed some documentation issues and extended specification (`#320 `_, `#333 `_, `#347 `_, `#362 `_). Thanks to `@smellman (Taro Matsuzawa aka. btm) `_. + 3.0.0 - 2016-05-07 ------------------ diff --git a/libs/format/README.rst b/libs/format/README.rst index f9707ff53..ea2a6da41 100644 --- a/libs/format/README.rst +++ b/libs/format/README.rst @@ -20,9 +20,11 @@ alternative to IOStreams. Features -------- -* Two APIs: faster concatenation-based write API and slower (but still - very fast) replacement-based format API with positional arguments for - localization. +* Two APIs: faster concatenation-based `write API + `_ and slower, + but still very fast, replacement-based `format API + `_ with positional arguments + for localization. * Write API similar to the one used by IOStreams but stateless allowing faster implementation. * Format API with `format string syntax @@ -35,10 +37,10 @@ Features * Support for user-defined types. * High speed: performance of the format API is close to that of glibc's `printf `_ - and better than performance of IOStreams. See `Speed tests`_ and + and better than the performance of IOStreams. See `Speed tests`_ and `Fast integer to string conversion in C++ `_. -* Small code size both in terms of source code (format consists of a single +* Small code size both in terms of source code (the core library consists of a single header file and a single source file) and compiled code. See `Compile time and code bloat`_. * Reliability: the library has an extensive set of `unit tests @@ -89,6 +91,8 @@ An object of any user-defined type for which there is an overloaded .. code:: c++ + #include "fmt/ostream.h" + class Date { int year_, month_, day_; public: @@ -132,6 +136,12 @@ Projects using this library * `AMPL/MP `_: An open-source library for mathematical programming +* `CUAUV `_: Cornell University's autonomous underwater vehicle + +* `Drake `_: A planning, control, and analysis toolbox for nonlinear dynamical systems (MIT) + +* `Envoy `_: C++ L7 proxy and communication bus (Lyft) + * `HarpyWar/pvpgn `_: Player vs Player Gaming Network with tweaks @@ -139,6 +149,8 @@ Projects using this library * `Keypirinha `_: A semantic launcher for Windows +* `Kodi `_ (formerly xbmc): Home theater software + * `Lifeline `_: A 2D game * `MongoDB Smasher `_: A small tool to generate randomized datasets @@ -158,6 +170,12 @@ Projects using this library * `Salesforce Analytics Cloud `_: Business intelligence software +* `Scylla `_: A Cassandra-compatible NoSQL data store that can handle + 1 million transactions per second on a single server + +* `Seastar `_: An advanced, open-source C++ framework for + high-performance server applications on modern hardware + * `spdlog `_: Super fast C++ logging library * `Stellar `_: Financial platform @@ -390,6 +408,11 @@ It only applies if you distribute the documentation of fmt. Acknowledgments --------------- +The fmt library is maintained by Victor Zverovich (`vitaut `_) +and Jonathan Müller (`foonathan `_) with contributions from many +other people. See `Contributors `_ and `Releases `_ for some of the names. Let us know if your contribution +is not listed or mentioned incorrectly and we'll make it right. + The benchmark section of this readme file and the performance tests are taken from the excellent `tinyformat `_ library written by Chris Foster. Boost Format library is acknowledged transitively diff --git a/libs/format/cppformat/format.h b/libs/format/cppformat/format.h deleted file mode 100644 index 3fbf86b89..000000000 --- a/libs/format/cppformat/format.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "../fmt/format.h" -#warning Including cppformat/format.h is deprecated. Include fmt/format.h instead. diff --git a/libs/format/cppformat/posix.h b/libs/format/cppformat/posix.h deleted file mode 100644 index 97b6fadcd..000000000 --- a/libs/format/cppformat/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "../fmt/posix.h" -#warning Including cppformat/posix.h is deprecated. Include fmt/posix.h instead. diff --git a/libs/format/doc/CMakeLists.txt b/libs/format/doc/CMakeLists.txt index fc5a0a244..df3e9b1e9 100644 --- a/libs/format/doc/CMakeLists.txt +++ b/libs/format/doc/CMakeLists.txt @@ -5,6 +5,8 @@ if (NOT DOXYGEN) endif () add_custom_target(doc - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build.py ${FMT_VERSION}) + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build.py ${FMT_VERSION} + SOURCES build.py conf.py _templates/layout.html) -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ DESTINATION share/doc/fmt) +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ + DESTINATION share/doc/fmt OPTIONAL) diff --git a/libs/format/doc/_static/breathe.css b/libs/format/doc/_static/breathe.css new file mode 100644 index 000000000..2a1534b0a --- /dev/null +++ b/libs/format/doc/_static/breathe.css @@ -0,0 +1,28 @@ + +/* -- breathe specific styles ----------------------------------------------- */ + +/* So enum value descriptions are displayed inline to the item */ +.breatheenumvalues li tt + p { + display: inline; +} + +/* So parameter descriptions are displayed inline to the item */ +.breatheparameterlist li tt + p { + display: inline; +} + +.container .breathe-sectiondef { + width: inherit; +} + +.github-btn { + border: 0; + overflow: hidden; +} + +.jumbotron { + background-size: 100% 4px; + background-repeat: repeat-y; + color: white; + text-align: center; +} diff --git a/libs/format/doc/_templates/layout.html b/libs/format/doc/_templates/layout.html index 261e2eb4f..0ac2dec78 100644 --- a/libs/format/doc/_templates/layout.html +++ b/libs/format/doc/_templates/layout.html @@ -8,8 +8,9 @@ {# Google Analytics #} {%- for scriptfile in script_files %} diff --git a/libs/format/doc/build.py b/libs/format/doc/build.py index 9721e2986..55992b9ff 100644 --- a/libs/format/doc/build.py +++ b/libs/format/doc/build.py @@ -8,30 +8,35 @@ from distutils.version import LooseVersion def pip_install(package, commit=None, **kwargs): "Install package using pip." + min_version = kwargs.get('min_version') + if min_version: + from pkg_resources import get_distribution, DistributionNotFound + try: + installed_version = get_distribution(os.path.basename(package)).version + if LooseVersion(installed_version) >= min_version: + print('{} {} already installed'.format(package, min_version)) + return + except DistributionNotFound: + pass if commit: - check_version = kwargs.get('check_version', '') - #output = check_output(['pip', 'show', package.split('/')[1]]) - #if check_version in output: - # print('{} already installed'.format(package)) - # return - package = 'git+git://github.com/{0}.git@{1}'.format(package, commit) - print('Installing {}'.format(package)) - check_call(['pip', 'install', '--upgrade', package]) + package = 'git+https://github.com/{0}.git@{1}'.format(package, commit) + print('Installing {0}'.format(package)) + check_call(['pip', 'install', package]) -def build_docs(version='dev'): +def create_build_env(dirname='virtualenv'): # Create virtualenv. - doc_dir = os.path.dirname(os.path.realpath(__file__)) - virtualenv_dir = 'virtualenv' - check_call(['virtualenv', virtualenv_dir]) + if not os.path.exists(dirname): + check_call(['virtualenv', dirname]) import sysconfig scripts_dir = os.path.basename(sysconfig.get_path('scripts')) - activate_this_file = os.path.join(virtualenv_dir, scripts_dir, - 'activate_this.py') + activate_this_file = os.path.join(dirname, scripts_dir, 'activate_this.py') with open(activate_this_file) as f: exec(f.read(), dict(__file__=activate_this_file)) + # Import get_distribution after activating virtualenv to get info about + # the correct packages. + from pkg_resources import get_distribution, DistributionNotFound # Upgrade pip because installation of sphinx with pip 1.1 available on Travis # is broken (see #207) and it doesn't support the show command. - from pkg_resources import get_distribution, DistributionNotFound pip_version = get_distribution('pip').version if LooseVersion(pip_version) < LooseVersion('1.5.4'): print("Updating pip") @@ -46,27 +51,35 @@ def build_docs(version='dev'): except DistributionNotFound: pass # Install Sphinx and Breathe. - pip_install('fmtlib/sphinx', - '12dde8afdb0a7bb5576e2656692c3478c69d8cc3', - check_version='1.4a0.dev-20151013') + pip_install('sphinx-doc/sphinx', '12b83372ac9316e8cbe86e7fed889296a4cc29ee', + min_version='1.4.1.dev20160531') pip_install('michaeljones/breathe', - '1c9d7f80378a92cffa755084823a78bb38ee4acc') + '6b1c5bb7a1866f15fc328b8716258354b10c1daa', + min_version='4.2.0') + +def build_docs(version='dev', **kwargs): + doc_dir = kwargs.get('doc_dir', os.path.dirname(os.path.realpath(__file__))) + work_dir = kwargs.get('work_dir', '.') + include_dir = kwargs.get('include_dir', + os.path.join(os.path.dirname(doc_dir), 'fmt')) # Build docs. cmd = ['doxygen', '-'] p = Popen(cmd, stdin=PIPE) + doxyxml_dir = os.path.join(work_dir, 'doxyxml') p.communicate(input=r''' PROJECT_NAME = fmt GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO - INPUT = {0}/format.h {0}/ostream.h + INPUT = {0}/container.h {0}/format.h {0}/ostream.h \ + {0}/printf.h {0}/string.h QUIET = YES JAVADOC_AUTOBRIEF = YES AUTOLINK_SUPPORT = NO GENERATE_HTML = NO GENERATE_XML = YES - XML_OUTPUT = doxyxml + XML_OUTPUT = {1} ALIASES = "rst=\verbatim embed:rst" ALIASES += "endrst=\endverbatim" MACRO_EXPANSION = YES @@ -76,24 +89,29 @@ def build_docs(version='dev'): FMT_USE_USER_DEFINED_LITERALS=1 \ FMT_API= EXCLUDE_SYMBOLS = fmt::internal::* StringValue write_str - '''.format(os.path.join(os.path.dirname(doc_dir), 'fmt')).encode('UTF-8')) + '''.format(include_dir, doxyxml_dir).encode('UTF-8')) if p.returncode != 0: raise CalledProcessError(p.returncode, cmd) + html_dir = os.path.join(work_dir, 'html') + versions = ['3.0.0', '2.0.0', '1.1.0'] check_call(['sphinx-build', - '-Dbreathe_projects.format=' + os.path.join(os.getcwd(), 'doxyxml'), - '-Dversion=' + version, '-Drelease=' + version, '-Aversion=' + version, - '-b', 'html', doc_dir, 'html']) + '-Dbreathe_projects.format=' + os.path.abspath(doxyxml_dir), + '-Dversion=' + version, '-Drelease=' + version, + '-Aversion=' + version, '-Aversions=' + ','.join(versions), + '-b', 'html', doc_dir, html_dir]) try: check_call(['lessc', '--clean-css', '--include-path=' + os.path.join(doc_dir, 'bootstrap'), os.path.join(doc_dir, 'fmt.less'), - 'html/_static/fmt.css']) + os.path.join(html_dir, '_static', 'fmt.css')]) except OSError as e: if e.errno != errno.ENOENT: raise - print('lessc not found; make sure that Less (http://lesscss.org/) is installed') + print('lessc not found; make sure that Less (http://lesscss.org/) ' + + 'is installed') sys.exit(1) - return 'html' + return html_dir if __name__ == '__main__': + create_build_env() build_docs(sys.argv[1]) diff --git a/libs/format/doc/conf.py b/libs/format/doc/conf.py index 7af3e4815..1e9010e79 100644 --- a/libs/format/doc/conf.py +++ b/libs/format/doc/conf.py @@ -228,8 +228,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'format', u'format Documentation', - [u'Victor Zverovich'], 1) + ('index', 'fmt', u'fmt documentation', [u'Victor Zverovich'], 1) ] # If true, show URL addresses after external links. @@ -242,8 +241,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'format', u'format Documentation', - u'Victor Zverovich', 'format', 'One line description of project.', + ('index', 'fmt', u'fmt documentation', + u'Victor Zverovich', 'fmt', 'One line description of project.', 'Miscellaneous'), ] diff --git a/libs/format/doc/html/_sources/api.txt b/libs/format/doc/html/_sources/api.txt index 5270a68d4..8dbef39e1 100644 --- a/libs/format/doc/html/_sources/api.txt +++ b/libs/format/doc/html/_sources/api.txt @@ -11,8 +11,8 @@ namespace is usually omitted in examples. Format API ========== -The following functions use :ref:`format string syntax ` similar -to the one used by Python's `str.format +The following functions defined in ``fmt/format.h`` use :ref:`format string +syntax ` similar to the one used by Python's `str.format `_ function. They take *format_str* and *args* as arguments. @@ -22,6 +22,11 @@ arguments in the resulting string. *args* is an argument list representing arbitrary arguments. +The `performance of the format API +`_ is close +to that of glibc's ``printf`` and better than the performance of IOStreams. +For even better speed use the `write API`_. + .. _format: .. doxygenfunction:: format(CStringRef, ArgList) @@ -40,8 +45,9 @@ arguments in the resulting string. Date and time formatting ------------------------ -The library supports `strftime `_-like -date and time formatting:: +The library supports `strftime +`_-like date and time +formatting:: #include "fmt/time.h" @@ -52,6 +58,36 @@ date and time formatting:: The format string syntax is described in the documentation of `strftime `_. +Formatting user-defined types +----------------------------- + +A custom ``format_arg`` function may be implemented and used to format any +user-defined type. That is how date and time formatting described in the +previous section is implemented in :file:`fmt/time.h`. The following example +shows how to implement custom formatting for a user-defined structure. + +:: + + struct MyStruct { double a, b; }; + + void format_arg(fmt::BasicFormatter &f, + const char *&format_str, const MyStruct &s) { + f.writer().write("[MyStruct: a={:.1f}, b={:.2f}]", s.a, s.b); + } + + MyStruct m = { 1, 2 }; + std::string s = fmt::format("m={}", n); + // s == "m=[MyStruct: a=1.0, b=2.00]" + +Note in the example above the ``format_arg`` function ignores the contents of +``format_str`` so the type will always be formatted as specified. See +``format_arg`` in :file:`fmt/time.h` for an advanced example of how to use +the ``format_str`` argument to customize the formatted output. + +This section shows how to define a custom format function for a user-defined +type. The next section describes how to get ``fmt`` to use a conventional stream +output ``operator<<`` when one is defined for a user-defined type. + ``std::ostream`` support ------------------------ @@ -63,7 +99,7 @@ formatting of user-defined types that have overloaded ``operator<<``:: class Date { int year_, month_, day_; public: - Date(int year, int month, int day) : year_(year), month_(month), day_(day) {} + Date(int year, int month, int day): year_(year), month_(month), day_(day) {} friend std::ostream &operator<<(std::ostream &os, const Date &d) { return os << d.year_ << '-' << d.month_ << '-' << d.day_; @@ -75,8 +111,6 @@ formatting of user-defined types that have overloaded ``operator<<``:: .. doxygenfunction:: print(std::ostream&, CStringRef, ArgList) -.. doxygenfunction:: fprintf(std::ostream&, CStringRef, ArgList) - Argument formatters ------------------- @@ -86,7 +120,7 @@ custom argument formatter class:: // A custom argument formatter that formats negative integers as unsigned // with the ``x`` format specifier. class CustomArgFormatter : - public fmt::BasicArgFormatter { + public fmt::BasicArgFormatter { public: CustomArgFormatter(fmt::BasicFormatter &f, fmt::FormatSpec &s, const char *fmt) @@ -120,22 +154,43 @@ custom argument formatter class:: .. doxygenclass:: fmt::ArgFormatter :members: -Printf formatting functions ---------------------------- +Printf formatting +----------------- +The header ``fmt/printf.h`` provides ``printf``-like formatting functionality. The following functions use `printf format string syntax `_ with -a POSIX extension for positional arguments. +the POSIX extension for positional arguments. Unlike their standard +counterparts, the ``fmt`` functions are type-safe and throw an exception if an +argument type doesn't match its format specification. .. doxygenfunction:: printf(CStringRef, ArgList) .. doxygenfunction:: fprintf(std::FILE *, CStringRef, ArgList) +.. doxygenfunction:: fprintf(std::ostream&, CStringRef, ArgList) + .. doxygenfunction:: sprintf(CStringRef, ArgList) +.. doxygenclass:: fmt::PrintfFormatter + :members: + +.. doxygenclass:: fmt::BasicPrintfArgFormatter + :members: + +.. doxygenclass:: fmt::PrintfArgFormatter + :members: + Write API ========= +The write API provides classes for writing formatted data into character +streams. It is usually faster than the `format API`_ but, as IOStreams, +may result in larger compiled code size. The main writer class is +`~fmt::BasicMemoryWriter` which stores its output in a memory buffer and +provides direct access to it. It is possible to create custom writers that +store output elsewhere by subclassing `~fmt::BasicWriter`. + .. doxygenclass:: fmt::BasicWriter :members: @@ -145,6 +200,12 @@ Write API .. doxygenclass:: fmt::BasicArrayWriter :members: +.. doxygenclass:: fmt::BasicStringWriter + :members: + +.. doxygenclass:: fmt::BasicContainerWriter + :members: + .. doxygenfunction:: bin(int) .. doxygenfunction:: oct(int) @@ -169,6 +230,8 @@ Utilities .. doxygenclass:: fmt::ArgList :members: +.. doxygenfunction:: fmt::to_string(const T&) + .. doxygenclass:: fmt::BasicStringRef :members: @@ -185,6 +248,8 @@ System errors .. doxygenclass:: fmt::SystemError :members: +.. doxygenfunction:: fmt::format_system_error + .. doxygenclass:: fmt::WindowsError :members: @@ -202,7 +267,8 @@ A custom allocator class can be specified as a template argument to It is also possible to write a formatting function that uses a custom allocator:: - typedef std::basic_string, CustomAllocator> CustomString; + typedef std::basic_string, CustomAllocator> + CustomString; CustomString format(CustomAllocator alloc, fmt::CStringRef format_str, fmt::ArgList args) { diff --git a/libs/format/doc/html/_sources/index.txt b/libs/format/doc/html/_sources/index.txt index 4e17d4b54..ce9b7bf94 100644 --- a/libs/format/doc/html/_sources/index.txt +++ b/libs/format/doc/html/_sources/index.txt @@ -10,9 +10,9 @@ alternative to C++ IOStreams.
What users say:
- Thanks for creating this library. It’s been a hole in C++ for a long time. - I’ve used both boost::format and loki::SPrintf, and neither felt like the - right answer. This does. + Thanks for creating this library. It’s been a hole in C++ for a long + time. I’ve used both boost::format and loki::SPrintf, and neither felt + like the right answer. This does.
@@ -24,8 +24,8 @@ Format API The replacement-based Format API provides a safe alternative to ``printf``, ``sprintf`` and friends with comparable or `better performance `_. -The `format string syntax `_ is similar -to the one used by `str.format `_ +The `format string syntax `_ is similar to the one used by +`str.format `_ in Python: .. code:: c++ @@ -98,8 +98,8 @@ literal operators, they must be made visible with the directive Write API --------- -The concatenation-based Write API (experimental) provides a -`fast `_ +The concatenation-based Write API (experimental) provides a `fast +`_ stateless alternative to IOStreams: .. code:: c++ @@ -112,8 +112,9 @@ stateless alternative to IOStreams: Safety ------ -The library is fully type safe, automatic memory management prevents buffer overflow, -errors in format strings are reported using exceptions. For example, the code +The library is fully type safe, automatic memory management prevents buffer +overflow, errors in format strings are reported using exceptions. For example, +the code .. code:: c++ @@ -138,19 +139,21 @@ formatted into a narrow string. You can use a wide format string instead: fmt::format(L"Cyrillic letter {}", L'\x42e'); For comparison, writing a wide character to ``std::ostream`` results in -its numeric value being written to the stream (i.e. 1070 instead of letter 'ю' which -is represented by ``L'\x42e'`` if we use Unicode) which is rarely what is needed. +its numeric value being written to the stream (i.e. 1070 instead of letter 'ю' +which is represented by ``L'\x42e'`` if we use Unicode) which is rarely what is +needed. .. _portability: Portability ----------- -The library is highly portable. Here is an incomplete list of operating systems and -compilers where it has been tested and known to work: +The library is highly portable. Here is an incomplete list of operating systems +and compilers where it has been tested and known to work: -* 64-bit (amd64) GNU/Linux with GCC 4.4.3, `4.6.3 `_, - 4.7.2, 4.8.1 and Intel C++ Compiler (ICC) 14.0.2 +* 64-bit (amd64) GNU/Linux with GCC 4.4.3, + `4.6.3 `_, 4.7.2, 4.8.1, and Intel C++ + Compiler (ICC) 14.0.2 * 32-bit (i386) GNU/Linux with GCC 4.4.3, 4.6.3 @@ -161,21 +164,21 @@ compilers where it has been tested and known to work: * 32-bit Windows with Visual C++ 2010 -Although the library uses C++11 features when available, it also works with older -compilers and standard library implementations. The only thing to keep in mind -for C++98 portability: +Although the library uses C++11 features when available, it also works with +older compilers and standard library implementations. The only thing to keep in +mind for C++98 portability: * Variadic templates: minimum GCC 4.4, Clang 2.9 or VS2013. This feature allows - the Format API to accept an unlimited number of arguments. With older compilers - the maximum is 15. + the Format API to accept an unlimited number of arguments. With older + compilers the maximum is 15. -* User-defined literals: minimum GCC 4.7, Clang 3.1 or VS2015. The suffixes - ``_format`` and ``_a`` are functionally equivalent to the functions +* User-defined literals: minimum GCC 4.7, Clang 3.1 or VS2015. The suffixes + ``_format`` and ``_a`` are functionally equivalent to the functions ``fmt::format`` and ``fmt::arg``. -The output of all formatting functions is consistent across platforms. In particular, -formatting a floating-point infinity always gives ``inf`` while the output -of ``printf`` is platform-dependent in this case. For example, +The output of all formatting functions is consistent across platforms. In +particular, formatting a floating-point infinity always gives ``inf`` while the +output of ``printf`` is platform-dependent in this case. For example, .. code:: @@ -188,10 +191,10 @@ always prints ``inf``. Ease of Use ----------- -fmt has a small self-contained code base consisting of a single header file -and a single source file and no external dependencies. A permissive BSD `license -`_ allows using the library both -in open-source and commercial projects. +fmt has a small self-contained code base with the core library consisting of +a single header file and a single source file and no external dependencies. +A permissive BSD `license `_ allows +using the library both in open-source and commercial projects. .. raw:: html diff --git a/libs/format/doc/html/_sources/syntax.txt b/libs/format/doc/html/_sources/syntax.txt index feda3e44d..1051467a0 100644 --- a/libs/format/doc/html/_sources/syntax.txt +++ b/libs/format/doc/html/_sources/syntax.txt @@ -49,12 +49,10 @@ mini-language" or interpretation of the *format_spec*. Most built-in types support a common formatting mini-language, which is described in the next section. -A *format_spec* field can also include nested replacement fields within it. -These nested replacement fields can contain only an argument index; -format specifications are not allowed. Formatting is performed as if the -replacement fields within the format_spec are substituted before the -*format_spec* string is interpreted. This allows the formatting of a value -to be dynamically specified. +A *format_spec* field can also include nested replacement fields in certain +positions within it. These nested replacement fields can contain only an +argument id; format specifications are not allowed. This allows the +formatting of a value to be dynamically specified. See the :ref:`formatexamples` section for some examples. @@ -80,8 +78,8 @@ The general form of a *standard format specifier* is: sign: "+" | "-" | " " width: `integer` | "{" `arg_id` "}" precision: `integer` | "{" `arg_id` "}" - type: `int_type` | "c" | "e" | "E" | "f" | "F" | "g" | "G" | "p" | "s" - int_type: "b" | "B" | "d" | "o" | "x" | "X" + type: `int_type` | "a" | "A" | "c" | "e" | "E" | "f" | "F" | "g" | "G" | "p" | "s" + int_type: "b" | "B" | "d" | "n" | "o" | "x" | "X" The *fill* character can be any character other than '{' or '}'. The presence of a fill character is signaled by the character following it, which must be @@ -234,7 +232,7 @@ The available presentation types for floating-point values are: +=========+==========================================================+ | ``'a'`` | Hexadecimal floating point format. Prints the number in | | | base 16 with prefix ``"0x"`` and lower-case letters for | -| | digits above 9. Uses 'p' to indicate the exponent. | +| | digits above 9. Uses ``'p'`` to indicate the exponent. | +---------+----------------------------------------------------------+ | ``'A'`` | Same as ``'a'`` except it uses upper-case letters for | | | the prefix, digits above 9 and to indicate the exponent. | diff --git a/libs/format/doc/html/_sources/usage.txt b/libs/format/doc/html/_sources/usage.txt index 27d96edec..dff312dfa 100644 --- a/libs/format/doc/html/_sources/usage.txt +++ b/libs/format/doc/html/_sources/usage.txt @@ -54,6 +54,23 @@ To build a `shared library`__ set the ``BUILD_SHARED_LIBS`` CMake variable to __ http://en.wikipedia.org/wiki/Library_%28computing%29#Shared_libraries +Header-only usage with CMake +============================ + +In order to add ``fmtlib`` into an existing ``CMakeLists.txt`` file, you can add the ``fmt`` library directory into your main project, which will enable the ``fmt`` library:: + + add_subdirectory(fmt) + +If you have a project called ``foo`` that you would like to link against the fmt library in a header-only fashion, you can enable with with:: + + target_link_libraries(foo PRIVATE fmt::fmt-header-only) + +And then to ensure that the ``fmt`` library does not always get built, you can modify the call to ``add_subdirectory`` to read :: + + add_subdirectory(fmt EXCLUDE_FROM_ALL) + +This will ensure that the ``fmt`` library is exluded from calls to ``make``, ``make all``, or ``cmake --build .``. + Building the documentation ========================== @@ -62,7 +79,11 @@ system: * `Python `_ with pip and virtualenv * `Doxygen `_ -* `Less `_ with less-plugin-clean-css +* `Less `_ with ``less-plugin-clean-css``. + Ubuntu doesn't package the ``clean-css`` plugin so you should use ``npm`` + instead of ``apt`` to install both ``less`` and the plugin:: + + sudo npm install -g less less-plugin-clean-css. First generate makefiles or project files using CMake as described in the previous section. Then compile the ``doc`` target/project, for example:: @@ -87,4 +108,4 @@ Homebrew fmt can be installed on OS X using `Homebrew `_:: - brew install cppformat + brew install fmt diff --git a/libs/format/doc/html/_static/pygments.css b/libs/format/doc/html/_static/pygments.css index 8213e90be..20c4814dc 100644 --- a/libs/format/doc/html/_static/pygments.css +++ b/libs/format/doc/html/_static/pygments.css @@ -47,8 +47,10 @@ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ @@ -59,7 +61,9 @@ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/libs/format/doc/html/api.html b/libs/format/doc/html/api.html index 073c02b99..e8b323871 100644 --- a/libs/format/doc/html/api.html +++ b/libs/format/doc/html/api.html @@ -8,7 +8,7 @@ - API Reference — fmt 3.0.0 documentation + API Reference — fmt 4.0.0 documentation @@ -17,10 +17,11 @@ @@ -35,8 +36,9 @@ diff --git a/libs/format/doc/html/contents.html b/libs/format/doc/html/contents.html index 9daa5e953..e2d5789ee 100644 --- a/libs/format/doc/html/contents.html +++ b/libs/format/doc/html/contents.html @@ -8,7 +8,7 @@ - Contents — fmt 3.0.0 documentation + Contents — fmt 4.0.0 documentation @@ -17,10 +17,11 @@ @@ -34,8 +35,9 @@ diff --git a/libs/format/doc/html/genindex.html b/libs/format/doc/html/genindex.html index 5f0142ca3..89ffacf4b 100644 --- a/libs/format/doc/html/genindex.html +++ b/libs/format/doc/html/genindex.html @@ -9,7 +9,7 @@ - Index — fmt 3.0.0 documentation + Index — fmt 4.0.0 documentation @@ -18,10 +18,11 @@ @@ -34,8 +35,9 @@ diff --git a/libs/format/doc/html/index.html b/libs/format/doc/html/index.html index 9d1316431..e159b2170 100644 --- a/libs/format/doc/html/index.html +++ b/libs/format/doc/html/index.html @@ -8,7 +8,7 @@ - Overview — fmt 3.0.0 documentation + Overview — fmt 4.0.0 documentation @@ -17,10 +17,11 @@ @@ -33,8 +34,9 @@ diff --git a/libs/format/doc/html/objects.inv b/libs/format/doc/html/objects.inv index 21d47b148..018ffadc3 100644 Binary files a/libs/format/doc/html/objects.inv and b/libs/format/doc/html/objects.inv differ diff --git a/libs/format/doc/html/search.html b/libs/format/doc/html/search.html index 54b2f380c..a8f742f30 100644 --- a/libs/format/doc/html/search.html +++ b/libs/format/doc/html/search.html @@ -8,7 +8,7 @@ - Search — fmt 3.0.0 documentation + Search — fmt 4.0.0 documentation @@ -17,10 +17,11 @@ @@ -40,8 +41,9 @@ diff --git a/libs/format/doc/html/searchindex.js b/libs/format/doc/html/searchindex.js index f6532839a..fecf16d98 100644 --- a/libs/format/doc/html/searchindex.js +++ b/libs/format/doc/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:47,filenames:["api","contents","index","syntax","usage"],objects:{"":{"fmt::ArgFormatter":[0,1,1,"_CPPv2N3fmt12ArgFormatterE"],"fmt::ArgFormatter::ArgFormatter":[0,2,1,"_CPPv2N3fmt12ArgFormatter12ArgFormatterER14BasicFormatterI4CharER10FormatSpecPK4Char"],"fmt::ArgList":[0,1,1,"_CPPv2N3fmt7ArgListE"],"fmt::ArgList::operator[]":[0,2,1,"_CPPv2N3fmt7ArgListixEj"],"fmt::ArgVisitor":[0,1,1,"_CPPv2N3fmt10ArgVisitorE"],"fmt::ArgVisitor::visit":[0,2,1,"_CPPv2N3fmt10ArgVisitor5visitERK3Arg"],"fmt::ArgVisitor::visit_any_double":[0,2,1,"_CPPv2N3fmt10ArgVisitor16visit_any_doubleE1T"],"fmt::ArgVisitor::visit_any_int":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_any_intE1T"],"fmt::ArgVisitor::visit_bool":[0,2,1,"_CPPv2N3fmt10ArgVisitor10visit_boolEb"],"fmt::ArgVisitor::visit_char":[0,2,1,"_CPPv2N3fmt10ArgVisitor10visit_charEi"],"fmt::ArgVisitor::visit_cstring":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_cstringEPKc"],"fmt::ArgVisitor::visit_custom":[0,2,1,"_CPPv2N3fmt10ArgVisitor12visit_customEN3Arg11CustomValueE"],"fmt::ArgVisitor::visit_double":[0,2,1,"_CPPv2N3fmt10ArgVisitor12visit_doubleEd"],"fmt::ArgVisitor::visit_int":[0,2,1,"_CPPv2N3fmt10ArgVisitor9visit_intEi"],"fmt::ArgVisitor::visit_long_double":[0,2,1,"_CPPv2N3fmt10ArgVisitor17visit_long_doubleEe"],"fmt::ArgVisitor::visit_long_long":[0,2,1,"_CPPv2N3fmt10ArgVisitor15visit_long_longE8LongLong"],"fmt::ArgVisitor::visit_pointer":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_pointerEPKv"],"fmt::ArgVisitor::visit_string":[0,2,1,"_CPPv2N3fmt10ArgVisitor12visit_stringEN3Arg11StringValueIcEE"],"fmt::ArgVisitor::visit_uint":[0,2,1,"_CPPv2N3fmt10ArgVisitor10visit_uintEj"],"fmt::ArgVisitor::visit_ulong_long":[0,2,1,"_CPPv2N3fmt10ArgVisitor16visit_ulong_longE9ULongLong"],"fmt::ArgVisitor::visit_wstring":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_wstringEN3Arg11StringValueIwEE"],"fmt::BasicArgFormatter":[0,1,1,"_CPPv2N3fmt17BasicArgFormatterE"],"fmt::BasicArgFormatter::BasicArgFormatter":[0,2,1,"_CPPv2N3fmt17BasicArgFormatter17BasicArgFormatterER14BasicFormatterI4Char4ImplER10FormatSpecPK4Char"],"fmt::BasicArgFormatter::visit_custom":[0,2,1,"_CPPv2N3fmt17BasicArgFormatter12visit_customEN8internal3Arg11CustomValueE"],"fmt::BasicArrayWriter":[0,1,1,"_CPPv2N3fmt16BasicArrayWriterE"],"fmt::BasicArrayWriter::BasicArrayWriter":[0,2,1,"_CPPv2N3fmt16BasicArrayWriter16BasicArrayWriterERASIZE_4Char"],"fmt::BasicCStringRef":[0,1,1,"_CPPv2N3fmt15BasicCStringRefE"],"fmt::BasicCStringRef::BasicCStringRef":[0,2,1,"_CPPv2N3fmt15BasicCStringRef15BasicCStringRefERKNSt12basic_stringI4CharEE"],"fmt::BasicCStringRef::c_str":[0,2,1,"_CPPv2N3fmt15BasicCStringRef5c_strEv"],"fmt::BasicFormatter":[0,1,1,"_CPPv2N3fmt14BasicFormatterE"],"fmt::BasicFormatter::BasicFormatter":[0,2,1,"_CPPv2N3fmt14BasicFormatter14BasicFormatterERK7ArgListR11BasicWriterI4CharE"],"fmt::BasicFormatter::Char":[0,3,1,"_CPPv2N3fmt14BasicFormatter4CharE"],"fmt::BasicFormatter::format":[0,2,1,"_CPPv2N3fmt14BasicFormatter6formatERPK4CharRKN8internal3ArgE"],"fmt::BasicFormatter::writer":[0,2,1,"_CPPv2N3fmt14BasicFormatter6writerEv"],"fmt::BasicMemoryWriter":[0,1,1,"_CPPv2N3fmt17BasicMemoryWriterE"],"fmt::BasicMemoryWriter::BasicMemoryWriter":[0,2,1,"_CPPv2N3fmt17BasicMemoryWriter17BasicMemoryWriterERR17BasicMemoryWriter"],"fmt::BasicMemoryWriter::operator=":[0,2,1,"_CPPv2N3fmt17BasicMemoryWriteraSERR17BasicMemoryWriter"],"fmt::BasicStringRef":[0,1,1,"_CPPv2N3fmt14BasicStringRefE"],"fmt::BasicStringRef::BasicStringRef":[0,2,1,"_CPPv2N3fmt14BasicStringRef14BasicStringRefERKNSt12basic_stringI4CharEE"],"fmt::BasicStringRef::data":[0,2,1,"_CPPv2N3fmt14BasicStringRef4dataEv"],"fmt::BasicStringRef::size":[0,2,1,"_CPPv2N3fmt14BasicStringRef4sizeEv"],"fmt::BasicStringRef::to_string":[0,2,1,"_CPPv2N3fmt14BasicStringRef9to_stringEv"],"fmt::BasicWriter":[0,1,1,"_CPPv2N3fmt11BasicWriterE"],"fmt::BasicWriter::c_str":[0,2,1,"_CPPv2N3fmt11BasicWriter5c_strEv"],"fmt::BasicWriter::data":[0,2,1,"_CPPv2N3fmt11BasicWriter4dataEv"],"fmt::BasicWriter::operator<<":[0,2,1,"_CPPv2N3fmt11BasicWriterlsEe"],"fmt::BasicWriter::size":[0,2,1,"_CPPv2N3fmt11BasicWriter4sizeEv"],"fmt::BasicWriter::str":[0,2,1,"_CPPv2N3fmt11BasicWriter3strEv"],"fmt::BasicWriter::write":[0,2,1,"_CPPv2N3fmt11BasicWriter5writeE15BasicCStringRefI4CharE7ArgList"],"fmt::BasicWriter::~BasicWriter":[0,2,1,"_CPPv2N3fmt11BasicWriterD0Ev"],"fmt::Buffer":[0,1,1,"_CPPv2N3fmt6BufferE"],"fmt::Buffer::append":[0,2,1,"_CPPv2N3fmt6Buffer6appendEPK1UPK1U"],"fmt::Buffer::capacity":[0,2,1,"_CPPv2N3fmt6Buffer8capacityEv"],"fmt::Buffer::grow":[0,2,1,"_CPPv2N3fmt6Buffer4growENSt6size_tE"],"fmt::Buffer::reserve":[0,2,1,"_CPPv2N3fmt6Buffer7reserveENSt6size_tE"],"fmt::Buffer::resize":[0,2,1,"_CPPv2N3fmt6Buffer6resizeENSt6size_tE"],"fmt::Buffer::size":[0,2,1,"_CPPv2N3fmt6Buffer4sizeEv"],"fmt::SystemError":[0,1,1,"_CPPv2N3fmt11SystemErrorE"],"fmt::SystemError::SystemError":[0,2,1,"_CPPv2N3fmt11SystemError11SystemErrorEi10CStringRef"],"fmt::WindowsError":[0,1,1,"_CPPv2N3fmt12WindowsErrorE"],"fmt::WindowsError::WindowsError":[0,2,1,"_CPPv2N3fmt12WindowsError12WindowsErrorEi10CStringRef"],"fmt::arg":[0,2,1,"_CPPv2N3fmt3argE9StringRefRK1T"],"fmt::bin":[0,2,1,"_CPPv2N3fmt3binEi"],"fmt::format":[0,2,1,"_CPPv2N3fmt6formatE10CStringRef7ArgList"],"fmt::fprintf":[0,2,1,"_CPPv2N3fmt7fprintfERNSt7ostreamE10CStringRef7ArgList"],"fmt::hex":[0,2,1,"_CPPv2N3fmt3hexEi"],"fmt::hexu":[0,2,1,"_CPPv2N3fmt4hexuEi"],"fmt::literals::operator\"\"_a":[0,2,1,"_CPPv2N3fmt8literalsli2_aEPKcNSt6size_tE"],"fmt::literals::operator\"\"_format":[0,2,1,"_CPPv2N3fmt8literalsli7_formatEPKcNSt6size_tE"],"fmt::oct":[0,2,1,"_CPPv2N3fmt3octEi"],"fmt::pad":[0,2,1,"_CPPv2N3fmt3padEij4Char"],"fmt::print":[0,2,1,"_CPPv2N3fmt5printERNSt7ostreamE10CStringRef7ArgList"],"fmt::printf":[0,2,1,"_CPPv2N3fmt6printfER11BasicWriterI4CharE15BasicCStringRefI4CharE7ArgList"],"fmt::sprintf":[0,2,1,"_CPPv2N3fmt7sprintfE10CStringRef7ArgList"],FMT_CAPTURE:[0,0,1,"c.FMT_CAPTURE"],FMT_VARIADIC:[0,0,1,"c.FMT_VARIADIC"]}},objnames:{"0":["c","macro","C macro"],"1":["cpp","class","C++ class"],"2":["cpp","function","C++ function"],"3":["cpp","type","C++ type"]},objtypes:{"0":"c:macro","1":"cpp:class","2":"cpp:function","3":"cpp:type"},terms:{"0000cafe":0,"0b101010":3,"0x2a":3,"0xcafe":0,"\u044e":2,"_format":[0,2],"boolean":3,"case":[0,2,3],"char":[0,2,3],"class":0,"const":[0,2],"default":[0,3],"final":3,"float":[0,2,3],"int":[0,3],"long":[0,2],"new":[0,3],"null":0,"public":0,"return":[0,2],"switch":3,"throw":[0,2],"true":[3,4],"void":0,"while":2,abov:[0,3],abra:[2,3],abracadabra:3,absent:3,accept:2,access:[0,3],across:2,add:[3,4],addit:3,after:3,align:[0,3],aligntypespec:0,all:[0,2,3],allow:[0,2,3],also:[0,2,3],altern:[2,3,4],although:[2,3],alwai:[2,3],amd64:2,android:1,ani:[0,3],answer:[0,2],anyth:3,appear:3,append:0,appli:2,appropri:[0,3],arbitrari:0,archiv:4,arg:[0,2],arg_id:3,argformatt:0,arglist:0,argvisitor:0,arrai:0,arraywrit:0,associ:0,assum:3,automat:[2,3],avail:[2,3,4],avoid:2,awar:3,base:[0,2,3],basic_str:0,basicargformatt:0,basicarraywrit:0,basiccstringref:0,basicformatt:0,basicmemorywrit:0,basicstringref:0,basicwrit:0,becaus:2,been:[2,4],befor:[3,4],begin:0,behavior:3,better:2,bin:[0,3],binari:3,bit:2,bool:0,boost:2,both:[2,3],brace:[0,3],breviti:0,brew:4,bring:[2,3],bsd:2,buffer:[0,2],build:1,build_shared_lib:4,built:[3,4],c_str:[0,2],cad:[2,3],call:0,can:[0,2,3,4],cannot:[0,2],capac:0,capacity_:0,captur:0,caught:2,caus:3,center:3,cerr:0,chang:0,char_trait:0,charact:[0,2,3],chartyp:0,choic:4,clang:2,clean:4,cmake:4,code:[0,2],colon:3,commerci:2,common:[0,3],compar:2,comparison:[2,3],compat:[0,2],compil:[0,2,4],comput:0,concaten:2,consid:3,consist:2,construct:[0,2],contain:[0,2,3],content:0,conveni:0,convers:3,convert:[0,3],copi:3,correspond:0,count:3,cppformat:[2,4],creat:[2,4],css:4,cstringref:0,curious:0,curli:3,current:[0,3,4],custom_format:0,customalloc:0,customargformatt:0,custommemorywrit:0,customstr:0,customvalu:0,cyril:2,dai:0,data:[0,3],day_:0,dbuild_shared_lib:4,decim:3,defin:[0,2,3],definit:0,depend:[0,2,3],describ:[0,3,4],descript:[0,2],destroi:0,detail:3,determin:3,differ:[0,3],digit:[0,3],direct:2,directli:0,directori:[0,4],dispatch:0,displai:3,doc:4,document:[0,1],doe:2,doesn:0,don:[0,2],doubl:[0,2,3],download:4,doxygen:4,dynam:[0,3],each:3,easier:2,either:3,elaps:0,element:0,els:[0,2],emul:2,enabl:3,end:0,ensur:2,environ:4,equival:[0,2,3],errno:[0,2],error_cod:0,escap:3,even:3,exampl:[0,1,2],except:[2,3],experiment:2,expon:3,extens:0,extern:2,fals:3,fast:2,featur:2,felt:2,ffffffd6:0,field:[0,3],file:[0,2,4],filenam:0,fill:[0,3],find:0,first:[3,4],fit:0,fix:[0,3],fmt:[0,2,3,4],fmt_:0,fmt_captur:0,fmt_variad:0,follow:[0,3,4],fopen:0,forc:3,form:[0,3],formal:3,format_spec:3,format_str:0,formaterror:2,formatspec:0,formerli:2,forti:2,fprintf:0,freeli:4,friend:[0,2],from:[0,2,3,4],fulli:2,func:0,gcc:2,gener:[0,2,3,4],get:3,getlasterror:0,git:4,github:2,give:2,given:[0,3],gnu:2,goe:2,goodby:2,grammar:3,grow:0,happi:2,have:[0,4],header:[0,2,4],hello:2,here:2,hex:[0,2,3],hexadecim:[2,3],hexu:0,hfile:0,hfile_error:0,highli:2,hold:[0,4],hole:2,homebrew:1,how:3,html:4,http:4,i386:2,icc:2,id_continu:3,id_start:3,ident:2,identifi:3,impl:0,implement:[0,2,3],implicitli:3,includ:[0,3,4],incomplet:2,increas:0,index:[0,3],indic:3,individu:3,inf:[2,3],infin:[2,3],inform:0,initi:0,insert:[2,3],instal:4,instead:[2,3],int_typ:3,integ:[0,2,3],integr:0,intel:2,intern:0,interpret:3,intformatspec:0,invok:4,iostream:2,just:3,keep:2,known:[0,2],languag:[0,1],larg:3,lead:3,least:0,left:[2,3],legaci:0,length:0,less:[3,4],letter:[0,2,3],librari:[0,1,2],licens:2,lifetim:0,lightweight:2,like:[0,2],line:[0,4],linux:2,list:[0,2],liter:[0,2,3],local:[2,3],localtim:0,loki:2,longlong:0,look:[0,2],lower:[0,3],lpofstruct:0,mac:[2,4],macro:0,made:2,madeup:0,magnitud:3,mai:[0,2,3],main:0,make:[0,2,4],makefil:4,manag:2,mani:3,maximum:[2,3],mean:3,memori:[0,2],memorywrit:[0,2],messag:[0,2],method:0,might:4,mind:2,mini:1,minimum:[2,3],minu:3,mkdir:4,month:0,month_:0,most:[0,3],move:0,msbuild:4,multipl:2,must:[2,3],myargvisitor:0,name:[0,2],namedarg:0,namespac:[0,2],nan:3,narrow:2,nativ:4,natur:2,ndk:1,need:[0,2,3,4],neg:[0,3],neither:2,nest:3,new_siz:0,next:3,nix:4,non:3,none:3,normal:3,notat:3,note:[2,3],noth:2,now:4,nullptr:0,number:[0,2,3],numer:[0,2,3],numeric_limit:2,object:[0,3],oct:[0,3],octal:3,of_read:0,offer:2,older:2,omit:[0,2,3],onc:4,onli:[2,3],open:[0,2],openfil:0,oper:[0,2],option:3,order:[2,3],org:4,other:[0,2,3,4],otherwis:2,out:[0,2],output:[0,2,3,4],overflow:2,overload:0,own:3,pad:[0,3],panic:[0,2],paramet:0,pars:0,part:0,particular:2,pass:0,path:4,pattern:0,perform:[2,3],permiss:2,pip:4,place:3,placement:2,platform:[0,2,4],plugin:4,pod:0,point:[0,2,3],pointer:[0,3],posit:[0,2,3],posix:0,possibl:[0,2],preced:3,precis:3,precompil:4,prefix:[0,3],presenc:3,present:3,prevent:2,previou:4,print:[0,2,3],print_error:0,process:0,produc:2,project:[2,4],protect:0,provid:[0,2,4],ptr_:0,python:[0,2,4],rang:4,rare:2,rather:2,recur:0,releas:4,remov:3,repeat:3,replac:[0,2,3],report:2,repositori:[2,4],repres:[0,2],represent:3,reserv:0,resid:0,resiz:0,respect:3,result:[0,2,3],returntyp:0,right:[0,2,3],round:3,run:4,runtim:0,runtime_error:0,safe:2,sai:2,same:[0,3],scientif:3,script:4,second:[0,3],section:[3,4],see:[0,3,4],self:2,separ:3,sequenc:3,set:[2,3,4],sever:[0,4],shalt:3,share:4,should:[3,4],show:3,shown:3,sign:3,signal:3,signatur:0,signific:3,similar:[0,2,3],simpl:3,singl:2,size:[0,3],size_t:0,slightli:2,sln:4,small:2,softwar:4,some:[0,3],sourc:2,space:[0,3],spec:0,specif:[0,1],specifi:[0,3],sprintf:[0,2],standard:[0,2,3],start:[3,4],stateless:2,stdafx:4,stderr:[0,2],stdout:[0,2],store:0,str:[0,2],stream:[0,2],strftime:0,string:[0,1,2],stringref:0,stringvalu:0,studio:4,subclass:0,subset:0,substitut:3,suffix:2,superclass:0,sure:0,surround:[0,3],syntax:[0,1,2],systemerror:0,take:0,target:4,templat:[0,2],term:3,termin:0,terser:2,test:[2,4],text:[0,3],textual:3,than:[2,3],thank:2,thei:[0,2,3],them:4,thi:[0,2,3,4],thing:2,thou:3,time_t:0,to_str:0,too:3,total:0,track:2,trail:3,translat:3,treat:3,two:2,type:[0,2,3],type_cod:0,typedef:0,typenam:0,typespec:0,typic:4,udlarg:0,udlformat:0,ulonglong:0,unchang:3,unicod:2,unknown:[0,2],unless:3,unlimit:2,unsign:0,updat:0,upper:[0,3],uppercas:3,usag:1,user:[0,2],usual:0,valid:[0,3],valu:[0,2,3],vari:0,variabl:[0,4],variad:[0,2],variou:3,vcproj:4,vector:0,virtual:0,virtualenv:4,visibl:2,visit:0,visit_any_doubl:0,visit_any_int:0,visit_bool:0,visit_char:0,visit_cstr:0,visit_custom:0,visit_doubl:0,visit_int:0,visit_long_doubl:0,visit_long_long:0,visit_point:0,visit_str:0,visit_uint:0,visit_ulong_long:0,visit_wstr:0,visitor:0,visual:[2,4],vs2013:2,vs2015:2,wai:0,warraywrit:0,wchar_t:0,wcstringref:0,well:3,what:2,when:[0,2,3],where:[0,2,4],whether:3,which:[2,3],whose:3,wide:[0,2,4],width:[0,3],window:[0,2,4],windowserror:0,within:3,wmemorywrit:0,word:3,work:[2,4],workflow:4,world:2,wrapper:2,writer:0,written:[0,2],wstringref:0,wwriter:0,www:4,x42e:2,xcode:4,xcodeproj:4,year:0,year_:0,you:[0,2,3,4],your:[2,4],zero:3},titles:["API Reference","Contents","Overview","Format String Syntax","Usage"],titleterms:{"function":0,alloc:0,android:4,api:[0,2],argument:0,build:4,content:1,custom:0,date:0,document:4,eas:2,error:0,exampl:3,format:[0,2,3],formatt:0,homebrew:4,languag:3,librari:4,mini:3,ndk:4,ostream:0,overview:2,portabl:2,printf:0,refer:0,safeti:2,specif:3,std:0,string:3,support:0,syntax:3,system:0,time:0,usag:4,util:0,write:[0,2]}}) \ No newline at end of file +Search.setIndex({envversion:49,filenames:["api","contents","index","syntax","usage"],objects:{"":{"fmt::ArgFormatter":[0,1,1,"_CPPv2N3fmt12ArgFormatterE"],"fmt::ArgFormatter::ArgFormatter":[0,2,1,"_CPPv2N3fmt12ArgFormatter12ArgFormatterER14BasicFormatterI4CharER10FormatSpecPK4Char"],"fmt::ArgList":[0,1,1,"_CPPv2N3fmt7ArgListE"],"fmt::ArgList::operator[]":[0,2,1,"_CPPv2NK3fmt7ArgListixEj"],"fmt::ArgVisitor":[0,1,1,"_CPPv2N3fmt10ArgVisitorE"],"fmt::ArgVisitor::visit":[0,2,1,"_CPPv2N3fmt10ArgVisitor5visitERK3Arg"],"fmt::ArgVisitor::visit_any_double":[0,2,1,"_CPPv2N3fmt10ArgVisitor16visit_any_doubleE1T"],"fmt::ArgVisitor::visit_any_int":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_any_intE1T"],"fmt::ArgVisitor::visit_bool":[0,2,1,"_CPPv2N3fmt10ArgVisitor10visit_boolEb"],"fmt::ArgVisitor::visit_char":[0,2,1,"_CPPv2N3fmt10ArgVisitor10visit_charEi"],"fmt::ArgVisitor::visit_cstring":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_cstringEPKc"],"fmt::ArgVisitor::visit_custom":[0,2,1,"_CPPv2N3fmt10ArgVisitor12visit_customEN3Arg11CustomValueE"],"fmt::ArgVisitor::visit_double":[0,2,1,"_CPPv2N3fmt10ArgVisitor12visit_doubleEd"],"fmt::ArgVisitor::visit_int":[0,2,1,"_CPPv2N3fmt10ArgVisitor9visit_intEi"],"fmt::ArgVisitor::visit_long_double":[0,2,1,"_CPPv2N3fmt10ArgVisitor17visit_long_doubleEe"],"fmt::ArgVisitor::visit_long_long":[0,2,1,"_CPPv2N3fmt10ArgVisitor15visit_long_longE8LongLong"],"fmt::ArgVisitor::visit_pointer":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_pointerEPKv"],"fmt::ArgVisitor::visit_string":[0,2,1,"_CPPv2N3fmt10ArgVisitor12visit_stringEN3Arg11StringValueIcEE"],"fmt::ArgVisitor::visit_uint":[0,2,1,"_CPPv2N3fmt10ArgVisitor10visit_uintEj"],"fmt::ArgVisitor::visit_ulong_long":[0,2,1,"_CPPv2N3fmt10ArgVisitor16visit_ulong_longE9ULongLong"],"fmt::ArgVisitor::visit_wstring":[0,2,1,"_CPPv2N3fmt10ArgVisitor13visit_wstringEN3Arg11StringValueIwEE"],"fmt::BasicArgFormatter":[0,1,1,"_CPPv2N3fmt17BasicArgFormatterE"],"fmt::BasicArgFormatter::BasicArgFormatter":[0,2,1,"_CPPv2N3fmt17BasicArgFormatter17BasicArgFormatterER14BasicFormatterI4Char4ImplER4SpecPK4Char"],"fmt::BasicArgFormatter::visit_custom":[0,2,1,"_CPPv2N3fmt17BasicArgFormatter12visit_customEN8internal3Arg11CustomValueE"],"fmt::BasicArrayWriter":[0,1,1,"_CPPv2N3fmt16BasicArrayWriterE"],"fmt::BasicArrayWriter::BasicArrayWriter":[0,2,1,"_CPPv2N3fmt16BasicArrayWriter16BasicArrayWriterERASIZE_4Char"],"fmt::BasicCStringRef":[0,1,1,"_CPPv2N3fmt15BasicCStringRefE"],"fmt::BasicCStringRef::BasicCStringRef":[0,2,1,"_CPPv2N3fmt15BasicCStringRef15BasicCStringRefERKNSt12basic_stringI4CharNSt11char_traitsI4CharEE9AllocatorEE"],"fmt::BasicCStringRef::c_str":[0,2,1,"_CPPv2NK3fmt15BasicCStringRef5c_strEv"],"fmt::BasicContainerWriter":[0,1,1,"_CPPv2N3fmt20BasicContainerWriterE"],"fmt::BasicContainerWriter::BasicContainerWriter":[0,2,1,"_CPPv2N3fmt20BasicContainerWriter20BasicContainerWriterER9Container"],"fmt::BasicFormatter":[0,1,1,"_CPPv2N3fmt14BasicFormatterE"],"fmt::BasicFormatter::BasicFormatter":[0,2,1,"_CPPv2N3fmt14BasicFormatter14BasicFormatterERK7ArgListR11BasicWriterI4CharE"],"fmt::BasicFormatter::Char":[0,3,1,"_CPPv2N3fmt14BasicFormatter4CharE"],"fmt::BasicFormatter::format":[0,2,1,"_CPPv2N3fmt14BasicFormatter6formatERPK4CharRKN8internal3ArgE"],"fmt::BasicFormatter::writer":[0,2,1,"_CPPv2N3fmt14BasicFormatter6writerEv"],"fmt::BasicMemoryWriter":[0,1,1,"_CPPv2N3fmt17BasicMemoryWriterE"],"fmt::BasicMemoryWriter::BasicMemoryWriter":[0,2,1,"_CPPv2N3fmt17BasicMemoryWriter17BasicMemoryWriterERR17BasicMemoryWriter"],"fmt::BasicMemoryWriter::operator=":[0,2,1,"_CPPv2N3fmt17BasicMemoryWriteraSERR17BasicMemoryWriter"],"fmt::BasicPrintfArgFormatter":[0,1,1,"_CPPv2N3fmt23BasicPrintfArgFormatterE"],"fmt::BasicPrintfArgFormatter::BasicPrintfArgFormatter":[0,2,1,"_CPPv2N3fmt23BasicPrintfArgFormatter23BasicPrintfArgFormatterER11BasicWriterI4CharER4Spec"],"fmt::BasicPrintfArgFormatter::visit_bool":[0,2,1,"_CPPv2N3fmt23BasicPrintfArgFormatter10visit_boolEb"],"fmt::BasicPrintfArgFormatter::visit_char":[0,2,1,"_CPPv2N3fmt23BasicPrintfArgFormatter10visit_charEi"],"fmt::BasicPrintfArgFormatter::visit_cstring":[0,2,1,"_CPPv2N3fmt23BasicPrintfArgFormatter13visit_cstringEPKc"],"fmt::BasicPrintfArgFormatter::visit_custom":[0,2,1,"_CPPv2N3fmt23BasicPrintfArgFormatter12visit_customEN8internal3Arg11CustomValueE"],"fmt::BasicPrintfArgFormatter::visit_pointer":[0,2,1,"_CPPv2N3fmt23BasicPrintfArgFormatter13visit_pointerEPKv"],"fmt::BasicStringRef":[0,1,1,"_CPPv2N3fmt14BasicStringRefE"],"fmt::BasicStringRef::BasicStringRef":[0,2,1,"_CPPv2N3fmt14BasicStringRef14BasicStringRefERKNSt12basic_stringI4CharNSt11char_traitsI4CharEE9AllocatorEE"],"fmt::BasicStringRef::data":[0,2,1,"_CPPv2NK3fmt14BasicStringRef4dataEv"],"fmt::BasicStringRef::size":[0,2,1,"_CPPv2NK3fmt14BasicStringRef4sizeEv"],"fmt::BasicStringRef::to_string":[0,2,1,"_CPPv2NK3fmt14BasicStringRef9to_stringEv"],"fmt::BasicStringWriter":[0,1,1,"_CPPv2N3fmt17BasicStringWriterE"],"fmt::BasicStringWriter::BasicStringWriter":[0,2,1,"_CPPv2N3fmt17BasicStringWriter17BasicStringWriterERK9Allocator"],"fmt::BasicStringWriter::move_to":[0,2,1,"_CPPv2N3fmt17BasicStringWriter7move_toERNSt12basic_stringI4CharNSt11char_traitsI4CharEE9AllocatorEE"],"fmt::BasicWriter":[0,1,1,"_CPPv2N3fmt11BasicWriterE"],"fmt::BasicWriter::c_str":[0,2,1,"_CPPv2NK3fmt11BasicWriter5c_strEv"],"fmt::BasicWriter::data":[0,2,1,"_CPPv2NK3fmt11BasicWriter4dataEv"],"fmt::BasicWriter::operator<<":[0,2,1,"_CPPv2N3fmt11BasicWriterlsEe"],"fmt::BasicWriter::size":[0,2,1,"_CPPv2NK3fmt11BasicWriter4sizeEv"],"fmt::BasicWriter::str":[0,2,1,"_CPPv2NK3fmt11BasicWriter3strEv"],"fmt::BasicWriter::write":[0,2,1,"_CPPv2N3fmt11BasicWriter5writeE15BasicCStringRefI4CharE7ArgList"],"fmt::BasicWriter::~BasicWriter":[0,2,1,"_CPPv2N3fmt11BasicWriterD0Ev"],"fmt::Buffer":[0,1,1,"_CPPv2N3fmt6BufferE"],"fmt::Buffer::append":[0,2,1,"_CPPv2N3fmt6Buffer6appendEPK1UPK1U"],"fmt::Buffer::capacity":[0,2,1,"_CPPv2NK3fmt6Buffer8capacityEv"],"fmt::Buffer::grow":[0,2,1,"_CPPv2N3fmt6Buffer4growENSt6size_tE"],"fmt::Buffer::reserve":[0,2,1,"_CPPv2N3fmt6Buffer7reserveENSt6size_tE"],"fmt::Buffer::resize":[0,2,1,"_CPPv2N3fmt6Buffer6resizeENSt6size_tE"],"fmt::Buffer::size":[0,2,1,"_CPPv2NK3fmt6Buffer4sizeEv"],"fmt::PrintfArgFormatter":[0,1,1,"_CPPv2N3fmt18PrintfArgFormatterE"],"fmt::PrintfArgFormatter::PrintfArgFormatter":[0,2,1,"_CPPv2N3fmt18PrintfArgFormatter18PrintfArgFormatterER11BasicWriterI4CharER10FormatSpec"],"fmt::PrintfFormatter":[0,1,1,"_CPPv2N3fmt15PrintfFormatterE"],"fmt::PrintfFormatter::PrintfFormatter":[0,2,1,"_CPPv2N3fmt15PrintfFormatter15PrintfFormatterERK7ArgListR11BasicWriterI4CharE"],"fmt::PrintfFormatter::format":[0,2,1,"_CPPv2N3fmt15PrintfFormatter6formatE15BasicCStringRefI4CharE"],"fmt::SystemError":[0,1,1,"_CPPv2N3fmt11SystemErrorE"],"fmt::SystemError::SystemError":[0,2,1,"_CPPv2N3fmt11SystemError11SystemErrorEi10CStringRef"],"fmt::WindowsError":[0,1,1,"_CPPv2N3fmt12WindowsErrorE"],"fmt::WindowsError::WindowsError":[0,2,1,"_CPPv2N3fmt12WindowsError12WindowsErrorEi10CStringRef"],"fmt::arg":[0,2,1,"_CPPv2N3fmt3argE9StringRefRK1T"],"fmt::bin":[0,2,1,"_CPPv2N3fmt3binEi"],"fmt::format":[0,2,1,"_CPPv2N3fmt6formatE10CStringRef7ArgList"],"fmt::format_system_error":[0,2,1,"_CPPv2N3fmt19format_system_errorERN3fmt6WriterEiN3fmt9StringRefE"],"fmt::fprintf":[0,2,1,"_CPPv2N3fmt7fprintfERNSt7ostreamE10CStringRef7ArgList"],"fmt::hex":[0,2,1,"_CPPv2N3fmt3hexEi"],"fmt::hexu":[0,2,1,"_CPPv2N3fmt4hexuEi"],"fmt::oct":[0,2,1,"_CPPv2N3fmt3octEi"],"fmt::pad":[0,2,1,"_CPPv2N3fmt3padEij4Char"],"fmt::print":[0,2,1,"_CPPv2N3fmt5printERNSt7ostreamE10CStringRef7ArgList"],"fmt::printf":[0,2,1,"_CPPv2N3fmt6printfER7WWriter11WCStringRefDpRK4Args"],"fmt::sprintf":[0,2,1,"_CPPv2N3fmt7sprintfE10CStringRef7ArgList"],"fmt::to_string":[0,2,1,"_CPPv2N3fmt9to_stringERK1T"],FMT_CAPTURE:[0,0,1,"c.FMT_CAPTURE"],FMT_VARIADIC:[0,0,1,"c.FMT_VARIADIC"]}},objnames:{"0":["c","macro","C macro"],"1":["cpp","class","C++ class"],"2":["cpp","function","C++ function"],"3":["cpp","type","C++ type"]},objtypes:{"0":"c:macro","1":"cpp:class","2":"cpp:function","3":"cpp:type"},terms:{"0000cafe":0,"0b101010":3,"0x2a":3,"0xcafe":0,"\u044e":2,"_format":[0,2],"boolean":3,"case":[0,2,3],"char":[0,2,3],"class":0,"const":[0,2],"default":[0,3],"final":3,"float":[0,2,3],"function":[0,2,3],"int":[0,3],"long":[0,2],"new":[0,3],"null":0,"public":0,"return":[0,2],"switch":3,"throw":[0,2],"true":[3,4],"void":0,"while":2,abov:[0,3],abra:[2,3],abracadabra:3,absent:3,accept:2,access:[0,3],across:2,add:[3,4],add_subdirectori:4,addit:[0,3],advanc:0,after:3,against:4,align:[0,3],aligntypespec:0,all:[0,2,3,4],allow:[0,2,3],also:[0,2,3],altern:[2,3,4],although:[2,3],alwai:[0,2,3,4],amd64:2,android:1,ani:[0,3],answer:[0,2],anyth:3,appear:3,append:0,appli:2,appropri:[0,3],apt:4,arbitrari:0,archiv:4,arg:[0,2],arg_id:3,argformatt:0,argformatterbas:0,arglist:0,argvisitor:0,arrai:0,arraywrit:0,associ:0,assum:3,automat:[2,3],avail:[2,3,4],avoid:2,awar:3,base:[0,2,3],basic_str:0,basicargformatt:0,basicarraywrit:0,basiccontainerwrit:0,basiccstringref:0,basicformatt:0,basicmemorywrit:0,basicprintfargformatt:0,basicstringref:0,basicstringwrit:0,basicwrit:0,becaus:2,been:[2,4],befor:[3,4],begin:0,behavior:3,better:[0,2],bin:[0,3],binari:3,bit:2,bool:0,boost:2,both:[2,3,4],brace:[0,3],breviti:0,brew:4,bring:[2,3],bsd:2,buffer:[0,2],build:[0,1],build_shared_lib:4,built:[3,4],c_str:[0,2],cad:[2,3],call:[0,4],can:[0,2,3,4],cannot:[0,2],capac:0,capacity_:0,captur:0,caught:2,caus:3,center:3,cerr:0,certain:3,chang:0,char_trait:0,charact:[0,2,3],chartyp:0,choic:4,clang:2,clean:4,clear:0,close:0,cmake:1,cmakelist:4,code:[0,2],colon:3,commerci:2,common:[0,3],compar:2,comparison:[2,3],compat:[0,2],compil:[0,2,4],comput:0,concaten:2,consid:3,consist:2,construct:[0,2],constructor:0,contain:[0,2,3],content:0,conveni:0,convent:0,convers:3,convert:[0,3],copi:3,core:2,correspond:0,count:3,counterpart:0,cppformat:2,creat:[0,2,4],css:4,cstringref:0,curious:0,curli:3,current:[0,3,4],custom_format:0,customalloc:0,customargformatt:0,custommemorywrit:0,customstr:0,customvalu:0,cyril:2,dai:0,data:[0,3],day_:0,dbuild_shared_lib:4,decim:3,definit:0,depend:[0,2,3],describ:[0,3,4],descript:[0,2],dest:0,destroi:0,detail:3,determin:3,differ:[0,3],digit:[0,3],direct:[0,2],directli:0,directori:[0,4],dispatch:0,displai:3,doc:[0,4],document:[0,1],doe:[2,4],doesn:[0,4],don:[0,2],doubl:[0,2,3],download:4,doxygen:[0,4],doxygenfunct:0,doxyxml:0,dynam:[0,3],each:3,easier:2,either:3,elaps:0,element:0,els:[0,2],elsewher:0,emul:2,enabl:[3,4],end:0,ensur:[2,4],environ:4,equival:[2,3],errno:[0,2],error_cod:0,escap:3,even:[0,3],exampl:[0,1,2],except:[0,2,3],exclude_from_al:4,exist:4,exlud:4,experiment:2,expon:3,extens:0,extern:2,fals:3,fashion:4,fast:2,faster:0,featur:2,felt:2,ffffffd6:0,field:[0,3],file:[0,2,4],filenam:0,fill:[0,3],find:0,first:[3,4],fit:0,fix:[0,3],fmt:[0,2,3,4],fmt_:0,fmt_captur:0,fmt_variad:0,fmtlib:4,follow:[0,3,4],foo:4,foonathan:0,fopen:0,forc:3,form:[0,3],formal:3,format_arg:0,format_spec:3,format_str:0,format_system_error:0,formaterror:2,formatspec:0,formatterbas:0,formerli:2,forti:2,fprintf:0,freeli:4,friend:[0,2],from:[0,2,3,4],fulli:2,func:0,gcc:2,gener:[0,2,3,4],get:[0,3,4],getlasterror:0,git:4,github:2,give:2,given:[0,3],glibc:0,gnu:2,goe:2,goodby:2,grammar:3,grow:0,happi:2,have:[0,4],header:[0,1,2],hello:2,here:2,hex:[0,2,3],hexadecim:[2,3],hexu:0,hfile:0,hfile_error:0,highli:2,hold:[0,4],hole:2,home:0,homebrew:1,how:[0,3],html:4,http:4,i386:2,icc:2,id_continu:3,id_start:3,ident:2,identifi:3,ignor:0,impl:0,implement:[0,2,3],implicitli:3,includ:[0,3,4],incomplet:2,increas:0,index:0,indic:3,individu:3,inf:[2,3],infin:[2,3],inform:0,inherit:0,initi:0,insert:[2,3],instal:4,instead:[2,3,4],int_typ:3,integ:[0,2,3],integr:0,intel:2,intern:0,interpret:3,intformatspec:0,invok:4,iostream:[0,2],just:3,keep:2,known:[0,2],languag:[0,1],larg:3,larger:0,lead:3,least:0,left:[2,3],legaci:0,length:0,less:[3,4],letter:[0,2,3],librari:[0,1,2],licens:2,lifetim:0,lightweight:2,like:[0,2,4],line:[0,4],link:4,linux:2,list:[0,2],liter:[0,2,3],local:[2,3],localtim:0,loki:2,longlong:0,look:[0,2],lower:[0,3],lpofstruct:0,mac:[2,4],macro:0,made:2,madeup:0,magnitud:3,mai:[0,2,3],main:[0,4],make:[0,2,4],makefil:4,manag:2,mani:3,match:0,maximum:[2,3],mean:3,memori:[0,2],memorybuff:0,memorywrit:[0,2],messag:[0,2],method:0,might:4,mind:2,mini:1,minimum:[2,3],minu:3,mkdir:4,modifi:4,month:0,month_:0,most:[0,3],move:0,move_to:0,msbuild:4,multipl:2,must:[2,3],myargvisitor:0,mystruct:0,name:[0,2],namedargwithtyp:0,namespac:[0,2],nan:3,narrow:2,nativ:4,natur:2,ndk:1,need:[0,2,3,4],neg:[0,3],neither:2,nest:3,new_siz:0,next:[0,3],nix:4,non:3,none:3,normal:3,notat:3,note:[0,2,3],noth:2,now:4,npm:4,nullptr:0,number:[0,2,3],numer:[0,2,3],numeric_limit:2,object:[0,3],oct:[0,3],octal:3,of_read:0,offer:2,older:2,omit:[0,2,3],onc:4,onli:[1,2,3],open:[0,2],openfil:0,oper:[0,2],option:3,order:[2,3,4],org:4,other:[0,2,3,4],otherwis:2,out:[0,2],output:[0,2,3,4],overflow:2,overload:0,own:3,packag:4,pad:[0,3],panic:[0,2],paramet:0,pars:0,part:0,particular:2,pass:0,path:4,pattern:0,perform:[0,2],permiss:2,pip:4,place:3,placement:2,platform:[0,2,4],plugin:4,pod:0,point:[0,2,3],pointer:[0,3],posit:[0,2,3],posix:0,possibl:[0,2],preced:3,precis:3,precompil:4,prefix:[0,3],presenc:3,present:3,prevent:2,previou:[0,4],print:[0,2,3],print_error:0,printfargformatt:0,printfformatt:0,privat:4,process:0,produc:2,program:0,project:[0,2,4],protect:0,provid:[0,2,4],ptr_:0,python:[0,2,4],rang:4,rare:2,rather:2,read:4,recur:0,releas:4,remov:3,repeat:3,replac:[0,2,3],report:2,repositori:[2,4],repres:[0,2],represent:3,reserv:0,resid:0,resiz:0,respect:3,result:[0,2,3],returntyp:0,right:[0,2,3],round:3,run:4,runtim:0,runtime_error:0,runtimeerror:0,safe:[0,2],sai:2,same:[0,3],scientif:3,script:4,second:[0,3],section:[0,3,4],see:[0,3,4],self:2,separ:3,sequenc:3,set:[2,3,4],sever:[0,4],shalt:3,share:4,should:[3,4],show:[0,3],shown:3,sign:3,signal:3,signatur:0,signific:3,similar:[0,2,3],similarli:0,simpl:3,singl:2,size:[0,3],size_t:0,slightli:2,sln:4,small:2,softwar:4,some:[0,3],sourc:2,space:[0,3],spec:0,specif:[0,1],specifi:[0,3],speed:0,sprintf:[0,2],standard:[0,2,3],start:[3,4],stateless:2,stdafx:4,stderr:[0,2],stdout:[0,2],store:0,str:[0,2],stream:[0,2],strftime:0,string:[0,1,2],stringref:0,stringvalu:0,stringwrit:0,struct:0,structur:0,studio:4,subclass:0,subset:0,sudo:4,suffix:2,superclass:0,sure:0,surround:[0,3],syntax:[0,1,2],systemerror:0,take:0,target:4,target_link_librari:4,templat:[0,2],term:3,termin:0,terser:2,test:[2,4],text:[0,3],textual:3,than:[0,2,3],thank:2,thei:[0,2,3],them:4,thi:[0,2,3,4],thing:2,thou:3,time_t:0,to_str:0,too:3,total:0,track:2,trail:3,translat:3,treat:3,two:2,txt:4,type_cod:0,typedef:0,typenam:0,typespec:0,typic:4,ubuntu:4,ulonglong:0,unchang:3,unicod:2,unknown:[0,2],unless:3,unlik:0,unlimit:2,unsign:0,updat:0,upper:[0,3],uppercas:3,usag:1,usual:0,valid:[0,3],valu:[0,2,3],value_typ:0,vari:0,variabl:[0,4],variad:[0,2],variou:3,vcproj:4,vecformat:0,vector:0,virtual:0,virtualenv:4,visibl:2,visit:0,visit_any_doubl:0,visit_any_int:0,visit_bool:0,visit_char:0,visit_cstr:0,visit_custom:0,visit_doubl:0,visit_int:0,visit_long_doubl:0,visit_long_long:0,visit_point:0,visit_str:0,visit_uint:0,visit_ulong_long:0,visit_wstr:0,visitor:0,visual:[2,4],vs2013:2,vs2015:2,wai:0,warraywrit:0,wchar_t:0,wcstringref:0,well:3,what:2,when:[0,2,3],where:[0,2,4],whether:3,which:[0,2,3,4],whose:3,wide:[0,2,4],width:[0,3],window:[0,2,4],windowserror:0,within:3,wmemorywrit:0,word:3,work:[2,4],workflow:4,world:2,would:4,wrapper:2,writer:0,written:[0,2],wstringref:0,wstringwrit:0,wwriter:0,www:4,x42e:2,xcode:4,xcodeproj:4,xml:0,year:0,year_:0,you:[0,2,3,4],your:[2,4],zero:3},titles:["API Reference","Contents","Overview","Format String Syntax","Usage"],titleterms:{alloc:0,android:4,api:[0,2],argument:0,build:4,cmake:4,content:1,custom:0,date:0,defin:0,document:4,eas:2,error:0,exampl:3,format:[0,2,3],formatt:0,header:4,homebrew:4,languag:3,librari:4,mini:3,ndk:4,onli:4,ostream:0,overview:2,portabl:2,printf:0,refer:0,safeti:2,specif:3,std:0,string:3,support:0,syntax:3,system:0,time:0,type:0,usag:4,user:0,util:0,write:[0,2]}}) \ No newline at end of file diff --git a/libs/format/doc/html/syntax.html b/libs/format/doc/html/syntax.html index ded1e98dc..55ec80507 100644 --- a/libs/format/doc/html/syntax.html +++ b/libs/format/doc/html/syntax.html @@ -8,7 +8,7 @@ - Format String Syntax — fmt 3.0.0 documentation + Format String Syntax — fmt 4.0.0 documentation @@ -17,10 +17,11 @@ @@ -34,8 +35,9 @@ diff --git a/libs/format/doc/html/usage.html b/libs/format/doc/html/usage.html index b2c90f581..12d59bf21 100644 --- a/libs/format/doc/html/usage.html +++ b/libs/format/doc/html/usage.html @@ -8,7 +8,7 @@ - Usage — fmt 3.0.0 documentation + Usage — fmt 4.0.0 documentation @@ -17,10 +17,11 @@ @@ -35,8 +36,9 @@ diff --git a/libs/format/doc/index.rst b/libs/format/doc/index.rst index 4e17d4b54..ce9b7bf94 100644 --- a/libs/format/doc/index.rst +++ b/libs/format/doc/index.rst @@ -10,9 +10,9 @@ alternative to C++ IOStreams.
What users say:
- Thanks for creating this library. It’s been a hole in C++ for a long time. - I’ve used both boost::format and loki::SPrintf, and neither felt like the - right answer. This does. + Thanks for creating this library. It’s been a hole in C++ for a long + time. I’ve used both boost::format and loki::SPrintf, and neither felt + like the right answer. This does.
@@ -24,8 +24,8 @@ Format API The replacement-based Format API provides a safe alternative to ``printf``, ``sprintf`` and friends with comparable or `better performance `_. -The `format string syntax `_ is similar -to the one used by `str.format `_ +The `format string syntax `_ is similar to the one used by +`str.format `_ in Python: .. code:: c++ @@ -98,8 +98,8 @@ literal operators, they must be made visible with the directive Write API --------- -The concatenation-based Write API (experimental) provides a -`fast `_ +The concatenation-based Write API (experimental) provides a `fast +`_ stateless alternative to IOStreams: .. code:: c++ @@ -112,8 +112,9 @@ stateless alternative to IOStreams: Safety ------ -The library is fully type safe, automatic memory management prevents buffer overflow, -errors in format strings are reported using exceptions. For example, the code +The library is fully type safe, automatic memory management prevents buffer +overflow, errors in format strings are reported using exceptions. For example, +the code .. code:: c++ @@ -138,19 +139,21 @@ formatted into a narrow string. You can use a wide format string instead: fmt::format(L"Cyrillic letter {}", L'\x42e'); For comparison, writing a wide character to ``std::ostream`` results in -its numeric value being written to the stream (i.e. 1070 instead of letter 'ю' which -is represented by ``L'\x42e'`` if we use Unicode) which is rarely what is needed. +its numeric value being written to the stream (i.e. 1070 instead of letter 'ю' +which is represented by ``L'\x42e'`` if we use Unicode) which is rarely what is +needed. .. _portability: Portability ----------- -The library is highly portable. Here is an incomplete list of operating systems and -compilers where it has been tested and known to work: +The library is highly portable. Here is an incomplete list of operating systems +and compilers where it has been tested and known to work: -* 64-bit (amd64) GNU/Linux with GCC 4.4.3, `4.6.3 `_, - 4.7.2, 4.8.1 and Intel C++ Compiler (ICC) 14.0.2 +* 64-bit (amd64) GNU/Linux with GCC 4.4.3, + `4.6.3 `_, 4.7.2, 4.8.1, and Intel C++ + Compiler (ICC) 14.0.2 * 32-bit (i386) GNU/Linux with GCC 4.4.3, 4.6.3 @@ -161,21 +164,21 @@ compilers where it has been tested and known to work: * 32-bit Windows with Visual C++ 2010 -Although the library uses C++11 features when available, it also works with older -compilers and standard library implementations. The only thing to keep in mind -for C++98 portability: +Although the library uses C++11 features when available, it also works with +older compilers and standard library implementations. The only thing to keep in +mind for C++98 portability: * Variadic templates: minimum GCC 4.4, Clang 2.9 or VS2013. This feature allows - the Format API to accept an unlimited number of arguments. With older compilers - the maximum is 15. + the Format API to accept an unlimited number of arguments. With older + compilers the maximum is 15. -* User-defined literals: minimum GCC 4.7, Clang 3.1 or VS2015. The suffixes - ``_format`` and ``_a`` are functionally equivalent to the functions +* User-defined literals: minimum GCC 4.7, Clang 3.1 or VS2015. The suffixes + ``_format`` and ``_a`` are functionally equivalent to the functions ``fmt::format`` and ``fmt::arg``. -The output of all formatting functions is consistent across platforms. In particular, -formatting a floating-point infinity always gives ``inf`` while the output -of ``printf`` is platform-dependent in this case. For example, +The output of all formatting functions is consistent across platforms. In +particular, formatting a floating-point infinity always gives ``inf`` while the +output of ``printf`` is platform-dependent in this case. For example, .. code:: @@ -188,10 +191,10 @@ always prints ``inf``. Ease of Use ----------- -fmt has a small self-contained code base consisting of a single header file -and a single source file and no external dependencies. A permissive BSD `license -`_ allows using the library both -in open-source and commercial projects. +fmt has a small self-contained code base with the core library consisting of +a single header file and a single source file and no external dependencies. +A permissive BSD `license `_ allows +using the library both in open-source and commercial projects. .. raw:: html diff --git a/libs/format/doc/syntax.rst b/libs/format/doc/syntax.rst index feda3e44d..1051467a0 100644 --- a/libs/format/doc/syntax.rst +++ b/libs/format/doc/syntax.rst @@ -49,12 +49,10 @@ mini-language" or interpretation of the *format_spec*. Most built-in types support a common formatting mini-language, which is described in the next section. -A *format_spec* field can also include nested replacement fields within it. -These nested replacement fields can contain only an argument index; -format specifications are not allowed. Formatting is performed as if the -replacement fields within the format_spec are substituted before the -*format_spec* string is interpreted. This allows the formatting of a value -to be dynamically specified. +A *format_spec* field can also include nested replacement fields in certain +positions within it. These nested replacement fields can contain only an +argument id; format specifications are not allowed. This allows the +formatting of a value to be dynamically specified. See the :ref:`formatexamples` section for some examples. @@ -80,8 +78,8 @@ The general form of a *standard format specifier* is: sign: "+" | "-" | " " width: `integer` | "{" `arg_id` "}" precision: `integer` | "{" `arg_id` "}" - type: `int_type` | "c" | "e" | "E" | "f" | "F" | "g" | "G" | "p" | "s" - int_type: "b" | "B" | "d" | "o" | "x" | "X" + type: `int_type` | "a" | "A" | "c" | "e" | "E" | "f" | "F" | "g" | "G" | "p" | "s" + int_type: "b" | "B" | "d" | "n" | "o" | "x" | "X" The *fill* character can be any character other than '{' or '}'. The presence of a fill character is signaled by the character following it, which must be @@ -234,7 +232,7 @@ The available presentation types for floating-point values are: +=========+==========================================================+ | ``'a'`` | Hexadecimal floating point format. Prints the number in | | | base 16 with prefix ``"0x"`` and lower-case letters for | -| | digits above 9. Uses 'p' to indicate the exponent. | +| | digits above 9. Uses ``'p'`` to indicate the exponent. | +---------+----------------------------------------------------------+ | ``'A'`` | Same as ``'a'`` except it uses upper-case letters for | | | the prefix, digits above 9 and to indicate the exponent. | diff --git a/libs/format/doc/usage.rst b/libs/format/doc/usage.rst index 27d96edec..dff312dfa 100644 --- a/libs/format/doc/usage.rst +++ b/libs/format/doc/usage.rst @@ -54,6 +54,23 @@ To build a `shared library`__ set the ``BUILD_SHARED_LIBS`` CMake variable to __ http://en.wikipedia.org/wiki/Library_%28computing%29#Shared_libraries +Header-only usage with CMake +============================ + +In order to add ``fmtlib`` into an existing ``CMakeLists.txt`` file, you can add the ``fmt`` library directory into your main project, which will enable the ``fmt`` library:: + + add_subdirectory(fmt) + +If you have a project called ``foo`` that you would like to link against the fmt library in a header-only fashion, you can enable with with:: + + target_link_libraries(foo PRIVATE fmt::fmt-header-only) + +And then to ensure that the ``fmt`` library does not always get built, you can modify the call to ``add_subdirectory`` to read :: + + add_subdirectory(fmt EXCLUDE_FROM_ALL) + +This will ensure that the ``fmt`` library is exluded from calls to ``make``, ``make all``, or ``cmake --build .``. + Building the documentation ========================== @@ -62,7 +79,11 @@ system: * `Python `_ with pip and virtualenv * `Doxygen `_ -* `Less `_ with less-plugin-clean-css +* `Less `_ with ``less-plugin-clean-css``. + Ubuntu doesn't package the ``clean-css`` plugin so you should use ``npm`` + instead of ``apt`` to install both ``less`` and the plugin:: + + sudo npm install -g less less-plugin-clean-css. First generate makefiles or project files using CMake as described in the previous section. Then compile the ``doc`` target/project, for example:: @@ -87,4 +108,4 @@ Homebrew fmt can be installed on OS X using `Homebrew `_:: - brew install cppformat + brew install fmt diff --git a/libs/format/fmt/CMakeLists.txt b/libs/format/fmt/CMakeLists.txt index 3fc872622..90eaf575f 100644 --- a/libs/format/fmt/CMakeLists.txt +++ b/libs/format/fmt/CMakeLists.txt @@ -1,26 +1,52 @@ # Define the fmt library, its includes and the needed defines. -# format.cc is added to FMT_HEADERS for the header-only configuration. -set(FMT_HEADERS format.h format.cc ostream.h ostream.cc time.h) +# *.cc are added to FMT_HEADERS for the header-only configuration. +set(FMT_HEADERS container.h format.h format.cc ostream.h ostream.cc printf.h + printf.cc string.h time.h) if (HAVE_OPEN) set(FMT_HEADERS ${FMT_HEADERS} posix.h) set(FMT_SOURCES ${FMT_SOURCES} posix.cc) endif () -add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} ../ChangeLog.rst) +add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} ../README.rst ../ChangeLog.rst) +add_library(fmt::fmt ALIAS fmt) -option(FMT_CPPFORMAT "Build cppformat library for backward compatibility." OFF) -if (FMT_CPPFORMAT) - message(WARNING "The cppformat library is deprecated, use fmt instead.") - add_library(cppformat ${FMT_SOURCES} ${FMT_HEADERS}) +# Starting with cmake 3.1 the CXX_STANDARD property can be used instead. +# Note: Don't make -std=c++11 public or interface, since it breaks projects +# that use C++14. +target_compile_options(fmt PRIVATE ${CPP11_FLAG}) +if (FMT_PEDANTIC) + target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS}) endif () -include_directories(fmt INTERFACE +target_include_directories(fmt PUBLIC $ $) set_target_properties(fmt PROPERTIES VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}) +if (BUILD_SHARED_LIBS) + if (UNIX AND NOT APPLE) + # Fix rpmlint warning: + # unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6. + target_link_libraries(fmt -Wl,--as-needed) + endif () + target_compile_definitions(fmt PRIVATE FMT_EXPORT INTERFACE FMT_SHARED) +endif () + +#------------------------------------------------------------------------------ +# additionally define a header only library when cmake is new enough +if (CMAKE_VERSION VERSION_GREATER 3.1.0 OR CMAKE_VERSION VERSION_EQUAL 3.1.0) + add_library(fmt-header-only INTERFACE) + add_library(fmt::fmt-header-only ALIAS fmt-header-only) + + target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) + + target_include_directories(fmt-header-only INTERFACE + $ + $) +endif () + # Install targets. if (FMT_INSTALL) include(CMakePackageConfigHelpers) @@ -47,18 +73,18 @@ if (FMT_INSTALL) ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in ${project_config} INSTALL_DESTINATION ${FMT_CMAKE_DIR}) - export(TARGETS ${INSTALL_TARGETS} FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) + export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt:: + FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) # Install version, config and target files. install( FILES ${project_config} ${version_config} DESTINATION ${FMT_CMAKE_DIR}) - install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}) + install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR} + NAMESPACE fmt::) # Install the library and headers. - install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name} DESTINATION ${FMT_LIB_DIR}) + install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name} + DESTINATION ${FMT_LIB_DIR}) install(FILES ${FMT_HEADERS} DESTINATION include/fmt) - if (FMT_CPPFORMAT) - install(TARGETS cppformat DESTINATION ${FMT_LIB_DIR}) - endif () endif () diff --git a/libs/format/fmt/container.h b/libs/format/fmt/container.h new file mode 100644 index 000000000..cb6303fb7 --- /dev/null +++ b/libs/format/fmt/container.h @@ -0,0 +1,82 @@ +/* + Formatting library for C++ - standard container utilities + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#ifndef FMT_CONTAINER_H_ +#define FMT_CONTAINER_H_ + +#include "format.h" + +namespace fmt { + +namespace internal { + +/** + \rst + A "buffer" that appends data to a standard container (e.g. typically a + ``std::vector`` or ``std::basic_string``). + \endrst + */ +template +class ContainerBuffer : public Buffer { + private: + Container& container_; + + protected: + virtual void grow(std::size_t size) FMT_OVERRIDE { + container_.resize(size); + this->ptr_ = &container_[0]; + this->capacity_ = size; + } + + public: + explicit ContainerBuffer(Container& container) : container_(container) { + this->size_ = container_.size(); + if (this->size_ > 0) { + this->ptr_ = &container_[0]; + this->capacity_ = this->size_; + } + } +}; +} // namespace internal + +/** + \rst + This class template provides operations for formatting and appending data + to a standard *container* like ``std::vector`` or ``std::basic_string``. + + **Example**:: + + void vecformat(std::vector& dest, fmt::BasicCStringRef format, + fmt::ArgList args) { + fmt::BasicContainerWriter > appender(dest); + appender.write(format, args); + } + FMT_VARIADIC(void, vecformat, std::vector&, + fmt::BasicCStringRef); + \endrst + */ +template +class BasicContainerWriter + : public BasicWriter { + private: + internal::ContainerBuffer buffer_; + + public: + /** + \rst + Constructs a :class:`fmt::BasicContainerWriter` object. + \endrst + */ + explicit BasicContainerWriter(Container& dest) + : BasicWriter(buffer_), buffer_(dest) {} +}; + +} // namespace fmt + +#endif // FMT_CONTAINER_H_ diff --git a/libs/format/fmt/format.cc b/libs/format/fmt/format.cc index ae5d11034..09d2ea9fd 100644 --- a/libs/format/fmt/format.cc +++ b/libs/format/fmt/format.cc @@ -41,6 +41,9 @@ #endif #if FMT_USE_WINDOWS_H +# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# endif # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX) # include # else @@ -50,8 +53,6 @@ # endif #endif -using fmt::internal::Arg; - #if FMT_EXCEPTIONS # define FMT_TRY try # define FMT_CATCH(x) catch (x) @@ -79,6 +80,11 @@ static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) { } namespace fmt { + +FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {} +FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {} +FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {} + namespace { #ifndef _MSC_VER @@ -100,27 +106,6 @@ inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) { # define FMT_SWPRINTF swprintf #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) -// Checks if a value fits in int - used to avoid warnings about comparing -// signed and unsigned integers. -template -struct IntChecker { - template - static bool fits_in_int(T value) { - unsigned max = INT_MAX; - return value <= max; - } - static bool fits_in_int(bool) { return true; } -}; - -template <> -struct IntChecker { - template - static bool fits_in_int(T value) { - return value >= INT_MIN && value <= INT_MAX; - } - static bool fits_in_int(int) { return true; } -}; - const char RESET_COLOR[] = "\x1b[0m"; typedef void (*FormatFunc)(Writer &, int, StringRef); @@ -186,7 +171,8 @@ int safe_strerror( : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} int run() { - strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r. + // Suppress a warning about unused strerror_r. + strerror_r(0, FMT_NULL, ""); return handle(strerror_r(error_code_, buffer_, buffer_size_)); } }; @@ -225,222 +211,19 @@ void report_error(FormatFunc func, int error_code, std::fwrite(full_message.data(), full_message.size(), 1, stderr); std::fputc('\n', stderr); } - -// IsZeroInt::visit(arg) returns true iff arg is a zero integer. -class IsZeroInt : public ArgVisitor { - public: - template - bool visit_any_int(T value) { return value == 0; } -}; - -// Checks if an argument is a valid printf width specifier and sets -// left alignment if it is negative. -class WidthHandler : public ArgVisitor { - private: - FormatSpec &spec_; - - FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler); - - public: - explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} - - void report_unhandled_arg() { - FMT_THROW(FormatError("width is not integer")); - } - - template - unsigned visit_any_int(T value) { - typedef typename internal::IntTraits::MainType UnsignedType; - UnsignedType width = static_cast(value); - if (internal::is_negative(value)) { - spec_.align_ = ALIGN_LEFT; - width = 0 - width; - } - if (width > INT_MAX) - FMT_THROW(FormatError("number is too big")); - return static_cast(width); - } -}; - -class PrecisionHandler : public ArgVisitor { - public: - void report_unhandled_arg() { - FMT_THROW(FormatError("precision is not integer")); - } - - template - int visit_any_int(T value) { - if (!IntChecker::is_signed>::fits_in_int(value)) - FMT_THROW(FormatError("number is too big")); - return static_cast(value); - } -}; - -template -struct is_same { - enum { value = 0 }; -}; - -template -struct is_same { - enum { value = 1 }; -}; - -// An argument visitor that converts an integer argument to T for printf, -// if T is an integral type. If T is void, the argument is converted to -// corresponding signed or unsigned type depending on the type specifier: -// 'd' and 'i' - signed, other - unsigned) -template -class ArgConverter : public ArgVisitor, void> { - private: - internal::Arg &arg_; - wchar_t type_; - - FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); - - public: - ArgConverter(internal::Arg &arg, wchar_t type) - : arg_(arg), type_(type) {} - - void visit_bool(bool value) { - if (type_ != 's') - visit_any_int(value); - } - - template - void visit_any_int(U value) { - bool is_signed = type_ == 'd' || type_ == 'i'; - using internal::Arg; - typedef typename internal::Conditional< - is_same::value, U, T>::type TargetType; - if (sizeof(TargetType) <= sizeof(int)) { - // Extra casts are used to silence warnings. - if (is_signed) { - arg_.type = Arg::INT; - arg_.int_value = static_cast(static_cast(value)); - } else { - arg_.type = Arg::UINT; - typedef typename internal::MakeUnsigned::Type Unsigned; - arg_.uint_value = static_cast(static_cast(value)); - } - } else { - if (is_signed) { - arg_.type = Arg::LONG_LONG; - // glibc's printf doesn't sign extend arguments of smaller types: - // std::printf("%lld", -42); // prints "4294967254" - // but we don't have to do the same because it's a UB. - arg_.long_long_value = static_cast(value); - } else { - arg_.type = Arg::ULONG_LONG; - arg_.ulong_long_value = - static_cast::Type>(value); - } - } - } -}; - -// Converts an integer argument to char for printf. -class CharConverter : public ArgVisitor { - private: - internal::Arg &arg_; - - FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); - - public: - explicit CharConverter(internal::Arg &arg) : arg_(arg) {} - - template - void visit_any_int(T value) { - arg_.type = internal::Arg::CHAR; - arg_.int_value = static_cast(value); - } -}; } // namespace -namespace internal { - -template -class PrintfArgFormatter : - public ArgFormatterBase, Char> { - - void write_null_pointer() { - this->spec().type_ = 0; - this->write("(nil)"); - } - - typedef ArgFormatterBase, Char> Base; - - public: - PrintfArgFormatter(BasicWriter &w, FormatSpec &s) - : ArgFormatterBase, Char>(w, s) {} - - void visit_bool(bool value) { - FormatSpec &fmt_spec = this->spec(); - if (fmt_spec.type_ != 's') - return this->visit_any_int(value); - fmt_spec.type_ = 0; - this->write(value); - } - - void visit_char(int value) { - const FormatSpec &fmt_spec = this->spec(); - BasicWriter &w = this->writer(); - if (fmt_spec.type_ && fmt_spec.type_ != 'c') - w.write_int(value, fmt_spec); - typedef typename BasicWriter::CharPtr CharPtr; - CharPtr out = CharPtr(); - if (fmt_spec.width_ > 1) { - Char fill = ' '; - out = w.grow_buffer(fmt_spec.width_); - if (fmt_spec.align_ != ALIGN_LEFT) { - std::fill_n(out, fmt_spec.width_ - 1, fill); - out += fmt_spec.width_ - 1; - } else { - std::fill_n(out + 1, fmt_spec.width_ - 1, fill); - } - } else { - out = w.grow_buffer(1); - } - *out = static_cast(value); - } - - void visit_cstring(const char *value) { - if (value) - Base::visit_cstring(value); - else if (this->spec().type_ == 'p') - write_null_pointer(); - else - this->write("(null)"); - } - - void visit_pointer(const void *value) { - if (value) - return Base::visit_pointer(value); - this->spec().type_ = 0; - write_null_pointer(); - } - - void visit_custom(Arg::CustomValue c) { - BasicFormatter formatter(ArgList(), this->writer()); - const Char format_str[] = {'}', 0}; - const Char *format = format_str; - c.format(&formatter, c.value, &format); - } -}; -} // namespace internal -} // namespace fmt - -FMT_FUNC void fmt::SystemError::init( +FMT_FUNC void SystemError::init( int err_code, CStringRef format_str, ArgList args) { error_code_ = err_code; MemoryWriter w; - internal::format_system_error(w, err_code, format(format_str, args)); + format_system_error(w, err_code, format(format_str, args)); std::runtime_error &base = *this; base = std::runtime_error(w.str()); } template -int fmt::internal::CharTraits::format_float( +int internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, T value) { if (width == 0) { @@ -454,7 +237,7 @@ int fmt::internal::CharTraits::format_float( } template -int fmt::internal::CharTraits::format_float( +int internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, T value) { if (width == 0) { @@ -468,7 +251,7 @@ int fmt::internal::CharTraits::format_float( } template -const char fmt::internal::BasicData::DIGITS[] = +const char internal::BasicData::DIGITS[] = "0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" @@ -487,40 +270,40 @@ const char fmt::internal::BasicData::DIGITS[] = factor * 1000000000 template -const uint32_t fmt::internal::BasicData::POWERS_OF_10_32[] = { +const uint32_t internal::BasicData::POWERS_OF_10_32[] = { 0, FMT_POWERS_OF_10(1) }; template -const uint64_t fmt::internal::BasicData::POWERS_OF_10_64[] = { +const uint64_t internal::BasicData::POWERS_OF_10_64[] = { 0, FMT_POWERS_OF_10(1), - FMT_POWERS_OF_10(fmt::ULongLong(1000000000)), + FMT_POWERS_OF_10(ULongLong(1000000000)), // Multiply several constants instead of using a single long long constant // to avoid warnings about C++98 not supporting long long. - fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10 + ULongLong(1000000000) * ULongLong(1000000000) * 10 }; -FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) { +FMT_FUNC void internal::report_unknown_type(char code, const char *type) { (void)type; if (std::isprint(static_cast(code))) { - FMT_THROW(fmt::FormatError( - fmt::format("unknown format code '{}' for {}", code, type))); + FMT_THROW(FormatError( + format("unknown format code '{}' for {}", code, type))); } - FMT_THROW(fmt::FormatError( - fmt::format("unknown format code '\\x{:02x}' for {}", + FMT_THROW(FormatError( + format("unknown format code '\\x{:02x}' for {}", static_cast(code), type))); } #if FMT_USE_WINDOWS_H -FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { +FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) { static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; if (s.size() > INT_MAX) FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG)); int s_size = static_cast(s.size()); int length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0); + CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0); if (length == 0) FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); buffer_.resize(length + 1); @@ -531,30 +314,31 @@ FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { buffer_[length] = 0; } -FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) { +FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) { if (int error_code = convert(s)) { FMT_THROW(WindowsError(error_code, "cannot convert string from UTF-16 to UTF-8")); } } -FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) { +FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) { if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER; int s_size = static_cast(s.size()); - int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0); + int length = WideCharToMultiByte( + CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL); if (length == 0) return GetLastError(); buffer_.resize(length + 1); length = WideCharToMultiByte( - CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0); + CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL); if (length == 0) return GetLastError(); buffer_[length] = 0; return 0; } -FMT_FUNC void fmt::WindowsError::init( +FMT_FUNC void WindowsError::init( int err_code, CStringRef format_str, ArgList args) { error_code_ = err_code; MemoryWriter w; @@ -563,17 +347,17 @@ FMT_FUNC void fmt::WindowsError::init( base = std::runtime_error(w.str()); } -FMT_FUNC void fmt::internal::format_windows_error( - fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT { +FMT_FUNC void internal::format_windows_error( + Writer &out, int error_code, StringRef message) FMT_NOEXCEPT { FMT_TRY { MemoryBuffer buffer; buffer.resize(INLINE_BUFFER_SIZE); for (;;) { wchar_t *system_message = &buffer[0]; - int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - system_message, static_cast(buffer.size()), 0); + int result = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + system_message, static_cast(buffer.size()), FMT_NULL); if (result != 0) { UTF16ToUTF8 utf8_message; if (utf8_message.convert(system_message) == ERROR_SUCCESS) { @@ -592,12 +376,11 @@ FMT_FUNC void fmt::internal::format_windows_error( #endif // FMT_USE_WINDOWS_H -FMT_FUNC void fmt::internal::format_system_error( - fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT { +FMT_FUNC void format_system_error( + Writer &out, int error_code, StringRef message) FMT_NOEXCEPT { FMT_TRY { - MemoryBuffer buffer; - buffer.resize(INLINE_BUFFER_SIZE); + internal::MemoryBuffer buffer; + buffer.resize(internal::INLINE_BUFFER_SIZE); for (;;) { char *system_message = &buffer[0]; int result = safe_strerror(error_code, system_message, buffer.size()); @@ -614,11 +397,11 @@ FMT_FUNC void fmt::internal::format_system_error( } template -void fmt::internal::ArgMap::init(const ArgList &args) { +void internal::ArgMap::init(const ArgList &args) { if (!map_.empty()) return; typedef internal::NamedArg NamedArg; - const NamedArg *named_arg = 0; + const NamedArg *named_arg = FMT_NULL; bool use_values = args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE; if (use_values) { @@ -659,18 +442,18 @@ void fmt::internal::ArgMap::init(const ArgList &args) { } template -void fmt::internal::FixedBuffer::grow(std::size_t) { +void internal::FixedBuffer::grow(std::size_t) { FMT_THROW(std::runtime_error("buffer overflow")); } -FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg( +FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg( unsigned arg_index, const char *&error) { - Arg arg = args_[arg_index]; + internal::Arg arg = args_[arg_index]; switch (arg.type) { - case Arg::NONE: + case internal::Arg::NONE: error = "argument index out of range"; break; - case Arg::NAMED_ARG: + case internal::Arg::NAMED_ARG: arg = *static_cast(arg.pointer); break; default: @@ -679,203 +462,31 @@ FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg( return arg; } -template -void fmt::internal::PrintfFormatter::parse_flags( - FormatSpec &spec, const Char *&s) { - for (;;) { - switch (*s++) { - case '-': - spec.align_ = ALIGN_LEFT; - break; - case '+': - spec.flags_ |= SIGN_FLAG | PLUS_FLAG; - break; - case '0': - spec.fill_ = '0'; - break; - case ' ': - spec.flags_ |= SIGN_FLAG; - break; - case '#': - spec.flags_ |= HASH_FLAG; - break; - default: - --s; - return; - } - } -} - -template -Arg fmt::internal::PrintfFormatter::get_arg( - const Char *s, unsigned arg_index) { - (void)s; - const char *error = 0; - Arg arg = arg_index == UINT_MAX ? - next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); - if (error) - FMT_THROW(FormatError(!*s ? "invalid format string" : error)); - return arg; -} - -template -unsigned fmt::internal::PrintfFormatter::parse_header( - const Char *&s, FormatSpec &spec) { - unsigned arg_index = UINT_MAX; - Char c = *s; - if (c >= '0' && c <= '9') { - // Parse an argument index (if followed by '$') or a width possibly - // preceded with '0' flag(s). - unsigned value = parse_nonnegative_int(s); - if (*s == '$') { // value is an argument index - ++s; - arg_index = value; - } else { - if (c == '0') - spec.fill_ = '0'; - if (value != 0) { - // Nonzero value means that we parsed width and don't need to - // parse it or flags again, so return now. - spec.width_ = value; - return arg_index; - } - } - } - parse_flags(spec, s); - // Parse width. - if (*s >= '0' && *s <= '9') { - spec.width_ = parse_nonnegative_int(s); - } else if (*s == '*') { - ++s; - spec.width_ = WidthHandler(spec).visit(get_arg(s)); - } - return arg_index; -} - -template -void fmt::internal::PrintfFormatter::format( - BasicWriter &writer, BasicCStringRef format_str) { - const Char *start = format_str.c_str(); - const Char *s = start; - while (*s) { - Char c = *s++; - if (c != '%') continue; - if (*s == c) { - write(writer, start, s); - start = ++s; - continue; - } - write(writer, start, s - 1); - - FormatSpec spec; - spec.align_ = ALIGN_RIGHT; - - // Parse argument index, flags and width. - unsigned arg_index = parse_header(s, spec); - - // Parse precision. - if (*s == '.') { - ++s; - if ('0' <= *s && *s <= '9') { - spec.precision_ = static_cast(parse_nonnegative_int(s)); - } else if (*s == '*') { - ++s; - spec.precision_ = PrecisionHandler().visit(get_arg(s)); - } - } - - Arg arg = get_arg(s, arg_index); - if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) - spec.flags_ &= ~to_unsigned(HASH_FLAG); - if (spec.fill_ == '0') { - if (arg.type <= Arg::LAST_NUMERIC_TYPE) - spec.align_ = ALIGN_NUMERIC; - else - spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. - } - - // Parse length and convert the argument to the required type. - switch (*s++) { - case 'h': - if (*s == 'h') - ArgConverter(arg, *++s).visit(arg); - else - ArgConverter(arg, *s).visit(arg); - break; - case 'l': - if (*s == 'l') - ArgConverter(arg, *++s).visit(arg); - else - ArgConverter(arg, *s).visit(arg); - break; - case 'j': - ArgConverter(arg, *s).visit(arg); - break; - case 'z': - ArgConverter(arg, *s).visit(arg); - break; - case 't': - ArgConverter(arg, *s).visit(arg); - break; - case 'L': - // printf produces garbage when 'L' is omitted for long double, no - // need to do the same. - break; - default: - --s; - ArgConverter(arg, *s).visit(arg); - } - - // Parse type. - if (!*s) - FMT_THROW(FormatError("invalid format string")); - spec.type_ = static_cast(*s++); - if (arg.type <= Arg::LAST_INTEGER_TYPE) { - // Normalize type. - switch (spec.type_) { - case 'i': case 'u': - spec.type_ = 'd'; - break; - case 'c': - // TODO: handle wchar_t - CharConverter(arg).visit(arg); - break; - } - } - - start = s; - - // Format argument. - internal::PrintfArgFormatter(writer, spec).visit(arg); - } - write(writer, start, s); -} - -FMT_FUNC void fmt::report_system_error( +FMT_FUNC void report_system_error( int error_code, fmt::StringRef message) FMT_NOEXCEPT { // 'fmt::' is for bcc32. - fmt::report_error(internal::format_system_error, error_code, message); + report_error(format_system_error, error_code, message); } #if FMT_USE_WINDOWS_H -FMT_FUNC void fmt::report_windows_error( +FMT_FUNC void report_windows_error( int error_code, fmt::StringRef message) FMT_NOEXCEPT { // 'fmt::' is for bcc32. - fmt::report_error(internal::format_windows_error, error_code, message); + report_error(internal::format_windows_error, error_code, message); } #endif -FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) { +FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) { MemoryWriter w; w.write(format_str, args); std::fwrite(w.data(), 1, w.size(), f); } -FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) { +FMT_FUNC void print(CStringRef format_str, ArgList args) { print(stdout, format_str, args); } -FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) { +FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) { char escape[] = "\x1b[30m"; escape[3] = static_cast('0' + c); std::fputs(escape, stdout); @@ -883,53 +494,42 @@ FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) { std::fputs(RESET_COLOR, stdout); } -FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) { - MemoryWriter w; - printf(w, format, args); - std::size_t size = w.size(); - return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size); -} - #ifndef FMT_HEADER_ONLY -template struct fmt::internal::BasicData; +template struct internal::BasicData; // Explicit instantiations for char. -template void fmt::internal::FixedBuffer::grow(std::size_t); +template void internal::FixedBuffer::grow(std::size_t); -template void fmt::internal::ArgMap::init(const fmt::ArgList &args); +template void internal::ArgMap::init(const ArgList &args); -template void fmt::internal::PrintfFormatter::format( - BasicWriter &writer, CStringRef format); - -template int fmt::internal::CharTraits::format_float( +template FMT_API int internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, double value); -template int fmt::internal::CharTraits::format_float( +template FMT_API int internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, long double value); // Explicit instantiations for wchar_t. -template void fmt::internal::FixedBuffer::grow(std::size_t); +template void internal::FixedBuffer::grow(std::size_t); -template void fmt::internal::ArgMap::init(const fmt::ArgList &args); +template void internal::ArgMap::init(const ArgList &args); -template void fmt::internal::PrintfFormatter::format( - BasicWriter &writer, WCStringRef format); - -template int fmt::internal::CharTraits::format_float( +template FMT_API int internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, double value); -template int fmt::internal::CharTraits::format_float( +template FMT_API int internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, long double value); #endif // FMT_HEADER_ONLY +} // namespace fmt + #ifdef _MSC_VER # pragma warning(pop) #endif diff --git a/libs/format/fmt/format.h b/libs/format/fmt/format.h index 9c2827d46..85fdf24e9 100644 --- a/libs/format/fmt/format.h +++ b/libs/format/fmt/format.h @@ -25,7 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma once +#ifndef FMT_FORMAT_H_ +#define FMT_FORMAT_H_ #include #include @@ -37,7 +38,10 @@ #include #include #include -#include +#include // for std::pair + +// The fmt library version in the form major * 10000 + minor * 100 + patch. +#define FMT_VERSION 40000 #ifdef _SECURE_SCL # define FMT_SECURE_SCL _SECURE_SCL @@ -49,7 +53,13 @@ # include #endif -#if defined(_MSC_VER) && _MSC_VER <= 1500 +#ifdef _MSC_VER +# define FMT_MSC_VER _MSC_VER +#else +# define FMT_MSC_VER 0 +#endif + +#if FMT_MSC_VER && FMT_MSC_VER <= 1500 typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; typedef __int64 intmax_t; @@ -97,8 +107,10 @@ typedef __int64 intmax_t; #endif #if defined(__clang__) && !defined(FMT_ICC_VERSION) +# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) # pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdocumentation" +# pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +# pragma clang diagnostic ignored "-Wpadded" #endif #ifdef __GNUC_LIBSTD__ @@ -129,7 +141,7 @@ typedef __int64 intmax_t; // since version 2013. # define FMT_USE_VARIADIC_TEMPLATES \ (FMT_HAS_FEATURE(cxx_variadic_templates) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800) + (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800) #endif #ifndef FMT_USE_RVALUE_REFERENCES @@ -140,19 +152,15 @@ typedef __int64 intmax_t; # else # define FMT_USE_RVALUE_REFERENCES \ (FMT_HAS_FEATURE(cxx_rvalue_references) || \ - (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600) + (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600) # endif #endif -#if FMT_USE_RVALUE_REFERENCES -# include // for std::move -#endif - // Check if exceptions are disabled. #if defined(__GNUC__) && !defined(__EXCEPTIONS) # define FMT_EXCEPTIONS 0 #endif -#if defined(_MSC_VER) && !_HAS_EXCEPTIONS +#if FMT_MSC_VER && !_HAS_EXCEPTIONS # define FMT_EXCEPTIONS 0 #endif #ifndef FMT_EXCEPTIONS @@ -172,20 +180,50 @@ typedef __int64 intmax_t; # define FMT_USE_NOEXCEPT 0 #endif +#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ + (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ + FMT_MSC_VER >= 1900 +# define FMT_DETECTED_NOEXCEPT noexcept +#else +# define FMT_DETECTED_NOEXCEPT throw() +#endif + #ifndef FMT_NOEXCEPT # if FMT_EXCEPTIONS -# if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ - _MSC_VER >= 1900 -# define FMT_NOEXCEPT noexcept -# else -# define FMT_NOEXCEPT throw() -# endif +# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT # else # define FMT_NOEXCEPT # endif #endif +// This is needed because GCC still uses throw() in its headers when exceptions +// are disabled. +#if FMT_GCC_VERSION +# define FMT_DTOR_NOEXCEPT FMT_DETECTED_NOEXCEPT +#else +# define FMT_DTOR_NOEXCEPT FMT_NOEXCEPT +#endif + +#ifndef FMT_OVERRIDE +# if (defined(FMT_USE_OVERRIDE) && FMT_USE_OVERRIDE) || FMT_HAS_FEATURE(cxx_override) || \ + (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ + FMT_MSC_VER >= 1900 +# define FMT_OVERRIDE override +# else +# define FMT_OVERRIDE +# endif +#endif + +#ifndef FMT_NULL +# if FMT_HAS_FEATURE(cxx_nullptr) || \ + (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ + FMT_MSC_VER >= 1600 +# define FMT_NULL nullptr +# else +# define FMT_NULL NULL +# endif +#endif + // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for a class #ifndef FMT_USE_DELETED_FUNCTIONS @@ -193,7 +231,7 @@ typedef __int64 intmax_t; #endif #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800 + (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800 # define FMT_DELETED_OR_UNDEFINED = delete # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ @@ -205,6 +243,20 @@ typedef __int64 intmax_t; TypeName& operator=(const TypeName&) #endif +#ifndef FMT_USE_DEFAULTED_FUNCTIONS +# define FMT_USE_DEFAULTED_FUNCTIONS 0 +#endif + +#ifndef FMT_DEFAULTED_COPY_CTOR +# if FMT_USE_DEFAULTED_FUNCTIONS || FMT_HAS_FEATURE(cxx_defaulted_functions) || \ + (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800 +# define FMT_DEFAULTED_COPY_CTOR(TypeName) \ + TypeName(const TypeName&) = default; +# else +# define FMT_DEFAULTED_COPY_CTOR(TypeName) +# endif +#endif + #ifndef FMT_USE_USER_DEFINED_LITERALS // All compilers which support UDLs also support variadic templates. This // makes the fmt::literals implementation easier. However, an explicit check @@ -213,28 +265,42 @@ typedef __int64 intmax_t; # define FMT_USE_USER_DEFINED_LITERALS \ FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \ (FMT_HAS_FEATURE(cxx_user_literals) || \ - (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) && \ + (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \ (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500) #endif +#ifndef FMT_USE_EXTERN_TEMPLATES +# define FMT_USE_EXTERN_TEMPLATES \ + (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) +#endif + +#ifdef FMT_HEADER_ONLY +// If header only do not use extern templates. +# undef FMT_USE_EXTERN_TEMPLATES +# define FMT_USE_EXTERN_TEMPLATES 0 +#endif + #ifndef FMT_ASSERT # define FMT_ASSERT(condition, message) assert((condition) && message) #endif +// __builtin_clz is broken in clang with Microsoft CodeGen: +// https://github.com/fmtlib/fmt/issues/519 +#ifndef _MSC_VER +# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) +# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) +# endif -#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) -# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) +# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) +# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) +# endif #endif -#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) -# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) -#endif - -// Some compilers masquerade as both MSVC and GCC-likes or +// Some compilers masquerade as both MSVC and GCC-likes or // otherwise support __builtin_clz and __builtin_clzll, so // only define FMT_BUILTIN_CLZ using the MSVC intrinsics // if the clz and clzll builtins are not available. -#if defined(_MSC_VER) && !defined(FMT_BUILTIN_CLZLL) +#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) # include // _BitScanReverse, _BitScanReverse64 namespace fmt { @@ -246,7 +312,7 @@ inline uint32_t clz(uint32_t x) { assert(x != 0); // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, + // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. # pragma warning(suppress: 6102) return 31 - r; @@ -272,7 +338,7 @@ inline uint32_t clzll(uint64_t x) { assert(x != 0); // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, + // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. # pragma warning(suppress: 6102) return 63 - r; @@ -297,14 +363,12 @@ inline DummyInt _ecvt_s(...) { return DummyInt(); } inline DummyInt isinf(...) { return DummyInt(); } inline DummyInt _finite(...) { return DummyInt(); } inline DummyInt isnan(...) { return DummyInt(); } -#ifndef _MSC_VER inline DummyInt _isnan(...) { return DummyInt(); } -#endif // A helper function to suppress bogus "conditional expression is constant" // warnings. template -inline T check(T value) { return value; } +inline T const_check(T value) { return value; } } } // namespace fmt @@ -323,8 +387,8 @@ class numeric_limits : using namespace fmt::internal; // The resolution "priority" is: // isinf macro > std::isinf > ::isinf > fmt::internal::isinf - if (check(sizeof(isinf(x)) == sizeof(bool) || - sizeof(isinf(x)) == sizeof(int))) { + if (const_check(sizeof(isinf(x)) == sizeof(bool) || + sizeof(isinf(x)) == sizeof(int))) { return isinf(x) != 0; } return !_finite(static_cast(x)); @@ -334,8 +398,8 @@ class numeric_limits : template static bool isnotanumber(T x) { using namespace fmt::internal; - if (check(sizeof(isnan(x)) == sizeof(bool) || - sizeof(isnan(x)) == sizeof(int))) { + if (const_check(sizeof(isnan(x)) == sizeof(bool) || + sizeof(isnan(x)) == sizeof(int))) { return isnan(x) != 0; } return _isnan(static_cast(x)) != 0; @@ -344,8 +408,10 @@ class numeric_limits : // Portable version of signbit. static bool isnegative(double x) { using namespace fmt::internal; - if (check(sizeof(signbit(x)) == sizeof(int))) + if (const_check(sizeof(signbit(x)) == sizeof(bool) || + sizeof(signbit(x)) == sizeof(int))) { return signbit(x) != 0; + } if (x < 0) return true; if (!isnotanumber(x)) return false; int dec = 0, sign = 0; @@ -376,13 +442,19 @@ typedef BasicWriter WWriter; template class ArgFormatter; +struct FormatSpec; + +template +class BasicPrintfArgFormatter; + template > class BasicFormatter; /** \rst - A string reference. It can be constructed from a C string or ``std::string``. + A string reference. It can be constructed from a C string or + ``std::basic_string``. You can use one of the following typedefs for common character types: @@ -425,10 +497,12 @@ class BasicStringRef { /** \rst - Constructs a string reference from an ``std::string`` object. + Constructs a string reference from a ``std::basic_string`` object. \endrst */ - BasicStringRef(const std::basic_string &s) + template + BasicStringRef( + const std::basic_string, Allocator> &s) : data_(s.c_str()), size_(s.size()) {} /** @@ -481,7 +555,7 @@ typedef BasicStringRef WStringRef; /** \rst A reference to a null terminated string. It can be constructed from a C - string or ``std::string``. + string or ``std::basic_string``. You can use one of the following typedefs for common character types: @@ -514,10 +588,13 @@ class BasicCStringRef { /** \rst - Constructs a string reference from an ``std::string`` object. + Constructs a string reference from a ``std::basic_string`` object. \endrst */ - BasicCStringRef(const std::basic_string &s) : data_(s.c_str()) {} + template + BasicCStringRef( + const std::basic_string, Allocator> &s) + : data_(s.c_str()) {} /** Returns the pointer to a C string. */ const Char *c_str() const { return data_; } @@ -526,13 +603,13 @@ class BasicCStringRef { typedef BasicCStringRef CStringRef; typedef BasicCStringRef WCStringRef; -/** - A formatting error such as invalid format string. -*/ +/** A formatting error such as invalid format string. */ class FormatError : public std::runtime_error { public: explicit FormatError(CStringRef message) : std::runtime_error(message.c_str()) {} + FormatError(const FormatError &ferr) : std::runtime_error(ferr) {} + FMT_API ~FormatError() FMT_DTOR_NOEXCEPT; }; namespace internal { @@ -590,7 +667,7 @@ class Buffer { std::size_t size_; std::size_t capacity_; - Buffer(T *ptr = 0, std::size_t capacity = 0) + Buffer(T *ptr = FMT_NULL, std::size_t capacity = 0) : ptr_(ptr), size_(0), capacity_(capacity) {} /** @@ -648,7 +725,8 @@ class Buffer { template template void Buffer::append(const U *begin, const U *end) { - std::size_t new_size = size_ + internal::to_unsigned(end - begin); + FMT_ASSERT(end >= begin, "negative value"); + std::size_t new_size = size_ + (end - begin); if (new_size > capacity_) grow(new_size); std::uninitialized_copy(begin, end, @@ -658,8 +736,8 @@ void Buffer::append(const U *begin, const U *end) { namespace internal { -// A memory buffer for trivially copyable/constructible types with the first SIZE -// elements stored in the object itself. +// A memory buffer for trivially copyable/constructible types with the first +// SIZE elements stored in the object itself. template > class MemoryBuffer : private Allocator, public Buffer { private: @@ -671,7 +749,7 @@ class MemoryBuffer : private Allocator, public Buffer { } protected: - void grow(std::size_t size); + void grow(std::size_t size) FMT_OVERRIDE; public: explicit MemoryBuffer(const Allocator &alloc = Allocator()) @@ -720,7 +798,7 @@ void MemoryBuffer::grow(std::size_t size) { std::size_t new_capacity = this->capacity_ + this->capacity_ / 2; if (size > new_capacity) new_capacity = size; - T *new_ptr = this->allocate(new_capacity); + T *new_ptr = this->allocate(new_capacity, FMT_NULL); // The following code doesn't throw, so the raw pointer above doesn't leak. std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity)); @@ -742,7 +820,7 @@ class FixedBuffer : public fmt::Buffer { FixedBuffer(Char *array, std::size_t size) : fmt::Buffer(array, size) {} protected: - FMT_API void grow(std::size_t size); + FMT_API void grow(std::size_t size) FMT_OVERRIDE; }; template @@ -774,6 +852,15 @@ class CharTraits : public BasicCharTraits { const char *format, unsigned width, int precision, T value); }; +#if FMT_USE_EXTERN_TEMPLATES +extern template int CharTraits::format_float + (char *buffer, std::size_t size, + const char* format, unsigned width, int precision, double value); +extern template int CharTraits::format_float + (char *buffer, std::size_t size, + const char* format, unsigned width, int precision, long double value); +#endif + template <> class CharTraits : public BasicCharTraits { public: @@ -785,6 +872,15 @@ class CharTraits : public BasicCharTraits { const wchar_t *format, unsigned width, int precision, T value); }; +#if FMT_USE_EXTERN_TEMPLATES +extern template int CharTraits::format_float + (wchar_t *buffer, std::size_t size, + const wchar_t* format, unsigned width, int precision, double value); +extern template int CharTraits::format_float + (wchar_t *buffer, std::size_t size, + const wchar_t* format, unsigned width, int precision, long double value); +#endif + // Checks if a number is negative - used to avoid warnings. template struct SignChecker { @@ -831,6 +927,10 @@ struct FMT_API BasicData { static const char DIGITS[]; }; +#if FMT_USE_EXTERN_TEMPLATES +extern template struct BasicData; +#endif + typedef BasicData<> Data; #ifdef FMT_BUILTIN_CLZLL @@ -919,12 +1019,14 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits, } unsigned index = static_cast(value * 2); *--buffer = Data::DIGITS[index + 1]; + thousands_sep(buffer); *--buffer = Data::DIGITS[index]; } template inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) { - return format_decimal(buffer, value, num_digits, NoThousandsSep()); + format_decimal(buffer, value, num_digits, NoThousandsSep()); + return; } #ifndef _WIN32 @@ -974,9 +1076,6 @@ FMT_API void format_windows_error(fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT; #endif -FMT_API void format_system_error(fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT; - // A formatting argument value. struct Value { template @@ -1026,6 +1125,8 @@ struct Arg : Value { template struct NamedArg; +template +struct NamedArgWithType; template struct Null {}; @@ -1074,7 +1175,9 @@ struct ConvertToIntImpl2 { template struct ConvertToInt { - enum { enable_conversion = sizeof(convert(get())) == sizeof(Yes) }; + enum { + enable_conversion = sizeof(fmt::internal::convert(get())) == sizeof(Yes) + }; enum { value = ConvertToIntImpl2::value }; }; @@ -1100,12 +1203,59 @@ template struct Conditional { typedef F type; }; // For bcc32 which doesn't understand ! in template arguments. -template +template struct Not { enum { value = 0 }; }; -template<> +template <> struct Not { enum { value = 1 }; }; +template +struct FalseType { enum { value = 0 }; }; + +template struct LConvCheck { + LConvCheck(int) {} +}; + +// Returns the thousands separator for the current locale. +// We check if ``lconv`` contains ``thousands_sep`` because on Android +// ``lconv`` is stubbed as an empty struct. +template +inline StringRef thousands_sep( + LConv *lc, LConvCheck = 0) { + return lc->thousands_sep; +} + +inline fmt::StringRef thousands_sep(...) { return ""; } + +#define FMT_CONCAT(a, b) a##b + +#if FMT_GCC_VERSION >= 303 +# define FMT_UNUSED __attribute__((unused)) +#else +# define FMT_UNUSED +#endif + +#ifndef FMT_USE_STATIC_ASSERT +# define FMT_USE_STATIC_ASSERT 0 +#endif + +#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \ + (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600 +# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) +#else +# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) +# define FMT_STATIC_ASSERT(cond, message) \ + typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED +#endif + +template +void format_arg(Formatter &, const Char *, const T &) { + FMT_STATIC_ASSERT(FalseType::value, + "Cannot format argument. To enable the use of ostream " + "operator<< include fmt/ostream.h. Otherwise provide " + "an overload of format_arg."); +} + // Makes an Arg object from any type. template class MakeValue : public Arg { @@ -1127,7 +1277,7 @@ class MakeValue : public Arg { // characters and strings into narrow strings as in // fmt::format("{}", L"test"); // To fix this, use a wide format string: fmt::format(L"{}", L"test"). -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +#if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) MakeValue(typename WCharHelper::Unsupported); #endif MakeValue(typename WCharHelper::Unsupported); @@ -1149,9 +1299,9 @@ class MakeValue : public Arg { template static void format_custom_arg( void *formatter, const void *arg, void *format_str_ptr) { - format(*static_cast(formatter), - *static_cast(format_str_ptr), - *static_cast(arg)); + format_arg(*static_cast(formatter), + *static_cast(format_str_ptr), + *static_cast(arg)); } public: @@ -1173,7 +1323,7 @@ class MakeValue : public Arg { MakeValue(long value) { // To minimize the number of types we need to deal with, long is // translated either to int or to long long depending on its size. - if (check(sizeof(long) == sizeof(int))) + if (const_check(sizeof(long) == sizeof(int))) int_value = static_cast(value); else long_long_value = value; @@ -1183,7 +1333,7 @@ class MakeValue : public Arg { } MakeValue(unsigned long value) { - if (check(sizeof(unsigned long) == sizeof(unsigned))) + if (const_check(sizeof(unsigned long) == sizeof(unsigned))) uint_value = static_cast(value); else ulong_long_value = value; @@ -1215,7 +1365,9 @@ class MakeValue : public Arg { FMT_MAKE_VALUE(char *, string.value, CSTRING) FMT_MAKE_VALUE(const char *, string.value, CSTRING) + FMT_MAKE_VALUE(signed char *, sstring.value, CSTRING) FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) + FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING) FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) FMT_MAKE_STR_VALUE(const std::string &, STRING) FMT_MAKE_STR_VALUE(StringRef, STRING) @@ -1244,23 +1396,22 @@ class MakeValue : public Arg { } template - MakeValue(const T &value, - typename EnableIf::value, int>::type = 0) { - int_value = value; - } - - template - static uint64_t type(const T &) { - return ConvertToInt::value ? Arg::INT : Arg::CUSTOM; + static typename EnableIf::value>::value, uint64_t>::type + type(const T &) { + return Arg::CUSTOM; } // Additional template param `Char_` is needed here because make_type always // uses char. template MakeValue(const NamedArg &value) { pointer = &value; } + template + MakeValue(const NamedArgWithType &value) { pointer = &value; } template static uint64_t type(const NamedArg &) { return Arg::NAMED_ARG; } + template + static uint64_t type(const NamedArgWithType &) { return Arg::NAMED_ARG; } }; template @@ -1269,7 +1420,7 @@ public: MakeArg() { type = Arg::NONE; } - + template MakeArg(const T &value) : Arg(MakeValue(value)) { @@ -1286,14 +1437,19 @@ struct NamedArg : Arg { : Arg(MakeArg< BasicFormatter >(value)), name(argname) {} }; +template +struct NamedArgWithType : NamedArg { + NamedArgWithType(BasicStringRef argname, const T &value) + : NamedArg(argname, value) {} +}; + class RuntimeError : public std::runtime_error { protected: RuntimeError() : std::runtime_error("") {} + RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {} + FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT; }; -template -class PrintfArgFormatter; - template class ArgMap; } // namespace internal @@ -1315,10 +1471,7 @@ class ArgList { }; internal::Arg::Type type(unsigned index) const { - unsigned shift = index * 4; - uint64_t mask = 0xf; - return static_cast( - (types_ & (mask << shift)) >> shift); + return type(types_, index); } template @@ -1335,6 +1488,8 @@ class ArgList { ArgList(ULongLong types, const internal::Arg *args) : types_(types), args_(args) {} + uint64_t types() const { return types_; } + /** Returns the argument at specified index. */ internal::Arg operator[](unsigned index) const { using internal::Arg; @@ -1360,6 +1515,13 @@ class ArgList { } return args_[index]; } + + static internal::Arg::Type type(uint64_t types, unsigned index) { + unsigned shift = index * 4; + uint64_t mask = 0xf; + return static_cast( + (types & (mask << shift)) >> shift); + } }; #define FMT_DISPATCH(call) static_cast(this)->call @@ -1488,9 +1650,10 @@ class ArgVisitor { */ Result visit(const Arg &arg) { switch (arg.type) { - default: + case Arg::NONE: + case Arg::NAMED_ARG: FMT_ASSERT(false, "invalid argument type"); - return Result(); + break; case Arg::INT: return FMT_DISPATCH(visit_int(arg.int_value)); case Arg::UINT: @@ -1518,6 +1681,7 @@ class ArgVisitor { case Arg::CUSTOM: return FMT_DISPATCH(visit_custom(arg.custom)); } + return Result(); } }; @@ -1542,6 +1706,7 @@ struct TypeSpec : EmptySpec { int precision() const { return -1; } bool flag(unsigned) const { return false; } char type() const { return TYPE; } + char type_prefix() const { return TYPE; } char fill() const { return ' '; } }; @@ -1577,6 +1742,7 @@ struct AlignTypeSpec : AlignSpec { bool flag(unsigned) const { return false; } char type() const { return TYPE; } + char type_prefix() const { return TYPE; } }; // A full format specifier. @@ -1592,6 +1758,7 @@ struct FormatSpec : AlignSpec { bool flag(unsigned f) const { return (flags_ & f) != 0; } int precision() const { return precision_; } char type() const { return type_; } + char type_prefix() const { return type_; } }; // An integer format specifier. @@ -1758,22 +1925,22 @@ class ArgMap { public: FMT_API void init(const ArgList &args); - const internal::Arg* find(const fmt::BasicStringRef &name) const { + const internal::Arg *find(const fmt::BasicStringRef &name) const { // The list is unsorted, so just return the first matching name. for (typename MapType::const_iterator it = map_.begin(), end = map_.end(); it != end; ++it) { if (it->first == name) return &it->second; } - return 0; + return FMT_NULL; } }; -template +template class ArgFormatterBase : public ArgVisitor { private: BasicWriter &writer_; - FormatSpec &spec_; + Spec &spec_; FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase); @@ -1783,9 +1950,12 @@ class ArgFormatterBase : public ArgVisitor { writer_.write_int(reinterpret_cast(p), spec_); } + // workaround MSVC two-phase lookup issue + typedef internal::Arg Arg; + protected: BasicWriter &writer() { return writer_; } - FormatSpec &spec() { return spec_; } + Spec &spec() { return spec_; } void write(bool value) { const char *str_value = value ? "true" : "false"; @@ -1794,12 +1964,14 @@ class ArgFormatterBase : public ArgVisitor { } void write(const char *value) { - Arg::StringValue str = {value, value != 0 ? std::strlen(value) : 0}; + Arg::StringValue str = {value, value ? std::strlen(value) : 0}; writer_.write_str(str, spec_); } public: - ArgFormatterBase(BasicWriter &w, FormatSpec &s) + typedef Spec SpecType; + + ArgFormatterBase(BasicWriter &w, Spec &s) : writer_(w), spec_(s) {} template @@ -1809,8 +1981,10 @@ class ArgFormatterBase : public ArgVisitor { void visit_any_double(T value) { writer_.write_double(value, spec_); } void visit_bool(bool value) { - if (spec_.type_) - return visit_any_int(value); + if (spec_.type_) { + visit_any_int(value); + return; + } write(value); } @@ -1825,21 +1999,21 @@ class ArgFormatterBase : public ArgVisitor { typedef typename BasicWriter::CharPtr CharPtr; Char fill = internal::CharTraits::cast(spec_.fill()); CharPtr out = CharPtr(); - - if (spec_.width_ > CHAR_WIDTH) { + const unsigned CHAR_SIZE = 1; + if (spec_.width_ > CHAR_SIZE) { out = writer_.grow_buffer(spec_.width_); if (spec_.align_ == ALIGN_RIGHT) { - std::uninitialized_fill_n(out, spec_.width_ - CHAR_WIDTH, fill); - out += spec_.width_ - CHAR_WIDTH; + std::uninitialized_fill_n(out, spec_.width_ - CHAR_SIZE, fill); + out += spec_.width_ - CHAR_SIZE; } else if (spec_.align_ == ALIGN_CENTER) { out = writer_.fill_padding(out, spec_.width_, - internal::check(CHAR_WIDTH), fill); + internal::const_check(CHAR_SIZE), fill); } else { - std::uninitialized_fill_n(out + CHAR_WIDTH, - spec_.width_ - CHAR_WIDTH, fill); + std::uninitialized_fill_n(out + CHAR_SIZE, + spec_.width_ - CHAR_SIZE, fill); } } else { - out = writer_.grow_buffer(CHAR_WIDTH); + out = writer_.grow_buffer(CHAR_SIZE); } *out = internal::CharTraits::cast(value); } @@ -1850,13 +2024,14 @@ class ArgFormatterBase : public ArgVisitor { write(value); } - void visit_string(Arg::StringValue value) { + // Qualification with "internal" here and below is a workaround for nvcc. + void visit_string(internal::Arg::StringValue value) { writer_.write_str(value, spec_); } using ArgVisitor::visit_wstring; - void visit_wstring(Arg::StringValue value) { + void visit_wstring(internal::Arg::StringValue value) { writer_.write_str(value, spec_); } @@ -1912,26 +2087,6 @@ class FormatterBase { w << BasicStringRef(start, internal::to_unsigned(end - start)); } }; - -// A printf formatter. -template -class PrintfFormatter : private FormatterBase { - private: - void parse_flags(FormatSpec &spec, const Char *&s); - - // Returns the argument with specified index or, if arg_index is equal - // to the maximum unsigned value, the next argument. - Arg get_arg(const Char *s, - unsigned arg_index = (std::numeric_limits::max)()); - - // Parses argument index, flags and width and returns the argument index. - unsigned parse_header(const Char *&s, FormatSpec &spec); - - public: - explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {} - FMT_API void format(BasicWriter &writer, - BasicCStringRef format_str); -}; } // namespace internal /** @@ -1951,8 +2106,8 @@ class PrintfFormatter : private FormatterBase { will be called. \endrst */ -template -class BasicArgFormatter : public internal::ArgFormatterBase { +template +class BasicArgFormatter : public internal::ArgFormatterBase { private: BasicFormatter &formatter_; const Char *format_; @@ -1967,11 +2122,11 @@ class BasicArgFormatter : public internal::ArgFormatterBase { \endrst */ BasicArgFormatter(BasicFormatter &formatter, - FormatSpec &spec, const Char *fmt) - : internal::ArgFormatterBase(formatter.writer(), spec), + Spec &spec, const Char *fmt) + : internal::ArgFormatterBase(formatter.writer(), spec), formatter_(formatter), format_(fmt) {} - /** Formats argument of a custom (user-defined) type. */ + /** Formats an argument of a custom (user-defined) type. */ void visit_custom(internal::Arg::CustomValue c) { c.format(&formatter_, c.value, &format_); } @@ -1979,12 +2134,14 @@ class BasicArgFormatter : public internal::ArgFormatterBase { /** The default argument formatter. */ template -class ArgFormatter : public BasicArgFormatter, Char> { +class ArgFormatter : + public BasicArgFormatter, Char, FormatSpec> { public: /** Constructs an argument formatter object. */ ArgFormatter(BasicFormatter &formatter, FormatSpec &spec, const Char *fmt) - : BasicArgFormatter, Char>(formatter, spec, fmt) {} + : BasicArgFormatter, + Char, FormatSpec>(formatter, spec, fmt) {} }; /** This template formats data and writes the output to a writer. */ @@ -2060,13 +2217,13 @@ inline uint64_t make_type(const T &arg) { return MakeValue< BasicFormatter >::type(arg); } -template +template struct ArgArray; -template +template struct ArgArray { typedef Value Type[N > 0 ? N : 1]; - + template static Value make(const T &value) { #ifdef __clang__ @@ -2081,7 +2238,7 @@ struct ArgArray { } }; -template +template struct ArgArray { typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE @@ -2221,7 +2378,7 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { */ class SystemError : public internal::RuntimeError { private: - void init(int err_code, CStringRef format_str, ArgList args); + FMT_API void init(int err_code, CStringRef format_str, ArgList args); protected: int error_code_; @@ -2233,17 +2390,10 @@ class SystemError : public internal::RuntimeError { public: /** \rst - Constructs a :class:`fmt::SystemError` object with the description - of the form - - .. parsed-literal:: - **: ** - - where ** is the formatted message and ** is - the system message corresponding to the error code. - *error_code* is a system error code as given by ``errno``. - If *error_code* is not a valid error code such as -1, the system message - may look like "Unknown error -1" and is platform-dependent. + Constructs a :class:`fmt::SystemError` object with a description + formatted with `fmt::format_system_error`. *message* and additional + arguments passed into the constructor are formatted similarly to + `fmt::format`. **Example**:: @@ -2259,11 +2409,33 @@ class SystemError : public internal::RuntimeError { SystemError(int error_code, CStringRef message) { init(error_code, message, ArgList()); } + FMT_DEFAULTED_COPY_CTOR(SystemError) FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef) + FMT_API ~SystemError() FMT_DTOR_NOEXCEPT; + int error_code() const { return error_code_; } }; +/** + \rst + Formats an error returned by an operating system or a language runtime, + for example a file opening error, and writes it to *out* in the following + form: + + .. parsed-literal:: + **: ** + + where ** is the passed message and ** is + the system message corresponding to the error code. + *error_code* is a system error code as given by ``errno``. + If *error_code* is not a valid error code such as -1, the system message + may look like "Unknown error -1" and is platform-dependent. + \endrst + */ +FMT_API void format_system_error(fmt::Writer &out, int error_code, + fmt::StringRef message) FMT_NOEXCEPT; + /** \rst This template provides operations for formatting and writing data into @@ -2352,16 +2524,16 @@ class BasicWriter { void write_int(T value, Spec spec); // Formats a floating-point number (double or long double). - template - void write_double(T value, const FormatSpec &spec); + template + void write_double(T value, const Spec &spec); // Writes a formatted string. template CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec); - template + template void write_str(const internal::Arg::StringValue &str, - const FormatSpec &spec); + const Spec &spec); // This following methods are private to disallow writing wide characters // and strings to a char stream. If you want to print a wide string as a @@ -2380,10 +2552,11 @@ class BasicWriter { template void append_float_length(Char *&, T) {} - template + template friend class internal::ArgFormatterBase; - friend class internal::PrintfArgFormatter; + template + friend class BasicPrintfArgFormatter; protected: /** @@ -2579,9 +2752,9 @@ typename BasicWriter::CharPtr BasicWriter::write_str( } template -template +template void BasicWriter::write_str( - const internal::Arg::StringValue &s, const FormatSpec &spec) { + const internal::Arg::StringValue &s, const Spec &spec) { // Check if StrChar is convertible to Char. internal::CharTraits::convert(StrChar()); if (spec.type_ && spec.type_ != 's') @@ -2591,7 +2764,6 @@ void BasicWriter::write_str( if (str_size == 0) { if (!str_value) { FMT_THROW(FormatError("string pointer is null")); - return; } } std::size_t precision = static_cast(spec.precision_); @@ -2706,7 +2878,7 @@ void BasicWriter::write_int(T value, Spec spec) { UnsignedType n = abs_value; if (spec.flag(HASH_FLAG)) { prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type(); + prefix[prefix_size++] = spec.type_prefix(); } unsigned num_digits = 0; do { @@ -2726,7 +2898,7 @@ void BasicWriter::write_int(T value, Spec spec) { UnsignedType n = abs_value; if (spec.flag(HASH_FLAG)) { prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type(); + prefix[prefix_size++] = spec.type_prefix(); } unsigned num_digits = 0; do { @@ -2756,9 +2928,12 @@ void BasicWriter::write_int(T value, Spec spec) { } case 'n': { unsigned num_digits = internal::count_digits(abs_value); - fmt::StringRef sep = std::localeconv()->thousands_sep; + fmt::StringRef sep = ""; +#if !(defined(ANDROID) || defined(__ANDROID__)) + sep = internal::thousands_sep(std::localeconv()); +#endif unsigned size = static_cast( - num_digits + sep.size() * (num_digits - 1) / 3); + num_digits + sep.size() * ((num_digits - 1) / 3)); CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1; internal::format_decimal(get(p), abs_value, 0, internal::ThousandsSep(sep)); break; @@ -2771,8 +2946,8 @@ void BasicWriter::write_int(T value, Spec spec) { } template -template -void BasicWriter::write_double(T value, const FormatSpec &spec) { +template +void BasicWriter::write_double(T value, const Spec &spec) { // Check type. char type = spec.type(); bool upper = false; @@ -2783,7 +2958,7 @@ void BasicWriter::write_double(T value, const FormatSpec &spec) { case 'e': case 'f': case 'g': case 'a': break; case 'F': -#ifdef _MSC_VER +#if FMT_MSC_VER // MSVC's printf doesn't support 'F'. type = 'f'; #endif @@ -2873,10 +3048,10 @@ void BasicWriter::write_double(T value, const FormatSpec &spec) { // Format using snprintf. Char fill = internal::CharTraits::cast(spec.fill()); unsigned n = 0; - Char *start = 0; + Char *start = FMT_NULL; for (;;) { std::size_t buffer_size = buffer_.capacity() - offset; -#ifdef _MSC_VER +#if FMT_MSC_VER // MSVC's vsnprintf_s doesn't work with zero size, so reserve // space for at least one extra character to make the size non-zero. // Note that the buffer's capacity will increase by more than 1. @@ -3150,56 +3325,6 @@ FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args); */ FMT_API void print(CStringRef format_str, ArgList args); -template -void printf(BasicWriter &w, BasicCStringRef format, ArgList args) { - internal::PrintfFormatter(args).format(w, format); -} - -/** - \rst - Formats arguments and returns the result as a string. - - **Example**:: - - std::string message = fmt::sprintf("The answer is %d", 42); - \endrst -*/ -inline std::string sprintf(CStringRef format, ArgList args) { - MemoryWriter w; - printf(w, format, args); - return w.str(); -} - -inline std::wstring sprintf(WCStringRef format, ArgList args) { - WMemoryWriter w; - printf(w, format, args); - return w.str(); -} - -/** - \rst - Prints formatted data to the file *f*. - - **Example**:: - - fmt::fprintf(stderr, "Don't %s!", "panic"); - \endrst - */ -FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args); - -/** - \rst - Prints formatted data to ``stdout``. - - **Example**:: - - fmt::printf("Elapsed time: %.2f seconds", 1.23); - \endrst - */ -inline int printf(CStringRef format, ArgList args) { - return fprintf(stdout, format, args); -} - /** Fast integer formatter. */ @@ -3316,13 +3441,13 @@ inline void format_decimal(char *&buffer, T value) { \endrst */ template -inline internal::NamedArg arg(StringRef name, const T &arg) { - return internal::NamedArg(name, arg); +inline internal::NamedArgWithType arg(StringRef name, const T &arg) { + return internal::NamedArgWithType(name, arg); } template -inline internal::NamedArg arg(WStringRef name, const T &arg) { - return internal::NamedArg(name, arg); +inline internal::NamedArgWithType arg(WStringRef name, const T &arg) { + return internal::NamedArgWithType(name, arg); } // The following two functions are deleted intentionally to disable @@ -3351,7 +3476,6 @@ void arg(WStringRef, const internal::NamedArg&) FMT_DELETED_OR_UNDEFINED; #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 -#define FMT_CONCAT(a, b) a##b #define FMT_FOR_EACH_(N, f, ...) \ FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) #define FMT_FOR_EACH(f, ...) \ @@ -3465,12 +3589,7 @@ FMT_VARIADIC(std::string, format, CStringRef) FMT_VARIADIC_W(std::wstring, format, WCStringRef) FMT_VARIADIC(void, print, CStringRef) FMT_VARIADIC(void, print, std::FILE *, CStringRef) - FMT_VARIADIC(void, print_colored, Color, CStringRef) -FMT_VARIADIC(std::string, sprintf, CStringRef) -FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) -FMT_VARIADIC(int, printf, CStringRef) -FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) namespace internal { template @@ -3535,7 +3654,7 @@ inline internal::Arg BasicFormatter::get_arg( template inline internal::Arg BasicFormatter::parse_arg_index(const Char *&s) { - const char *error = 0; + const char *error = FMT_NULL; internal::Arg arg = *s < '0' || *s > '9' ? next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error); if (error) { @@ -3553,7 +3672,7 @@ inline internal::Arg BasicFormatter::parse_arg_name(const Char *&s) { do { c = *++s; } while (internal::is_name_start(c) || ('0' <= c && c <= '9')); - const char *error = 0; + const char *error = FMT_NULL; internal::Arg arg = get_arg(BasicStringRef(start, s - start), error); if (error) FMT_THROW(FormatError(error)); @@ -3565,7 +3684,7 @@ const Char *BasicFormatter::format( const Char *&format_str, const internal::Arg &arg) { using internal::Arg; const Char *s = format_str; - FormatSpec spec; + typename ArgFormatter::SpecType spec; if (*s == ':') { if (arg.type == Arg::CUSTOM) { arg.custom.format(this, arg.custom.value, &s); @@ -3751,6 +3870,66 @@ void BasicFormatter::format(BasicCStringRef format_str) { } write(writer_, start, s); } + +template +struct ArgJoin { + It first; + It last; + BasicCStringRef sep; + + ArgJoin(It first, It last, const BasicCStringRef& sep) : + first(first), + last(last), + sep(sep) {} +}; + +template +ArgJoin join(It first, It last, const BasicCStringRef& sep) { + return ArgJoin(first, last, sep); +} + +template +ArgJoin join(It first, It last, const BasicCStringRef& sep) { + return ArgJoin(first, last, sep); +} + +#if FMT_HAS_GXX_CXX11 +template +auto join(const Range& range, const BasicCStringRef& sep) + -> ArgJoin { + return join(std::begin(range), std::end(range), sep); +} + +template +auto join(const Range& range, const BasicCStringRef& sep) + -> ArgJoin { + return join(std::begin(range), std::end(range), sep); +} +#endif + +template +void format_arg(fmt::BasicFormatter &f, + const Char *&format_str, const ArgJoin& e) { + const Char* end = format_str; + if (*end == ':') + ++end; + while (*end && *end != '}') + ++end; + if (*end != '}') + FMT_THROW(FormatError("missing '}' in format string")); + + It it = e.first; + if (it != e.last) { + const Char* save = format_str; + f.format(format_str, internal::MakeArg >(*it++)); + while (it != e.last) { + f.writer().write(e.sep); + format_str = save; + f.format(format_str, internal::MakeArg >(*it++)); + } + } + format_str = end + 1; +} } // namespace fmt #if FMT_USE_USER_DEFINED_LITERALS @@ -3773,7 +3952,7 @@ struct UdlArg { const Char *str; template - NamedArg operator=(T &&value) const { + NamedArgWithType operator=(T &&value) const { return {str, std::forward(value)}; } }; @@ -3832,3 +4011,4 @@ operator"" _a(const wchar_t *s, std::size_t) { return {s}; } # define FMT_FUNC #endif +#endif // FMT_FORMAT_H_ diff --git a/libs/format/fmt/ostream.cc b/libs/format/fmt/ostream.cc index 0ba303478..2d443f730 100644 --- a/libs/format/fmt/ostream.cc +++ b/libs/format/fmt/ostream.cc @@ -4,34 +4,15 @@ Copyright (c) 2012 - 2016, Victor Zverovich All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. 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. - - 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. + For the license information refer to format.h. */ #include "ostream.h" namespace fmt { -namespace { -// Write the content of w to os. -void write(std::ostream &os, Writer &w) { +namespace internal { +FMT_FUNC void write(std::ostream &os, Writer &w) { const char *data = w.data(); typedef internal::MakeUnsigned::Type UnsignedStreamSize; UnsignedStreamSize size = w.size(); @@ -49,13 +30,6 @@ void write(std::ostream &os, Writer &w) { FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) { MemoryWriter w; w.write(format_str, args); - write(os, w); -} - -FMT_FUNC int fprintf(std::ostream &os, CStringRef format, ArgList args) { - MemoryWriter w; - printf(w, format, args); - write(os, w); - return static_cast(w.size()); + internal::write(os, w); } } // namespace fmt diff --git a/libs/format/fmt/ostream.h b/libs/format/fmt/ostream.h index 458d31de3..84a02d173 100644 --- a/libs/format/fmt/ostream.h +++ b/libs/format/fmt/ostream.h @@ -4,25 +4,7 @@ Copyright (c) 2012 - 2016, Victor Zverovich All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. 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. - - 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. + For the license information refer to format.h. */ #ifndef FMT_OSTREAM_H_ @@ -42,28 +24,27 @@ class FormatBuf : public std::basic_streambuf { typedef typename std::basic_streambuf::traits_type traits_type; Buffer &buffer_; - Char *start_; public: - FormatBuf(Buffer &buffer) : buffer_(buffer), start_(&buffer[0]) { - this->setp(start_, start_ + buffer_.capacity()); - } + FormatBuf(Buffer &buffer) : buffer_(buffer) {} - int_type overflow(int_type ch = traits_type::eof()) { - if (!traits_type::eq_int_type(ch, traits_type::eof())) { - size_t buf_size = size(); - buffer_.resize(buf_size); - buffer_.reserve(buf_size * 2); + protected: + // The put-area is actually always empty. This makes the implementation + // simpler and has the advantage that the streambuf and the buffer are always + // in sync and sputc never writes into uninitialized memory. The obvious + // disadvantage is that each call to sputc always results in a (virtual) call + // to overflow. There is no disadvantage here for sputn since this always + // results in a call to xsputn. - start_ = &buffer_[0]; - start_[buf_size] = traits_type::to_char_type(ch); - this->setp(start_+ buf_size + 1, start_ + buf_size * 2); - } + int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE { + if (!traits_type::eq_int_type(ch, traits_type::eof())) + buffer_.push_back(static_cast(ch)); return ch; } - size_t size() const { - return to_unsigned(this->pptr() - start_); + std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE { + buffer_.append(s, s + count); + return count; } }; @@ -84,19 +65,22 @@ struct ConvertToIntImpl { value = sizeof(convert(get() << get())) == sizeof(No) }; }; + +// Write the content of w to os. +FMT_API void write(std::ostream &os, Writer &w); } // namespace internal // Formats a value. -template -void format(BasicFormatter &f, - const Char *&format_str, const T &value) { +template +void format_arg(BasicFormatter &f, + const Char *&format_str, const T &value) { internal::MemoryBuffer buffer; internal::FormatBuf format_buf(buffer); std::basic_ostream output(&format_buf); output << value; - BasicStringRef str(&buffer[0], format_buf.size()); + BasicStringRef str(&buffer[0], buffer.size()); typedef internal::MakeArg< BasicFormatter > MakeArg; format_str = f.format(format_str, MakeArg(str)); } @@ -112,18 +96,6 @@ void format(BasicFormatter &f, */ FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args); FMT_VARIADIC(void, print, std::ostream &, CStringRef) - -/** - \rst - Prints formatted data to the stream *os*. - - **Example**:: - - fprintf(cerr, "Don't %s!", "panic"); - \endrst - */ -FMT_API int fprintf(std::ostream &os, CStringRef format_str, ArgList args); -FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef) } // namespace fmt #ifdef FMT_HEADER_ONLY diff --git a/libs/format/fmt/posix.cc b/libs/format/fmt/posix.cc index 1ec746a46..356668c13 100644 --- a/libs/format/fmt/posix.cc +++ b/libs/format/fmt/posix.cc @@ -1,28 +1,10 @@ /* A C++ interface to POSIX functions. - Copyright (c) 2014 - 2016, Victor Zverovich + Copyright (c) 2012 - 2016, Victor Zverovich All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. 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. - - 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. + For the license information refer to format.h. */ // Disable bogus MSVC warnings. @@ -39,6 +21,9 @@ #ifndef _WIN32 # include #else +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include # include @@ -90,16 +75,16 @@ fmt::BufferedFile::BufferedFile( fmt::CStringRef filename, fmt::CStringRef mode) { FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), 0); if (!file_) - throw SystemError(errno, "cannot open file {}", filename); + FMT_THROW(SystemError(errno, "cannot open file {}", filename)); } void fmt::BufferedFile::close() { if (!file_) return; int result = FMT_SYSTEM(fclose(file_)); - file_ = 0; + file_ = FMT_NULL; if (result != 0) - throw SystemError(errno, "cannot close file"); + FMT_THROW(SystemError(errno, "cannot close file")); } // A macro used to prevent expansion of fileno on broken versions of MinGW. @@ -108,7 +93,7 @@ void fmt::BufferedFile::close() { int fmt::BufferedFile::fileno() const { int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_)); if (fd == -1) - throw SystemError(errno, "cannot get file descriptor"); + FMT_THROW(SystemError(errno, "cannot get file descriptor")); return fd; } @@ -121,7 +106,7 @@ fmt::File::File(fmt::CStringRef path, int oflag) { FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); #endif if (fd_ == -1) - throw SystemError(errno, "cannot open file {}", path); + FMT_THROW(SystemError(errno, "cannot open file {}", path)); } fmt::File::~File() FMT_NOEXCEPT { @@ -139,7 +124,7 @@ void fmt::File::close() { int result = FMT_POSIX_CALL(close(fd_)); fd_ = -1; if (result != 0) - throw SystemError(errno, "cannot close file"); + FMT_THROW(SystemError(errno, "cannot close file")); } fmt::LongLong fmt::File::size() const { @@ -153,7 +138,7 @@ fmt::LongLong fmt::File::size() const { if (size_lower == INVALID_FILE_SIZE) { DWORD error = GetLastError(); if (error != NO_ERROR) - throw WindowsError(GetLastError(), "cannot get file size"); + FMT_THROW(WindowsError(GetLastError(), "cannot get file size")); } fmt::ULongLong long_size = size_upper; return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower; @@ -161,7 +146,7 @@ fmt::LongLong fmt::File::size() const { typedef struct stat Stat; Stat file_stat = Stat(); if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) - throw SystemError(errno, "cannot get file attributes"); + FMT_THROW(SystemError(errno, "cannot get file attributes")); FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size), "return type of File::size is not large enough"); return file_stat.st_size; @@ -172,7 +157,7 @@ std::size_t fmt::File::read(void *buffer, std::size_t count) { RWResult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count)))); if (result < 0) - throw SystemError(errno, "cannot read from file"); + FMT_THROW(SystemError(errno, "cannot read from file")); return internal::to_unsigned(result); } @@ -180,7 +165,7 @@ std::size_t fmt::File::write(const void *buffer, std::size_t count) { RWResult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count)))); if (result < 0) - throw SystemError(errno, "cannot write to file"); + FMT_THROW(SystemError(errno, "cannot write to file")); return internal::to_unsigned(result); } @@ -189,7 +174,7 @@ fmt::File fmt::File::dup(int fd) { // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html int new_fd = FMT_POSIX_CALL(dup(fd)); if (new_fd == -1) - throw SystemError(errno, "cannot duplicate file descriptor {}", fd); + FMT_THROW(SystemError(errno, "cannot duplicate file descriptor {}", fd)); return File(new_fd); } @@ -197,8 +182,8 @@ void fmt::File::dup2(int fd) { int result = 0; FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); if (result == -1) { - throw SystemError(errno, - "cannot duplicate file descriptor {} to {}", fd_, fd); + FMT_THROW(SystemError(errno, + "cannot duplicate file descriptor {} to {}", fd_, fd)); } } @@ -225,7 +210,7 @@ void fmt::File::pipe(File &read_end, File &write_end) { int result = FMT_POSIX_CALL(pipe(fds)); #endif if (result != 0) - throw SystemError(errno, "cannot create pipe"); + FMT_THROW(SystemError(errno, "cannot create pipe")); // The following assignments don't throw because read_fd and write_fd // are closed. read_end = File(fds[0]); @@ -236,7 +221,7 @@ fmt::BufferedFile fmt::File::fdopen(const char *mode) { // Don't retry as fdopen doesn't return EINTR. FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode)); if (!f) - throw SystemError(errno, "cannot associate stream with file descriptor"); + FMT_THROW(SystemError(errno, "cannot associate stream with file descriptor")); BufferedFile file(f); fd_ = -1; return file; @@ -250,7 +235,7 @@ long fmt::getpagesize() { #else long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); if (size < 0) - throw SystemError(errno, "cannot get memory page size"); + FMT_THROW(SystemError(errno, "cannot get memory page size")); return size; #endif } diff --git a/libs/format/fmt/posix.h b/libs/format/fmt/posix.h index ab6d12e87..88512de55 100644 --- a/libs/format/fmt/posix.h +++ b/libs/format/fmt/posix.h @@ -1,34 +1,16 @@ /* A C++ interface to POSIX functions. - Copyright (c) 2014 - 2016, Victor Zverovich + Copyright (c) 2012 - 2016, Victor Zverovich All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. 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. - - 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. + For the license information refer to format.h. */ #ifndef FMT_POSIX_H_ #define FMT_POSIX_H_ -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(__CYGWIN__) // Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/. # undef __STRICT_ANSI__ #endif @@ -41,7 +23,7 @@ #include -#ifdef __APPLE__ +#if defined __APPLE__ || defined(__FreeBSD__) # include // for LC_NUMERIC_MASK on OS X #endif @@ -69,25 +51,6 @@ # endif #endif -#if FMT_GCC_VERSION >= 407 -# define FMT_UNUSED __attribute__((unused)) -#else -# define FMT_UNUSED -#endif - -#ifndef FMT_USE_STATIC_ASSERT -# define FMT_USE_STATIC_ASSERT 0 -#endif - -#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \ - (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600 -# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) -#else -# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) -# define FMT_STATIC_ASSERT(cond, message) \ - typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED -#endif - // Retries the expression while it evaluates to error_result and errno // equals to EINTR. #ifndef _WIN32 @@ -125,10 +88,10 @@ class BufferedFile { public: // Constructs a BufferedFile object which doesn't represent any file. - BufferedFile() FMT_NOEXCEPT : file_(0) {} + BufferedFile() FMT_NOEXCEPT : file_(FMT_NULL) {} // Destroys the object closing the file it represents if any. - ~BufferedFile() FMT_NOEXCEPT; + FMT_API ~BufferedFile() FMT_NOEXCEPT; #if !FMT_USE_RVALUE_REFERENCES // Emulate a move constructor and a move assignment operator if rvalue @@ -147,7 +110,7 @@ public: // A "move constructor" for moving from an lvalue. BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) { - f.file_ = 0; + f.file_ = FMT_NULL; } // A "move assignment operator" for moving from a temporary. @@ -161,7 +124,7 @@ public: BufferedFile &operator=(BufferedFile &other) { close(); file_ = other.file_; - other.file_ = 0; + other.file_ = FMT_NULL; return *this; } @@ -169,7 +132,7 @@ public: // BufferedFile file = BufferedFile(...); operator Proxy() FMT_NOEXCEPT { Proxy p = {file_}; - file_ = 0; + file_ = FMT_NULL; return p; } @@ -179,29 +142,29 @@ public: public: BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) { - other.file_ = 0; + other.file_ = FMT_NULL; } BufferedFile& operator=(BufferedFile &&other) { close(); file_ = other.file_; - other.file_ = 0; + other.file_ = FMT_NULL; return *this; } #endif // Opens a file. - BufferedFile(CStringRef filename, CStringRef mode); + FMT_API BufferedFile(CStringRef filename, CStringRef mode); // Closes the file. - void close(); + FMT_API void close(); // Returns the pointer to a FILE object representing this file. FILE *get() const FMT_NOEXCEPT { return file_; } // We place parentheses around fileno to workaround a bug in some versions // of MinGW that define fileno as a macro. - int (fileno)() const; + FMT_API int (fileno)() const; void print(CStringRef format_str, const ArgList &args) { fmt::print(file_, format_str, args); @@ -234,7 +197,7 @@ class File { File() FMT_NOEXCEPT : fd_(-1) {} // Opens a file and constructs a File object representing this file. - File(CStringRef path, int oflag); + FMT_API File(CStringRef path, int oflag); #if !FMT_USE_RVALUE_REFERENCES // Emulate a move constructor and a move assignment operator if rvalue @@ -297,49 +260,50 @@ class File { #endif // Destroys the object closing the file it represents if any. - ~File() FMT_NOEXCEPT; + FMT_API ~File() FMT_NOEXCEPT; // Returns the file descriptor. int descriptor() const FMT_NOEXCEPT { return fd_; } // Closes the file. - void close(); + FMT_API void close(); // Returns the file size. The size has signed type for consistency with // stat::st_size. - LongLong size() const; + FMT_API LongLong size() const; // Attempts to read count bytes from the file into the specified buffer. - std::size_t read(void *buffer, std::size_t count); + FMT_API std::size_t read(void *buffer, std::size_t count); // Attempts to write count bytes from the specified buffer to the file. - std::size_t write(const void *buffer, std::size_t count); + FMT_API std::size_t write(const void *buffer, std::size_t count); // Duplicates a file descriptor with the dup function and returns // the duplicate as a file object. - static File dup(int fd); + FMT_API static File dup(int fd); // Makes fd be the copy of this file descriptor, closing fd first if // necessary. - void dup2(int fd); + FMT_API void dup2(int fd); // Makes fd be the copy of this file descriptor, closing fd first if // necessary. - void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT; + FMT_API void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT; // Creates a pipe setting up read_end and write_end file objects for reading // and writing respectively. - static void pipe(File &read_end, File &write_end); + FMT_API static void pipe(File &read_end, File &write_end); // Creates a BufferedFile object associated with this file and detaches // this File object from the file. - BufferedFile fdopen(const char *mode); + FMT_API BufferedFile fdopen(const char *mode); }; // Returns the memory page size. long getpagesize(); -#if defined(LC_NUMERIC_MASK) || defined(_MSC_VER) +#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \ + !defined(__ANDROID__) && !defined(__CYGWIN__) # define FMT_LOCALE #endif @@ -372,9 +336,9 @@ class Locale { public: typedef locale_t Type; - Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL)) { + Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL)) { if (!locale_) - throw fmt::SystemError(errno, "cannot create locale"); + FMT_THROW(fmt::SystemError(errno, "cannot create locale")); } ~Locale() { freelocale(locale_); } @@ -383,7 +347,7 @@ class Locale { // Converts string to floating-point number and advances str past the end // of the parsed input. double strtod(const char *&str) const { - char *end = 0; + char *end = FMT_NULL; double result = strtod_l(str, &end, locale_); str = end; return result; diff --git a/libs/format/fmt/printf.cc b/libs/format/fmt/printf.cc new file mode 100644 index 000000000..95d7a36ab --- /dev/null +++ b/libs/format/fmt/printf.cc @@ -0,0 +1,32 @@ +/* + Formatting library for C++ + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#include "format.h" +#include "printf.h" + +namespace fmt { + +template +void printf(BasicWriter &w, BasicCStringRef format, ArgList args); + +FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) { + MemoryWriter w; + printf(w, format, args); + std::size_t size = w.size(); + return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size); +} + +#ifndef FMT_HEADER_ONLY + +template void PrintfFormatter::format(CStringRef format); +template void PrintfFormatter::format(WCStringRef format); + +#endif // FMT_HEADER_ONLY + +} // namespace fmt diff --git a/libs/format/fmt/printf.h b/libs/format/fmt/printf.h new file mode 100644 index 000000000..30cbc49ba --- /dev/null +++ b/libs/format/fmt/printf.h @@ -0,0 +1,603 @@ +/* + Formatting library for C++ + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#ifndef FMT_PRINTF_H_ +#define FMT_PRINTF_H_ + +#include // std::fill_n +#include // std::numeric_limits + +#include "ostream.h" + +namespace fmt { +namespace internal { + +// Checks if a value fits in int - used to avoid warnings about comparing +// signed and unsigned integers. +template +struct IntChecker { + template + static bool fits_in_int(T value) { + unsigned max = std::numeric_limits::max(); + return value <= max; + } + static bool fits_in_int(bool) { return true; } +}; + +template <> +struct IntChecker { + template + static bool fits_in_int(T value) { + return value >= std::numeric_limits::min() && + value <= std::numeric_limits::max(); + } + static bool fits_in_int(int) { return true; } +}; + +class PrecisionHandler : public ArgVisitor { + public: + void report_unhandled_arg() { + FMT_THROW(FormatError("precision is not integer")); + } + + template + int visit_any_int(T value) { + if (!IntChecker::is_signed>::fits_in_int(value)) + FMT_THROW(FormatError("number is too big")); + return static_cast(value); + } +}; + +// IsZeroInt::visit(arg) returns true iff arg is a zero integer. +class IsZeroInt : public ArgVisitor { + public: + template + bool visit_any_int(T value) { return value == 0; } +}; + +// returns the default type for format specific "%s" +class DefaultType : public ArgVisitor { + public: + char visit_char(int) { return 'c'; } + + char visit_bool(bool) { return 's'; } + + char visit_pointer(const void *) { return 'p'; } + + template + char visit_any_int(T) { return 'd'; } + + template + char visit_any_double(T) { return 'g'; } + + char visit_unhandled_arg() { return 's'; } +}; + +template +struct is_same { + enum { value = 0 }; +}; + +template +struct is_same { + enum { value = 1 }; +}; + +// An argument visitor that converts an integer argument to T for printf, +// if T is an integral type. If T is void, the argument is converted to +// corresponding signed or unsigned type depending on the type specifier: +// 'd' and 'i' - signed, other - unsigned) +template +class ArgConverter : public ArgVisitor, void> { + private: + internal::Arg &arg_; + wchar_t type_; + + FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); + + public: + ArgConverter(internal::Arg &arg, wchar_t type) + : arg_(arg), type_(type) {} + + void visit_bool(bool value) { + if (type_ != 's') + visit_any_int(value); + } + + void visit_char(char value) { + if (type_ != 's') + visit_any_int(value); + } + + template + void visit_any_int(U value) { + bool is_signed = type_ == 'd' || type_ == 'i'; + if (type_ == 's') { + is_signed = std::numeric_limits::is_signed; + } + + using internal::Arg; + typedef typename internal::Conditional< + is_same::value, U, T>::type TargetType; + if (sizeof(TargetType) <= sizeof(int)) { + // Extra casts are used to silence warnings. + if (is_signed) { + arg_.type = Arg::INT; + arg_.int_value = static_cast(static_cast(value)); + } else { + arg_.type = Arg::UINT; + typedef typename internal::MakeUnsigned::Type Unsigned; + arg_.uint_value = static_cast(static_cast(value)); + } + } else { + if (is_signed) { + arg_.type = Arg::LONG_LONG; + // glibc's printf doesn't sign extend arguments of smaller types: + // std::printf("%lld", -42); // prints "4294967254" + // but we don't have to do the same because it's a UB. + arg_.long_long_value = static_cast(value); + } else { + arg_.type = Arg::ULONG_LONG; + arg_.ulong_long_value = + static_cast::Type>(value); + } + } + } +}; + +// Converts an integer argument to char for printf. +class CharConverter : public ArgVisitor { + private: + internal::Arg &arg_; + + FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); + + public: + explicit CharConverter(internal::Arg &arg) : arg_(arg) {} + + template + void visit_any_int(T value) { + arg_.type = internal::Arg::CHAR; + arg_.int_value = static_cast(value); + } +}; + +// Checks if an argument is a valid printf width specifier and sets +// left alignment if it is negative. +class WidthHandler : public ArgVisitor { + private: + FormatSpec &spec_; + + FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler); + + public: + explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} + + void report_unhandled_arg() { + FMT_THROW(FormatError("width is not integer")); + } + + template + unsigned visit_any_int(T value) { + typedef typename internal::IntTraits::MainType UnsignedType; + UnsignedType width = static_cast(value); + if (internal::is_negative(value)) { + spec_.align_ = ALIGN_LEFT; + width = 0 - width; + } + unsigned int_max = std::numeric_limits::max(); + if (width > int_max) + FMT_THROW(FormatError("number is too big")); + return static_cast(width); + } +}; +} // namespace internal + +/** + \rst + A ``printf`` argument formatter based on the `curiously recurring template + pattern `_. + + To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some + or all of the visit methods with the same signatures as the methods in + `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`. + Pass the subclass as the *Impl* template parameter. When a formatting + function processes an argument, it will dispatch to a visit method + specific to the argument type. For example, if the argument type is + ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass + will be called. If the subclass doesn't contain a method with this signature, + then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its + superclass will be called. + \endrst + */ +template +class BasicPrintfArgFormatter : + public internal::ArgFormatterBase { + private: + void write_null_pointer() { + this->spec().type_ = 0; + this->write("(nil)"); + } + + typedef internal::ArgFormatterBase Base; + + public: + /** + \rst + Constructs an argument formatter object. + *writer* is a reference to the output writer and *spec* contains format + specifier information for standard argument types. + \endrst + */ + BasicPrintfArgFormatter(BasicWriter &w, Spec &s) + : internal::ArgFormatterBase(w, s) {} + + /** Formats an argument of type ``bool``. */ + void visit_bool(bool value) { + Spec &fmt_spec = this->spec(); + if (fmt_spec.type_ != 's') + return this->visit_any_int(value); + fmt_spec.type_ = 0; + this->write(value); + } + + /** Formats a character. */ + void visit_char(int value) { + const Spec &fmt_spec = this->spec(); + BasicWriter &w = this->writer(); + if (fmt_spec.type_ && fmt_spec.type_ != 'c') + w.write_int(value, fmt_spec); + typedef typename BasicWriter::CharPtr CharPtr; + CharPtr out = CharPtr(); + if (fmt_spec.width_ > 1) { + Char fill = ' '; + out = w.grow_buffer(fmt_spec.width_); + if (fmt_spec.align_ != ALIGN_LEFT) { + std::fill_n(out, fmt_spec.width_ - 1, fill); + out += fmt_spec.width_ - 1; + } else { + std::fill_n(out + 1, fmt_spec.width_ - 1, fill); + } + } else { + out = w.grow_buffer(1); + } + *out = static_cast(value); + } + + /** Formats a null-terminated C string. */ + void visit_cstring(const char *value) { + if (value) + Base::visit_cstring(value); + else if (this->spec().type_ == 'p') + write_null_pointer(); + else + this->write("(null)"); + } + + /** Formats a pointer. */ + void visit_pointer(const void *value) { + if (value) + return Base::visit_pointer(value); + this->spec().type_ = 0; + write_null_pointer(); + } + + /** Formats an argument of a custom (user-defined) type. */ + void visit_custom(internal::Arg::CustomValue c) { + BasicFormatter formatter(ArgList(), this->writer()); + const Char format_str[] = {'}', 0}; + const Char *format = format_str; + c.format(&formatter, c.value, &format); + } +}; + +/** The default printf argument formatter. */ +template +class PrintfArgFormatter : + public BasicPrintfArgFormatter, Char, FormatSpec> { + public: + /** Constructs an argument formatter object. */ + PrintfArgFormatter(BasicWriter &w, FormatSpec &s) + : BasicPrintfArgFormatter, Char, FormatSpec>(w, s) {} +}; + +/** This template formats data and writes the output to a writer. */ +template > +class PrintfFormatter : private internal::FormatterBase { + private: + BasicWriter &writer_; + + void parse_flags(FormatSpec &spec, const Char *&s); + + // Returns the argument with specified index or, if arg_index is equal + // to the maximum unsigned value, the next argument. + internal::Arg get_arg( + const Char *s, + unsigned arg_index = (std::numeric_limits::max)()); + + // Parses argument index, flags and width and returns the argument index. + unsigned parse_header(const Char *&s, FormatSpec &spec); + + public: + /** + \rst + Constructs a ``PrintfFormatter`` object. References to the arguments and + the writer are stored in the formatter object so make sure they have + appropriate lifetimes. + \endrst + */ + explicit PrintfFormatter(const ArgList &al, BasicWriter &w) + : FormatterBase(al), writer_(w) {} + + /** Formats stored arguments and writes the output to the writer. */ + void format(BasicCStringRef format_str); +}; + +template +void PrintfFormatter::parse_flags(FormatSpec &spec, const Char *&s) { + for (;;) { + switch (*s++) { + case '-': + spec.align_ = ALIGN_LEFT; + break; + case '+': + spec.flags_ |= SIGN_FLAG | PLUS_FLAG; + break; + case '0': + spec.fill_ = '0'; + break; + case ' ': + spec.flags_ |= SIGN_FLAG; + break; + case '#': + spec.flags_ |= HASH_FLAG; + break; + default: + --s; + return; + } + } +} + +template +internal::Arg PrintfFormatter::get_arg(const Char *s, + unsigned arg_index) { + (void)s; + const char *error = FMT_NULL; + internal::Arg arg = arg_index == std::numeric_limits::max() ? + next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); + if (error) + FMT_THROW(FormatError(!*s ? "invalid format string" : error)); + return arg; +} + +template +unsigned PrintfFormatter::parse_header( + const Char *&s, FormatSpec &spec) { + unsigned arg_index = std::numeric_limits::max(); + Char c = *s; + if (c >= '0' && c <= '9') { + // Parse an argument index (if followed by '$') or a width possibly + // preceded with '0' flag(s). + unsigned value = internal::parse_nonnegative_int(s); + if (*s == '$') { // value is an argument index + ++s; + arg_index = value; + } else { + if (c == '0') + spec.fill_ = '0'; + if (value != 0) { + // Nonzero value means that we parsed width and don't need to + // parse it or flags again, so return now. + spec.width_ = value; + return arg_index; + } + } + } + parse_flags(spec, s); + // Parse width. + if (*s >= '0' && *s <= '9') { + spec.width_ = internal::parse_nonnegative_int(s); + } else if (*s == '*') { + ++s; + spec.width_ = internal::WidthHandler(spec).visit(get_arg(s)); + } + return arg_index; +} + +template +void PrintfFormatter::format(BasicCStringRef format_str) { + const Char *start = format_str.c_str(); + const Char *s = start; + while (*s) { + Char c = *s++; + if (c != '%') continue; + if (*s == c) { + write(writer_, start, s); + start = ++s; + continue; + } + write(writer_, start, s - 1); + + FormatSpec spec; + spec.align_ = ALIGN_RIGHT; + + // Parse argument index, flags and width. + unsigned arg_index = parse_header(s, spec); + + // Parse precision. + if (*s == '.') { + ++s; + if ('0' <= *s && *s <= '9') { + spec.precision_ = static_cast(internal::parse_nonnegative_int(s)); + } else if (*s == '*') { + ++s; + spec.precision_ = internal::PrecisionHandler().visit(get_arg(s)); + } else { + spec.precision_ = 0; + } + } + + using internal::Arg; + Arg arg = get_arg(s, arg_index); + if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg)) + spec.flags_ &= ~internal::to_unsigned(HASH_FLAG); + if (spec.fill_ == '0') { + if (arg.type <= Arg::LAST_NUMERIC_TYPE) + spec.align_ = ALIGN_NUMERIC; + else + spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. + } + + // Parse length and convert the argument to the required type. + using internal::ArgConverter; + switch (*s++) { + case 'h': + if (*s == 'h') + ArgConverter(arg, *++s).visit(arg); + else + ArgConverter(arg, *s).visit(arg); + break; + case 'l': + if (*s == 'l') + ArgConverter(arg, *++s).visit(arg); + else + ArgConverter(arg, *s).visit(arg); + break; + case 'j': + ArgConverter(arg, *s).visit(arg); + break; + case 'z': + ArgConverter(arg, *s).visit(arg); + break; + case 't': + ArgConverter(arg, *s).visit(arg); + break; + case 'L': + // printf produces garbage when 'L' is omitted for long double, no + // need to do the same. + break; + default: + --s; + ArgConverter(arg, *s).visit(arg); + } + + // Parse type. + if (!*s) + FMT_THROW(FormatError("invalid format string")); + spec.type_ = static_cast(*s++); + + if (spec.type_ == 's') { + // set the format type to the default if 's' is specified + spec.type_ = internal::DefaultType().visit(arg); + } + + if (arg.type <= Arg::LAST_INTEGER_TYPE) { + // Normalize type. + switch (spec.type_) { + case 'i': case 'u': + spec.type_ = 'd'; + break; + case 'c': + // TODO: handle wchar_t + internal::CharConverter(arg).visit(arg); + break; + } + } + + start = s; + + // Format argument. + AF(writer_, spec).visit(arg); + } + write(writer_, start, s); +} + +inline void printf(Writer &w, CStringRef format, ArgList args) { + PrintfFormatter(args, w).format(format); +} +FMT_VARIADIC(void, printf, Writer &, CStringRef) + +inline void printf(WWriter &w, WCStringRef format, ArgList args) { + PrintfFormatter(args, w).format(format); +} +FMT_VARIADIC(void, printf, WWriter &, WCStringRef) + +/** + \rst + Formats arguments and returns the result as a string. + + **Example**:: + + std::string message = fmt::sprintf("The answer is %d", 42); + \endrst +*/ +inline std::string sprintf(CStringRef format, ArgList args) { + MemoryWriter w; + printf(w, format, args); + return w.str(); +} +FMT_VARIADIC(std::string, sprintf, CStringRef) + +inline std::wstring sprintf(WCStringRef format, ArgList args) { + WMemoryWriter w; + printf(w, format, args); + return w.str(); +} +FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) + +/** + \rst + Prints formatted data to the file *f*. + + **Example**:: + + fmt::fprintf(stderr, "Don't %s!", "panic"); + \endrst + */ +FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args); +FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) + +/** + \rst + Prints formatted data to ``stdout``. + + **Example**:: + + fmt::printf("Elapsed time: %.2f seconds", 1.23); + \endrst + */ +inline int printf(CStringRef format, ArgList args) { + return fprintf(stdout, format, args); +} +FMT_VARIADIC(int, printf, CStringRef) + +/** + \rst + Prints formatted data to the stream *os*. + + **Example**:: + + fprintf(cerr, "Don't %s!", "panic"); + \endrst + */ +inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args) { + MemoryWriter w; + printf(w, format_str, args); + internal::write(os, w); + return static_cast(w.size()); +} +FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef) +} // namespace fmt + +#ifdef FMT_HEADER_ONLY +# include "printf.cc" +#endif + +#endif // FMT_PRINTF_H_ diff --git a/libs/format/fmt/string.h b/libs/format/fmt/string.h new file mode 100644 index 000000000..ccf46ee11 --- /dev/null +++ b/libs/format/fmt/string.h @@ -0,0 +1,126 @@ +/* + Formatting library for C++ - string utilities + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#ifndef FMT_STRING_H_ +#define FMT_STRING_H_ + +#include "format.h" + +namespace fmt { + +namespace internal { + +// A buffer that stores data in ``std::basic_string``. +template > +class StringBuffer : public Buffer { + public: + typedef std::basic_string, Allocator> StringType; + + private: + StringType data_; + + protected: + virtual void grow(std::size_t size) FMT_OVERRIDE { + data_.resize(size); + this->ptr_ = &data_[0]; + this->capacity_ = size; + } + + public: + explicit StringBuffer(const Allocator &allocator = Allocator()) + : data_(allocator) {} + + // Moves the data to ``str`` clearing the buffer. + void move_to(StringType &str) { + data_.resize(this->size_); + str.swap(data_); + this->capacity_ = this->size_ = 0; + this->ptr_ = FMT_NULL; + } +}; +} // namespace internal + +/** + \rst + This class template provides operations for formatting and writing data + into a character stream. The output is stored in a ``std::basic_string`` + that grows dynamically. + + You can use one of the following typedefs for common character types + and the standard allocator: + + +---------------+----------------------------+ + | Type | Definition | + +===============+============================+ + | StringWriter | BasicStringWriter | + +---------------+----------------------------+ + | WStringWriter | BasicStringWriter | + +---------------+----------------------------+ + + **Example**:: + + StringWriter out; + out << "The answer is " << 42 << "\n"; + + This will write the following output to the ``out`` object: + + .. code-block:: none + + The answer is 42 + + The output can be moved to a ``std::basic_string`` with ``out.move_to()``. + \endrst + */ +template > +class BasicStringWriter : public BasicWriter { + private: + internal::StringBuffer buffer_; + + public: + /** + \rst + Constructs a :class:`fmt::BasicStringWriter` object. + \endrst + */ + explicit BasicStringWriter(const Allocator &allocator = Allocator()) + : BasicWriter(buffer_), buffer_(allocator) {} + + /** + \rst + Moves the buffer content to *str* clearing the buffer. + \endrst + */ + void move_to(std::basic_string, Allocator> &str) { + buffer_.move_to(str); + } +}; + +typedef BasicStringWriter StringWriter; +typedef BasicStringWriter WStringWriter; + +/** + \rst + Converts *value* to ``std::string`` using the default format for type *T*. + + **Example**:: + + #include "fmt/string.h" + + std::string answer = fmt::to_string(42); + \endrst + */ +template +std::string to_string(const T &value) { + fmt::MemoryWriter w; + w << value; + return w.str(); +} +} + +#endif // FMT_STRING_H_ diff --git a/libs/format/fmt/time.h b/libs/format/fmt/time.h index 863382c0b..c98b0e011 100644 --- a/libs/format/fmt/time.h +++ b/libs/format/fmt/time.h @@ -4,37 +4,25 @@ Copyright (c) 2012 - 2016, Victor Zverovich All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. 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. - - 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. + For the license information refer to format.h. */ #ifndef FMT_TIME_H_ #define FMT_TIME_H_ -#include "fmt/format.h" +#include "format.h" #include +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code +# pragma warning(disable: 4996) // "deprecated" functions +#endif + namespace fmt { template -void format(BasicFormatter &f, - const char *&format_str, const std::tm &tm) { +void format_arg(BasicFormatter &f, + const char *&format_str, const std::tm &tm) { if (*format_str == ':') ++format_str; const char *end = format_str; @@ -54,11 +42,102 @@ void format(BasicFormatter &f, buffer.resize(start + count); break; } + if (size >= format.size() * 256) { + // If the buffer is 256 times larger than the format string, assume + // that `strftime` gives an empty result. There doesn't seem to be a + // better way to distinguish the two cases: + // https://github.com/fmtlib/fmt/issues/367 + break; + } const std::size_t MIN_GROWTH = 10; - buffer.reserve(buffer.capacity() + size > MIN_GROWTH ? size : MIN_GROWTH); + buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH)); } format_str = end + 1; } + +namespace internal{ +inline Null<> localtime_r(...) { return Null<>(); } +inline Null<> localtime_s(...) { return Null<>(); } +inline Null<> gmtime_r(...) { return Null<>(); } +inline Null<> gmtime_s(...) { return Null<>(); } } +// Thread-safe replacement for std::localtime +inline std::tm localtime(std::time_t time) { + struct LocalTime { + std::time_t time_; + std::tm tm_; + + LocalTime(std::time_t t): time_(t) {} + + bool run() { + using namespace fmt::internal; + return handle(localtime_r(&time_, &tm_)); + } + + bool handle(std::tm *tm) { return tm != FMT_NULL; } + + bool handle(internal::Null<>) { + using namespace fmt::internal; + return fallback(localtime_s(&tm_, &time_)); + } + + bool fallback(int res) { return res == 0; } + + bool fallback(internal::Null<>) { + using namespace fmt::internal; + std::tm *tm = std::localtime(&time_); + if (tm) tm_ = *tm; + return tm != FMT_NULL; + } + }; + LocalTime lt(time); + if (lt.run()) + return lt.tm_; + // Too big time values may be unsupported. + FMT_THROW(fmt::FormatError("time_t value out of range")); + return std::tm(); +} + +// Thread-safe replacement for std::gmtime +inline std::tm gmtime(std::time_t time) { + struct GMTime { + std::time_t time_; + std::tm tm_; + + GMTime(std::time_t t): time_(t) {} + + bool run() { + using namespace fmt::internal; + return handle(gmtime_r(&time_, &tm_)); + } + + bool handle(std::tm *tm) { return tm != FMT_NULL; } + + bool handle(internal::Null<>) { + using namespace fmt::internal; + return fallback(gmtime_s(&tm_, &time_)); + } + + bool fallback(int res) { return res == 0; } + + bool fallback(internal::Null<>) { + std::tm *tm = std::gmtime(&time_); + if (tm != FMT_NULL) tm_ = *tm; + return tm != FMT_NULL; + } + }; + GMTime gt(time); + if (gt.run()) + return gt.tm_; + // Too big time values may be unsupported. + FMT_THROW(fmt::FormatError("time_t value out of range")); + return std::tm(); +} +} //namespace fmt + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + #endif // FMT_TIME_H_ diff --git a/libs/format/support/appveyor-build.py b/libs/format/support/appveyor-build.py index a5b684ef3..3b747f3cc 100644 --- a/libs/format/support/appveyor-build.py +++ b/libs/format/support/appveyor-build.py @@ -10,22 +10,23 @@ platform = os.environ.get('PLATFORM') path = os.environ['PATH'] cmake_command = ['cmake', '-DFMT_PEDANTIC=ON', '-DCMAKE_BUILD_TYPE=' + config] if build == 'mingw': - cmake_command.append('-GMinGW Makefiles') - build_command = ['mingw32-make', '-j4'] - test_command = ['mingw32-make', 'test'] - # Remove the path to Git bin directory from $PATH because it breaks MinGW config. - path = path.replace(r'C:\Program Files (x86)\Git\bin', '') - os.environ['PATH'] = r'C:\MinGW\bin;' + path + cmake_command.append('-GMinGW Makefiles') + build_command = ['mingw32-make', '-j4'] + test_command = ['mingw32-make', 'test'] + # Remove the path to Git bin directory from $PATH because it breaks + # MinGW config. + path = path.replace(r'C:\Program Files (x86)\Git\bin', '') + os.environ['PATH'] = r'C:\MinGW\bin;' + path else: - # Add MSBuild 14.0 to PATH as described in - # http://help.appveyor.com/discussions/problems/2229-v140-not-found-on-vs2105rc. - os.environ['PATH'] = r'C:\Program Files (x86)\MSBuild\14.0\Bin;' + path - generator = 'Visual Studio 14 2015' - if platform == 'x64': - generator += ' Win64' - cmake_command.append('-G' + generator) - build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4'] - test_command = ['ctest', '-C', config] + # Add MSBuild 14.0 to PATH as described in + # http://help.appveyor.com/discussions/problems/2229-v140-not-found-on-vs2105rc. + os.environ['PATH'] = r'C:\Program Files (x86)\MSBuild\14.0\Bin;' + path + generator = 'Visual Studio 14 2015' + if platform == 'x64': + generator += ' Win64' + cmake_command.append('-G' + generator) + build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4'] + test_command = ['ctest', '-C', config] check_call(cmake_command) check_call(build_command) diff --git a/libs/format/support/appveyor.yml b/libs/format/support/appveyor.yml index 087512c31..a651c525f 100644 --- a/libs/format/support/appveyor.yml +++ b/libs/format/support/appveyor.yml @@ -20,3 +20,7 @@ build_script: on_failure: - appveyor PushArtifact Testing/Temporary/LastTest.log - appveyor AddTest test + +# Uncomment this to debug AppVeyor failures. +#on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/libs/format/support/cmake/cxx11.cmake b/libs/format/support/cmake/cxx11.cmake index 31ea1063e..21d125433 100644 --- a/libs/format/support/cmake/cxx11.cmake +++ b/libs/format/support/cmake/cxx11.cmake @@ -20,7 +20,14 @@ if (FMT_USE_CPP11) check_cxx_source_compiles(" #include int main() {}" FMT_CPP11_UNISTD_H) - if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H) + # Check if snprintf works with -std=c++11. It may not in MinGW. + check_cxx_source_compiles(" + #include + int main() { + char buffer[10]; + snprintf(buffer, 10, \"foo\"); + }" FMT_CPP11_SNPRINTF) + if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H AND FMT_CPP11_SNPRINTF) set(CPP11_FLAG -std=c++11) else () check_cxx_compiler_flag(-std=gnu++11 HAVE_STD_GNUPP11_FLAG) @@ -37,6 +44,11 @@ if (FMT_USE_CPP11) endif () endif () +if (CMAKE_CXX_STANDARD) + # Don't use -std compiler flag if CMAKE_CXX_STANDARD is specified. + set(CPP11_FLAG ) +endif () + set(CMAKE_REQUIRED_FLAGS ${CPP11_FLAG}) # Check if variadic templates are working and not affected by GCC bug 39653: diff --git a/libs/format/support/manage.py b/libs/format/support/manage.py new file mode 100644 index 000000000..1da371d49 --- /dev/null +++ b/libs/format/support/manage.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python + +"""Manage site and releases. + +Usage: + manage.py release [] + manage.py site +""" + +from __future__ import print_function +import datetime, docopt, fileinput, json, os +import re, requests, shutil, sys, tempfile +from contextlib import contextmanager +from distutils.version import LooseVersion +from subprocess import check_call + + +class Git: + def __init__(self, dir): + self.dir = dir + + def call(self, method, args, **kwargs): + return check_call(['git', method] + list(args), **kwargs) + + def add(self, *args): + return self.call('add', args, cwd=self.dir) + + def checkout(self, *args): + return self.call('checkout', args, cwd=self.dir) + + def clean(self, *args): + return self.call('clean', args, cwd=self.dir) + + def clone(self, *args): + return self.call('clone', list(args) + [self.dir]) + + def commit(self, *args): + return self.call('commit', args, cwd=self.dir) + + def pull(self, *args): + return self.call('pull', args, cwd=self.dir) + + def push(self, *args): + return self.call('push', args, cwd=self.dir) + + def reset(self, *args): + return self.call('reset', args, cwd=self.dir) + + def update(self, *args): + clone = not os.path.exists(self.dir) + if clone: + self.clone(*args) + return clone + + +def clean_checkout(repo, branch): + repo.clean('-f', '-d') + repo.reset('--hard') + repo.checkout(branch) + + +class Runner: + def __init__(self, cwd): + self.cwd = cwd + + def __call__(self, *args, **kwargs): + kwargs['cwd'] = kwargs.get('cwd', self.cwd) + check_call(args, **kwargs) + + +def create_build_env(): + """Create a build environment.""" + class Env: + pass + env = Env() + + # Import the documentation build module. + env.fmt_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + sys.path.insert(0, os.path.join(env.fmt_dir, 'doc')) + import build + + env.build_dir = 'build' + + # Virtualenv and repos are cached to speed up builds. + build.create_build_env(os.path.join(env.build_dir, 'virtualenv')) + + env.fmt_repo = Git(os.path.join(env.build_dir, 'fmt')) + return env + + +@contextmanager +def rewrite(filename): + class Buffer: + pass + buffer = Buffer() + if not os.path.exists(filename): + buffer.data = '' + yield buffer + return + with open(filename) as f: + buffer.data = f.read() + yield buffer + with open(filename, 'w') as f: + f.write(buffer.data) + + +fmt_repo_url = 'git@github.com:fmtlib/fmt' + + +def update_site(env): + env.fmt_repo.update(fmt_repo_url) + + doc_repo = Git(os.path.join(env.build_dir, 'fmtlib.github.io')) + doc_repo.update('git@github.com:fmtlib/fmtlib.github.io') + + for version in ['1.0.0', '1.1.0', '2.0.0', '3.0.0']: + clean_checkout(env.fmt_repo, version) + target_doc_dir = os.path.join(env.fmt_repo.dir, 'doc') + # Remove the old theme. + for entry in os.listdir(target_doc_dir): + path = os.path.join(target_doc_dir, entry) + if os.path.isdir(path): + shutil.rmtree(path) + # Copy the new theme. + for entry in ['_static', '_templates', 'basic-bootstrap', 'bootstrap', + 'conf.py', 'fmt.less']: + src = os.path.join(env.fmt_dir, 'doc', entry) + dst = os.path.join(target_doc_dir, entry) + copy = shutil.copytree if os.path.isdir(src) else shutil.copyfile + copy(src, dst) + # Rename index to contents. + contents = os.path.join(target_doc_dir, 'contents.rst') + if not os.path.exists(contents): + os.rename(os.path.join(target_doc_dir, 'index.rst'), contents) + # Fix issues in reference.rst/api.rst. + for filename in ['reference.rst', 'api.rst']: + pattern = re.compile('doxygenfunction.. (bin|oct|hexu|hex)$', re.M) + with rewrite(os.path.join(target_doc_dir, filename)) as b: + b.data = b.data.replace('std::ostream &', 'std::ostream&') + b.data = re.sub(pattern, r'doxygenfunction:: \1(int)', b.data) + b.data = b.data.replace('std::FILE*', 'std::FILE *') + b.data = b.data.replace('unsigned int', 'unsigned') + # Fix a broken link in index.rst. + index = os.path.join(target_doc_dir, 'index.rst') + with rewrite(index) as b: + b.data = b.data.replace( + 'doc/latest/index.html#format-string-syntax', 'syntax.html') + # Build the docs. + html_dir = os.path.join(env.build_dir, 'html') + if os.path.exists(html_dir): + shutil.rmtree(html_dir) + include_dir = env.fmt_repo.dir + if LooseVersion(version) >= LooseVersion('3.0.0'): + include_dir = os.path.join(include_dir, 'fmt') + import build + build.build_docs(version, doc_dir=target_doc_dir, + include_dir=include_dir, work_dir=env.build_dir) + shutil.rmtree(os.path.join(html_dir, '.doctrees')) + # Create symlinks for older versions. + for link, target in {'index': 'contents', 'api': 'reference'}.items(): + link = os.path.join(html_dir, link) + '.html' + target += '.html' + if os.path.exists(os.path.join(html_dir, target)) and \ + not os.path.exists(link): + os.symlink(target, link) + # Copy docs to the website. + version_doc_dir = os.path.join(doc_repo.dir, version) + shutil.rmtree(version_doc_dir) + shutil.move(html_dir, version_doc_dir) + + +def release(args): + env = create_build_env() + fmt_repo = env.fmt_repo + + branch = args.get('') + if branch is None: + branch = 'master' + if not fmt_repo.update('-b', branch, fmt_repo_url): + clean_checkout(fmt_repo, branch) + + # Convert changelog from RST to GitHub-flavored Markdown and get the + # version. + changelog = 'ChangeLog.rst' + changelog_path = os.path.join(fmt_repo.dir, changelog) + import rst2md + changes, version = rst2md.convert(changelog_path) + cmakelists = 'CMakeLists.txt' + for line in fileinput.input(os.path.join(fmt_repo.dir, cmakelists), + inplace=True): + prefix = 'set(FMT_VERSION ' + if line.startswith(prefix): + line = prefix + version + ')\n' + sys.stdout.write(line) + + # Update the version in the changelog. + title_len = 0 + for line in fileinput.input(changelog_path, inplace=True): + if line.decode('utf-8').startswith(version + ' - TBD'): + line = version + ' - ' + datetime.date.today().isoformat() + title_len = len(line) + line += '\n' + elif title_len: + line = '-' * title_len + '\n' + title_len = 0 + sys.stdout.write(line) + # TODO: add new version to manage.py + fmt_repo.checkout('-B', 'release') + fmt_repo.add(changelog, cmakelists) + fmt_repo.commit('-m', 'Update version') + + # Build the docs and package. + run = Runner(fmt_repo.dir) + run('cmake', '.') + run('make', 'doc', 'package_source') + + update_site(env) + + # Create a release on GitHub. + fmt_repo.push('origin', 'release') + r = requests.post('https://api.github.com/repos/fmtlib/fmt/releases', + params={'access_token': os.getenv('FMT_TOKEN')}, + data=json.dumps({'tag_name': version, + 'target_commitish': 'release', + 'body': changes, 'draft': True})) + if r.status_code != 201: + raise Exception('Failed to create a release ' + str(r)) + + +if __name__ == '__main__': + args = docopt.docopt(__doc__) + if args.get('release'): + release(args) + elif args.get('site'): + update_site(create_build_env()) diff --git a/libs/format/support/rst2md.py b/libs/format/support/rst2md.py new file mode 100644 index 000000000..00ee93d9c --- /dev/null +++ b/libs/format/support/rst2md.py @@ -0,0 +1,127 @@ +# reStructuredText (RST) to GitHub-flavored Markdown converter + +import re +from docutils import core, nodes, writers + + +def is_github_ref(node): + return re.match('https://github.com/.*/(issues|pull)/.*', node['refuri']) + + +class Translator(nodes.NodeVisitor): + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.output = '' + self.indent = 0 + self.preserve_newlines = False + + def write(self, text): + self.output += text.replace('\n', '\n' + ' ' * self.indent) + + def visit_document(self, node): + pass + + def depart_document(self, node): + pass + + def visit_section(self, node): + pass + + def depart_section(self, node): + # Skip all sections except the first one. + raise nodes.StopTraversal + + def visit_title(self, node): + self.version = re.match(r'(\d+\.\d+\.\d+).*', node.children[0]).group(1) + raise nodes.SkipChildren + + def depart_title(self, node): + pass + + def visit_Text(self, node): + if not self.preserve_newlines: + node = node.replace('\n', ' ') + self.write(node) + + def depart_Text(self, node): + pass + + def visit_bullet_list(self, node): + pass + + def depart_bullet_list(self, node): + pass + + def visit_list_item(self, node): + self.write('* ') + self.indent += 2 + + def depart_list_item(self, node): + self.indent -= 2 + self.write('\n\n') + + def visit_paragraph(self, node): + pass + + def depart_paragraph(self, node): + pass + + def visit_reference(self, node): + if not is_github_ref(node): + self.write('[') + + def depart_reference(self, node): + if not is_github_ref(node): + self.write('](' + node['refuri'] + ')') + + def visit_target(self, node): + pass + + def depart_target(self, node): + pass + + def visit_literal(self, node): + self.write('`') + + def depart_literal(self, node): + self.write('`') + + def visit_literal_block(self, node): + self.write('\n\n```') + if 'c++' in node['classes']: + self.write('c++') + self.write('\n') + self.preserve_newlines = True + + def depart_literal_block(self, node): + self.write('\n```\n') + self.preserve_newlines = False + + def visit_inline(self, node): + pass + + def depart_inline(self, node): + pass + + def visit_image(self, node): + self.write('![](' + node['uri'] + ')') + + def depart_image(self, node): + pass + + +class MDWriter(writers.Writer): + """GitHub-flavored markdown writer""" + + supported = ('md',) + """Formats this writer supports.""" + + def translate(self): + translator = Translator(self.document) + self.document.walkabout(translator) + self.output = (translator.output, translator.version) + + +def convert(rst_path): + """Converts RST file to Markdown.""" + return core.publish_file(source_path=rst_path, writer=MDWriter()) diff --git a/libs/format/support/travis-build.py b/libs/format/support/travis-build.py index 6dc096669..910177920 100644 --- a/libs/format/support/travis-build.py +++ b/libs/format/support/travis-build.py @@ -6,34 +6,28 @@ import errno, os, re, shutil, sys, tempfile, urllib from subprocess import call, check_call, check_output, Popen, PIPE, STDOUT def rmtree_if_exists(dir): - try: - shutil.rmtree(dir) - except OSError as e: - if e.errno == errno.ENOENT: - pass + try: + shutil.rmtree(dir) + except OSError as e: + if e.errno == errno.ENOENT: + pass def makedirs_if_not_exist(dir): - try: - os.makedirs(dir) - except OSError as e: - if e.errno != errno.EEXIST: - raise + try: + os.makedirs(dir) + except OSError as e: + if e.errno != errno.EEXIST: + raise -fmt_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - -build = os.environ['BUILD'] -if build == 'Doc': - travis = 'TRAVIS' in os.environ - # Install dependencies. - if travis: +def install_dependencies(): branch = os.environ['TRAVIS_BRANCH'] if branch != 'master': - print('Branch: ' + branch) - exit(0) # Ignore non-master branches - check_call('curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | ' + - 'sudo apt-key add -', shell=True) - check_call('echo "deb https://deb.nodesource.com/node_0.10 precise main" | ' + - 'sudo tee /etc/apt/sources.list.d/nodesource.list', shell=True) + print('Branch: ' + branch) + exit(0) # Ignore non-master branches + check_call('curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key ' + + '| sudo apt-key add -', shell=True) + check_call('echo "deb https://deb.nodesource.com/node_0.10 precise main" ' + + '| sudo tee /etc/apt/sources.list.d/nodesource.list', shell=True) check_call(['sudo', 'apt-get', 'update']) check_call(['sudo', 'apt-get', 'install', 'python-virtualenv', 'nodejs']) check_call(['npm', 'install', '-g', 'less', 'less-plugin-clean-css']) @@ -41,39 +35,48 @@ if build == 'Doc': urllib.urlretrieve('http://mirrors.kernel.org/ubuntu/pool/main/d/doxygen/' + deb_file, deb_file) check_call(['sudo', 'dpkg', '-i', deb_file]) - sys.path.insert(0, os.path.join(fmt_dir, 'doc')) - import build - html_dir = build.build_docs() - repo = 'fmtlib.github.io' - if travis and 'KEY' not in os.environ: - # Don't update the repo if building on Travis from an account that doesn't - # have push access. - print('Skipping update of ' + repo) - exit(0) - # Clone the fmtlib.github.io repo. - rmtree_if_exists(repo) - git_url = 'https://github.com/' if travis else 'git@github.com:' - check_call(['git', 'clone', git_url + 'fmtlib/{}.git'.format(repo)]) - # Copy docs to the repo. - target_dir = os.path.join(repo, 'dev') - rmtree_if_exists(target_dir) - shutil.copytree(html_dir, target_dir, ignore=shutil.ignore_patterns('.*')) - if travis: - check_call(['git', 'config', '--global', 'user.name', 'amplbot']) - check_call(['git', 'config', '--global', 'user.email', 'viz@ampl.com']) - # Push docs to GitHub pages. - check_call(['git', 'add', '--all'], cwd=repo) - if call(['git', 'diff-index', '--quiet', 'HEAD'], cwd=repo): - check_call(['git', 'commit', '-m', 'Update documentation'], cwd=repo) - cmd = 'git push' + +fmt_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + +build = os.environ['BUILD'] +if build == 'Doc': + travis = 'TRAVIS' in os.environ if travis: - cmd += ' https://$KEY@github.com/fmtlib/fmtlib.github.io.git master' - p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=repo) - # Print the output without the key. - print(p.communicate()[0].replace(os.environ['KEY'], '$KEY')) - if p.returncode != 0: - raise CalledProcessError(p.returncode, cmd) - exit(0) + install_dependencies() + sys.path.insert(0, os.path.join(fmt_dir, 'doc')) + import build + build.create_build_env() + html_dir = build.build_docs() + repo = 'fmtlib.github.io' + if travis and 'KEY' not in os.environ: + # Don't update the repo if building on Travis from an account that + # doesn't have push access. + print('Skipping update of ' + repo) + exit(0) + # Clone the fmtlib.github.io repo. + rmtree_if_exists(repo) + git_url = 'https://github.com/' if travis else 'git@github.com:' + check_call(['git', 'clone', git_url + 'fmtlib/{}.git'.format(repo)]) + # Copy docs to the repo. + target_dir = os.path.join(repo, 'dev') + rmtree_if_exists(target_dir) + shutil.copytree(html_dir, target_dir, ignore=shutil.ignore_patterns('.*')) + if travis: + check_call(['git', 'config', '--global', 'user.name', 'amplbot']) + check_call(['git', 'config', '--global', 'user.email', 'viz@ampl.com']) + # Push docs to GitHub pages. + check_call(['git', 'add', '--all'], cwd=repo) + if call(['git', 'diff-index', '--quiet', 'HEAD'], cwd=repo): + check_call(['git', 'commit', '-m', 'Update documentation'], cwd=repo) + cmd = 'git push' + if travis: + cmd += ' https://$KEY@github.com/fmtlib/fmtlib.github.io.git master' + p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=repo) + # Print the output without the key. + print(p.communicate()[0].replace(os.environ['KEY'], '$KEY')) + if p.returncode != 0: + raise CalledProcessError(p.returncode, cmd) + exit(0) standard = os.environ['STANDARD'] install_dir = os.path.join(fmt_dir, "_install") @@ -83,11 +86,13 @@ test_build_dir = os.path.join(fmt_dir, "_build_test") # Configure library. makedirs_if_not_exist(build_dir) common_cmake_flags = [ - '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build + '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build ] extra_cmake_flags = [] if standard != '0x': - extra_cmake_flags = ['-DCMAKE_CXX_FLAGS=-std=c++' + standard, '-DFMT_USE_CPP11=OFF'] + extra_cmake_flags = [ + '-DCMAKE_CXX_FLAGS=-std=c++' + standard, '-DFMT_USE_CPP11=OFF' + ] check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', fmt_dir] + common_cmake_flags + extra_cmake_flags, cwd=build_dir) @@ -98,9 +103,9 @@ check_call(['make', '-j4'], cwd=build_dir) env = os.environ.copy() env['CTEST_OUTPUT_ON_FAILURE'] = '1' if call(['make', 'test'], env=env, cwd=build_dir): - with open('Testing/Temporary/LastTest.log', 'r') as f: - print(f.read()) - sys.exit(-1) + with open('Testing/Temporary/LastTest.log', 'r') as f: + print(f.read()) + sys.exit(-1) # Install library. check_call(['make', 'install'], cwd=build_dir) diff --git a/libs/format/support/update-converity-branch.py b/libs/format/support/update-converity-branch.py index 36c0475ae..519f5d00d 100644 --- a/libs/format/support/update-converity-branch.py +++ b/libs/format/support/update-converity-branch.py @@ -8,23 +8,23 @@ import shutil, tempfile from subprocess import check_output, STDOUT class Git: - def __init__(self, dir): - self.dir = dir + def __init__(self, dir): + self.dir = dir - def __call__(self, *args): - output = check_output(['git'] + list(args), cwd=self.dir, stderr=STDOUT) - print(output) - return output + def __call__(self, *args): + output = check_output(['git'] + list(args), cwd=self.dir, stderr=STDOUT) + print(output) + return output dir = tempfile.mkdtemp() try: - git = Git(dir) - git('clone', '-b', 'coverity', 'git@github.com:fmtlib/fmt.git', dir) - output = git('merge', '-X', 'theirs', '--no-commit', 'origin/master') - if 'Fast-forward' not in output: - git('reset', 'HEAD', '.travis.yml') - git('checkout', '--', '.travis.yml') - git('commit', '-m', 'Update coverity branch') - git('push') + git = Git(dir) + git('clone', '-b', 'coverity', 'git@github.com:fmtlib/fmt.git', dir) + output = git('merge', '-X', 'theirs', '--no-commit', 'origin/master') + if 'Fast-forward' not in output: + git('reset', 'HEAD', '.travis.yml') + git('checkout', '--', '.travis.yml') + git('commit', '-m', 'Update coverity branch') + git('push') finally: - shutil.rmtree(dir) + shutil.rmtree(dir) diff --git a/libs/format/test/CMakeLists.txt b/libs/format/test/CMakeLists.txt index e4e868d54..31a418de7 100644 --- a/libs/format/test/CMakeLists.txt +++ b/libs/format/test/CMakeLists.txt @@ -56,11 +56,19 @@ if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wno-long-long -Wno-variadic-macros) endif () +function(add_fmt_executable name) + add_executable(${name} ${ARGN}) + if (MINGW) + target_link_libraries(${name} -static-libgcc -static-libstdc++) + endif () +endfunction() + # Adds a test. # Usage: add_fmt_test(name srcs...) function(add_fmt_test name) - add_executable(${name} ${name}.cc ${ARGN}) + add_fmt_executable(${name} ${name}.cc ${ARGN}) target_link_libraries(${name} test-main) + # define if certain c++ features can be used target_compile_definitions(${name} PRIVATE FMT_USE_TYPE_TRAITS=$ @@ -72,13 +80,17 @@ function(add_fmt_test name) endfunction() add_fmt_test(assert-test) +add_fmt_test(container-test) add_fmt_test(gtest-extra-test) add_fmt_test(format-test) add_fmt_test(format-impl-test) add_fmt_test(ostream-test) add_fmt_test(printf-test) +add_fmt_test(string-test) +add_fmt_test(time-test) add_fmt_test(util-test mock-allocator.h) add_fmt_test(macro-test) +add_fmt_test(custom-formatter-test) # Enable stricter options for one test to make sure that the header is free of # warnings. @@ -87,7 +99,8 @@ if (FMT_PEDANTIC AND MSVC) endif () if (HAVE_OPEN) - add_executable(posix-mock-test posix-mock-test.cc ../fmt/format.cc ${TEST_MAIN_SRC}) + add_fmt_executable(posix-mock-test + posix-mock-test.cc ../fmt/format.cc ../fmt/printf.cc ${TEST_MAIN_SRC}) target_include_directories(posix-mock-test PRIVATE ${PROJECT_SOURCE_DIR}) target_compile_definitions(posix-mock-test PRIVATE FMT_USE_FILE_DESCRIPTORS=1) target_link_libraries(posix-mock-test gmock) @@ -95,7 +108,7 @@ if (HAVE_OPEN) add_fmt_test(posix-test) endif () -add_executable(header-only-test +add_fmt_executable(header-only-test header-only-test.cc header-only-test2.cc test-main.cc) target_link_libraries(header-only-test gmock) if (TARGET fmt-header-only) @@ -109,6 +122,7 @@ endif () check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG) if (HAVE_FNO_EXCEPTIONS_FLAG) add_library(noexception-test ../fmt/format.cc) + target_include_directories(noexception-test PRIVATE ${PROJECT_SOURCE_DIR}) target_compile_options(noexception-test PRIVATE -fno-exceptions) endif () @@ -116,6 +130,7 @@ if (FMT_PEDANTIC) # Test that the library compiles without windows.h. if (CMAKE_SYSTEM_NAME STREQUAL "Windows") add_library(no-windows-h-test ../fmt/format.cc) + target_include_directories(no-windows-h-test PRIVATE ${PROJECT_SOURCE_DIR}) target_compile_definitions(no-windows-h-test PRIVATE FMT_USE_WINDOWS_H=0) endif () @@ -125,7 +140,7 @@ if (FMT_PEDANTIC) "${CMAKE_CURRENT_BINARY_DIR}/compile-test" --build-generator ${CMAKE_GENERATOR} --build-makeprogram ${CMAKE_MAKE_PROGRAM} - --build-options + --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCPP11_FLAG=${CPP11_FLAG}" "-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}") diff --git a/libs/format/test/add-subdirectory-test/CMakeLists.txt b/libs/format/test/add-subdirectory-test/CMakeLists.txt index 5460363a8..d1edd8a52 100644 --- a/libs/format/test/add-subdirectory-test/CMakeLists.txt +++ b/libs/format/test/add-subdirectory-test/CMakeLists.txt @@ -5,9 +5,9 @@ project(fmt-test) add_subdirectory(../.. fmt) add_executable(library-test "main.cc") -target_link_libraries(library-test fmt) +target_link_libraries(library-test fmt::fmt) -if (TARGET fmt-header-only) +if (TARGET fmt::fmt-header-only) add_executable(header-only-test "main.cc") - target_link_libraries(header-only-test fmt-header-only) + target_link_libraries(header-only-test fmt::fmt-header-only) endif () diff --git a/libs/format/test/container-test.cc b/libs/format/test/container-test.cc new file mode 100644 index 000000000..8cafb3d02 --- /dev/null +++ b/libs/format/test/container-test.cc @@ -0,0 +1,94 @@ +/* + Tests of container utilities + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#include "fmt/container.h" +#include "gtest/gtest.h" + +using fmt::internal::ContainerBuffer; + +TEST(ContainerBufferTest, Empty) { + std::string data; + ContainerBuffer buffer(data); + EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(0u, buffer.capacity()); +} + +TEST(ContainerBufferTest, Reserve) { + std::string data; + ContainerBuffer buffer(data); + std::size_t capacity = std::string().capacity() + 10; + buffer.reserve(capacity); + EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(capacity, buffer.capacity()); +} + +TEST(ContainerBufferTest, Resize) { + std::string data; + ContainerBuffer buffer(data); + std::size_t size = std::string().capacity() + 10; + buffer.resize(size); + EXPECT_EQ(size, buffer.size()); + EXPECT_EQ(size, buffer.capacity()); +} + +TEST(ContainerBufferTest, Append) { + std::string data("Why so"); + const std::string serious(" serious"); + ContainerBuffer buffer(data); + buffer.append(serious.c_str(), serious.c_str() + serious.length()); + EXPECT_EQ("Why so serious", data); + EXPECT_EQ(data.length(), buffer.size()); +} + +TEST(BasicContainerWriterTest, String) { + std::string data; + fmt::BasicContainerWriter out(data); + out << "The answer is " << 42 << "\n"; + EXPECT_EQ("The answer is 42\n", data); + EXPECT_EQ(17u, out.size()); +} + +TEST(BasicContainerWriterTest, WString) { + std::wstring data; + fmt::BasicContainerWriter out(data); + out << "The answer is " << 42 << "\n"; + EXPECT_EQ(L"The answer is 42\n", data); + EXPECT_EQ(17u, out.size()); +} + +TEST(BasicContainerWriterTest, Vector) { + std::vector data; + fmt::BasicContainerWriter > out(data); + out << "The answer is " << 42 << "\n"; + EXPECT_EQ(17u, data.size()); + EXPECT_EQ(out.size(), data.size()); +} + +TEST(BasicContainerWriterTest, StringAppend) { + std::string data("The"); + fmt::BasicContainerWriter out(data); + EXPECT_EQ(3u, data.size()); + EXPECT_EQ(3u, out.size()); + out << " answer is " << 42 << "\n"; + EXPECT_EQ("The answer is 42\n", data); + EXPECT_EQ(17u, out.size()); +} + +TEST(BasicContainerWriterTest, VectorAppend) { + std::vector data; + data.push_back('T'); + data.push_back('h'); + data.push_back('e'); + fmt::BasicContainerWriter > out(data); + EXPECT_EQ(3u, data.size()); + EXPECT_EQ(3u, out.size()); + out << " answer is " << 42 << "\n"; + EXPECT_EQ(17u, data.size()); + EXPECT_EQ(17u, out.size()); +} diff --git a/libs/format/test/custom-formatter-test.cc b/libs/format/test/custom-formatter-test.cc new file mode 100644 index 000000000..cc9c44854 --- /dev/null +++ b/libs/format/test/custom-formatter-test.cc @@ -0,0 +1,68 @@ +/* + Custom argument formatter tests + + Copyright (c) 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#include "fmt/printf.h" +#include "gtest-extra.h" + +using fmt::BasicPrintfArgFormatter; + +// A custom argument formatter that doesn't print `-` for floating-point values +// rounded to 0. +class CustomArgFormatter + : public fmt::BasicArgFormatter { + public: + CustomArgFormatter(fmt::BasicFormatter &f, + fmt::FormatSpec &s, const char *fmt) + : fmt::BasicArgFormatter(f, s, fmt) {} + + void visit_double(double value) { + if (round(value * pow(10, spec().precision())) == 0) + value = 0; + fmt::BasicArgFormatter::visit_double(value); + } +}; + +// A custom argument formatter that doesn't print `-` for floating-point values +// rounded to 0. +class CustomPrintfArgFormatter : + public BasicPrintfArgFormatter { + public: + typedef BasicPrintfArgFormatter Base; + + CustomPrintfArgFormatter(fmt::BasicWriter &w, fmt::FormatSpec &spec) + : Base(w, spec) {} + + void visit_double(double value) { + if (round(value * pow(10, spec().precision())) == 0) + value = 0; + Base::visit_double(value); + } +}; + +std::string custom_format(const char *format_str, fmt::ArgList args) { + fmt::MemoryWriter writer; + // Pass custom argument formatter as a template arg to BasicFormatter. + fmt::BasicFormatter formatter(args, writer); + formatter.format(format_str); + return writer.str(); +} +FMT_VARIADIC(std::string, custom_format, const char *) + +std::string custom_sprintf(const char* format_str, fmt::ArgList args){ + fmt::MemoryWriter writer; + fmt::PrintfFormatter formatter(args, writer); + formatter.format(format_str); + return writer.str(); +} +FMT_VARIADIC(std::string, custom_sprintf, const char*); + +TEST(CustomFormatterTest, Format) { + EXPECT_EQ("0.00", custom_format("{:.2f}", -.00001)); + EXPECT_EQ("0.00", custom_sprintf("%.2f", -.00001)); +} diff --git a/libs/format/test/find-package-test/CMakeLists.txt b/libs/format/test/find-package-test/CMakeLists.txt index 1f28c30c6..40c075609 100644 --- a/libs/format/test/find-package-test/CMakeLists.txt +++ b/libs/format/test/find-package-test/CMakeLists.txt @@ -5,9 +5,9 @@ project(fmt-test) find_package(FMT REQUIRED) add_executable(library-test main.cc) -target_link_libraries(library-test fmt) +target_link_libraries(library-test fmt::fmt) -if (TARGET fmt-header-only) +if (TARGET fmt::fmt-header-only) add_executable(header-only-test main.cc) - target_link_libraries(header-only-test fmt-header-only) + target_link_libraries(header-only-test fmt::fmt-header-only) endif () diff --git a/libs/format/test/format-impl-test.cc b/libs/format/test/format-impl-test.cc index aff9ea54a..1eb5e9165 100644 --- a/libs/format/test/format-impl-test.cc +++ b/libs/format/test/format-impl-test.cc @@ -26,10 +26,12 @@ */ #define FMT_NOEXCEPT +#undef FMT_SHARED #include "test-assert.h" -// Include format.cc instead of format.h to test implementation-specific stuff. +// Include *.cc instead of *.h to test implementation-specific stuff. #include "fmt/format.cc" +#include "fmt/printf.cc" #include #include @@ -46,7 +48,7 @@ TEST(FormatTest, ArgConverter) { Arg arg = Arg(); arg.type = Arg::LONG_LONG; arg.long_long_value = std::numeric_limits::max(); - fmt::ArgConverter(arg, 'd').visit(arg); + fmt::internal::ArgConverter(arg, 'd').visit(arg); EXPECT_EQ(Arg::LONG_LONG, arg.type); } diff --git a/libs/format/test/format-test.cc b/libs/format/test/format-test.cc index 52ff8a1e0..6388d5a5c 100644 --- a/libs/format/test/format-test.cc +++ b/libs/format/test/format-test.cc @@ -43,8 +43,23 @@ // Test that the library compiles if None is defined to 0 as done by xlib.h. #define None 0 +struct LocaleMock { + static LocaleMock *instance; + + MOCK_METHOD0(localeconv, lconv *()); +} *LocaleMock::instance; + +namespace fmt { +namespace std { +using namespace ::std; +lconv *localeconv() { + return LocaleMock::instance ? + LocaleMock::instance->localeconv() : ::std::localeconv(); +} +} +} + #include "fmt/format.h" -#include "fmt/time.h" #include "util.h" #include "mock-allocator.h" @@ -235,7 +250,7 @@ TEST(WriterTest, Allocator) { std::size_t size = static_cast(1.5 * fmt::internal::INLINE_BUFFER_SIZE); std::vector mem(size); - EXPECT_CALL(alloc, allocate(size)).WillOnce(testing::Return(&mem[0])); + EXPECT_CALL(alloc, allocate(size, 0)).WillOnce(testing::Return(&mem[0])); for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE + 1; ++i) w << '*'; EXPECT_CALL(alloc, deallocate(&mem[0], size)); @@ -917,7 +932,7 @@ TEST(FormatterTest, RuntimeWidth) { FormatError, "number is too big"); EXPECT_THROW_MSG(format("{0:{1}}", 0, -1l), FormatError, "negative width"); - if (fmt::internal::check(sizeof(long) > sizeof(int))) { + if (fmt::internal::const_check(sizeof(long) > sizeof(int))) { long value = INT_MAX; EXPECT_THROW_MSG(format("{0:{1}}", 0, (value + 1)), FormatError, "number is too big"); @@ -1036,7 +1051,7 @@ TEST(FormatterTest, RuntimePrecision) { FormatError, "number is too big"); EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1l), FormatError, "negative precision"); - if (fmt::internal::check(sizeof(long) > sizeof(int))) { + if (fmt::internal::const_check(sizeof(long) > sizeof(int))) { long value = INT_MAX; EXPECT_THROW_MSG(format("{0:.{1}}", 0, (value + 1)), FormatError, "number is too big"); @@ -1209,13 +1224,24 @@ TEST(FormatterTest, FormatOct) { } TEST(FormatterTest, FormatIntLocale) { -#ifndef _WIN32 - const char *locale = "en_US.utf-8"; -#else - const char *locale = "English_United States"; -#endif - std::setlocale(LC_ALL, locale); - EXPECT_EQ("1,234,567", format("{:n}", 1234567)); + ScopedMock mock; + lconv lc = lconv(); + char sep[] = "--"; + lc.thousands_sep = sep; + EXPECT_CALL(mock, localeconv()).Times(3).WillRepeatedly(testing::Return(&lc)); + EXPECT_EQ("123", format("{:n}", 123)); + EXPECT_EQ("1--234", format("{:n}", 1234)); + EXPECT_EQ("1--234--567", format("{:n}", 1234567)); +} + +struct ConvertibleToLongLong { + operator fmt::LongLong() const { + return fmt::LongLong(1) << 32; + } +}; + +TEST(FormatterTest, FormatConvertibleToLongLong) { + EXPECT_EQ("100000000", format("{:x}", ConvertibleToLongLong())); } TEST(FormatterTest, FormatFloat) { @@ -1327,6 +1353,8 @@ TEST(FormatterTest, FormatUCharString) { EXPECT_EQ("test", format("{0:s}", str)); const unsigned char *const_str = str; EXPECT_EQ("test", format("{0:s}", const_str)); + unsigned char *ptr = str; + EXPECT_EQ("test", format("{0:s}", ptr)); } TEST(FormatterTest, FormatPointer) { @@ -1350,7 +1378,7 @@ TEST(FormatterTest, FormatCStringRef) { EXPECT_EQ("test", format("{0}", CStringRef("test"))); } -void format(fmt::BasicFormatter &f, const char *, const Date &d) { +void format_arg(fmt::BasicFormatter &f, const char *, const Date &d) { f.writer() << d.year() << '-' << d.month() << '-' << d.day(); } @@ -1363,7 +1391,7 @@ TEST(FormatterTest, FormatCustom) { class Answer {}; template -void format(fmt::BasicFormatter &f, const Char *, Answer) { +void format_arg(fmt::BasicFormatter &f, const Char *, Answer) { f.writer() << "42"; } @@ -1534,13 +1562,25 @@ TEST(FormatTest, Variadic) { EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1)); } -TEST(FormatTest, Time) { - std::tm tm = std::tm(); - tm.tm_year = 116; - tm.tm_mon = 3; - tm.tm_mday = 25; - EXPECT_EQ("The date is 2016-04-25.", - fmt::format("The date is {:%Y-%m-%d}.", tm)); +TEST(FormatTest, JoinArg) { + using fmt::join; + int v1[3] = { 1, 2, 3 }; + std::vector v2; + v2.push_back(1.2f); + v2.push_back(3.4f); + + EXPECT_EQ("(1, 2, 3)", format("({})", join(v1 + 0, v1 + 3, ", "))); + EXPECT_EQ("(1)", format("({})", join(v1 + 0, v1 + 1, ", "))); + EXPECT_EQ("()", format("({})", join(v1 + 0, v1 + 0, ", "))); + EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1 + 0, v1 + 3, ", "))); + EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2.begin(), v2.end(), ", "))); + + EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1 + 0, v1 + 3, L", "))); + +#if FMT_HAS_GXX_CXX11 + EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", "))); + EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", "))); +#endif } template @@ -1644,3 +1684,10 @@ FMT_VARIADIC(void, custom_format, const char *) TEST(FormatTest, CustomArgFormatter) { custom_format("{}", 42); } + +void convert(int); + +// Check if there is no collision with convert function in the global namespace. +TEST(FormatTest, ConvertCollision) { + fmt::format("{}", 42); +} diff --git a/libs/format/test/gmock/gmock.h b/libs/format/test/gmock/gmock.h index 17bde1e7e..84f58cdd1 100644 --- a/libs/format/test/gmock/gmock.h +++ b/libs/format/test/gmock/gmock.h @@ -10090,8 +10090,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // threads concurrently. Result InvokeWith(const ArgumentTuple& args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { - return static_cast( - this->UntypedInvokeWith(&args))->GetValueAndDelete(); + const ResultHolder *rh = static_cast( + this->UntypedInvokeWith(&args)); + return rh ? rh->GetValueAndDelete() : Result(); } // Adds and returns a default action spec for this mock function. diff --git a/libs/format/test/gtest-extra-test.cc b/libs/format/test/gtest-extra-test.cc index 8f681c2cf..6a8c5676f 100644 --- a/libs/format/test/gtest-extra-test.cc +++ b/libs/format/test/gtest-extra-test.cc @@ -320,7 +320,7 @@ TEST(StreamingAssertionsTest, EXPECT_WRITE) { TEST(UtilTest, FormatSystemError) { fmt::MemoryWriter out; - fmt::internal::format_system_error(out, EDOM, "test message"); + fmt::format_system_error(out, EDOM, "test message"); EXPECT_EQ(out.str(), format_system_error(EDOM, "test message")); } diff --git a/libs/format/test/gtest-extra.cc b/libs/format/test/gtest-extra.cc index f7c296305..7640d1545 100644 --- a/libs/format/test/gtest-extra.cc +++ b/libs/format/test/gtest-extra.cc @@ -105,6 +105,6 @@ std::string read(File &f, std::size_t count) { std::string format_system_error(int error_code, fmt::StringRef message) { fmt::MemoryWriter out; - fmt::internal::format_system_error(out, error_code, message); + fmt::format_system_error(out, error_code, message); return out.str(); } diff --git a/libs/format/test/gtest-extra.h b/libs/format/test/gtest-extra.h index 649fbe275..5f7fe29d8 100644 --- a/libs/format/test/gtest-extra.h +++ b/libs/format/test/gtest-extra.h @@ -29,7 +29,7 @@ #define FMT_GTEST_EXTRA_H_ #include -#include +#include #include "fmt/format.h" @@ -172,4 +172,10 @@ std::string read(fmt::File &f, std::size_t count); #endif // FMT_USE_FILE_DESCRIPTORS +template +struct ScopedMock : testing::StrictMock { + ScopedMock() { Mock::instance = this; } + ~ScopedMock() { Mock::instance = 0; } +}; + #endif // FMT_GTEST_EXTRA_H_ diff --git a/libs/format/test/gtest/gtest.h b/libs/format/test/gtest/gtest.h index 4f3804f70..52d2ed6d0 100644 --- a/libs/format/test/gtest/gtest.h +++ b/libs/format/test/gtest/gtest.h @@ -2823,7 +2823,11 @@ inline int IsATTY(int /* fd */) { return 0; } inline int IsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { - return _stricmp(s1, s2); +# if _EMULATE_GLIBC + return strcasecmp(s1, s2); +# else + return _stricmp(s1, s2); +# endif } inline char* StrDup(const char* src) { return _strdup(src); } # endif // __BORLANDC__ diff --git a/libs/format/test/mock-allocator.h b/libs/format/test/mock-allocator.h index 7de1e1a09..34b9c11ab 100644 --- a/libs/format/test/mock-allocator.h +++ b/libs/format/test/mock-allocator.h @@ -36,8 +36,8 @@ class MockAllocator { MockAllocator() {} MockAllocator(const MockAllocator &) {} typedef T value_type; - MOCK_METHOD1_T(allocate, T* (std::size_t n)); - MOCK_METHOD2_T(deallocate, void (T* p, std::size_t n)); + MOCK_METHOD2_T(allocate, T *(std::size_t n, const T *h)); + MOCK_METHOD2_T(deallocate, void (T *p, std::size_t n)); }; template @@ -78,8 +78,10 @@ class AllocatorRef { Allocator *get() const { return alloc_; } - value_type* allocate(std::size_t n) { return alloc_->allocate(n); } - void deallocate(value_type* p, std::size_t n) { alloc_->deallocate(p, n); } + value_type *allocate(std::size_t n, const value_type *h) { + return alloc_->allocate(n, h); + } + void deallocate(value_type *p, std::size_t n) { alloc_->deallocate(p, n); } }; #endif // FMT_MOCK_ALLOCATOR_H_ diff --git a/libs/format/test/ostream-test.cc b/libs/format/test/ostream-test.cc index bbcce95e2..4081b43f8 100644 --- a/libs/format/test/ostream-test.cc +++ b/libs/format/test/ostream-test.cc @@ -25,7 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "fmt/ostream.cc" +#include "fmt/ostream.h" #include #include "gmock/gmock.h" @@ -35,13 +35,6 @@ using fmt::format; using fmt::FormatError; -template -std::basic_ostream &operator<<( - std::basic_ostream &os, const BasicTestString &s) { - os << s.value(); - return os; -} - std::ostream &operator<<(std::ostream &os, const Date &d) { os << d.year() << '-' << d.month() << '-' << d.day(); return os; @@ -128,22 +121,11 @@ TEST(OStreamTest, Print) { EXPECT_EQ("Don't panic!", os.str()); } -TEST(OStreamTest, PrintfCustom) { - EXPECT_EQ("abc", fmt::sprintf("%s", TestString("abc"))); -} - -TEST(OStreamTest, FPrintf) { - std::ostringstream os; - int ret = fmt::fprintf(os, "Don't %s!", "panic"); - EXPECT_EQ("Don't panic!", os.str()); - EXPECT_EQ(12, ret); -} - TEST(OStreamTest, WriteToOStream) { std::ostringstream os; fmt::MemoryWriter w; w << "foo"; - fmt::write(os, w); + fmt::internal::write(os, w); EXPECT_EQ("foo", os.str()); } @@ -188,5 +170,5 @@ TEST(OStreamTest, WriteToOStreamMaxSize) { data += n; size -= static_cast(n); } while (size != 0); - fmt::write(os, w); + fmt::internal::write(os, w); } diff --git a/libs/format/test/posix-mock-test.cc b/libs/format/test/posix-mock-test.cc index 2a89a8224..7a78327e3 100644 --- a/libs/format/test/posix-mock-test.cc +++ b/libs/format/test/posix-mock-test.cc @@ -453,12 +453,6 @@ TEST(BufferedFileTest, FilenoNoRetry) { fileno_count = 0; } -template -struct ScopedMock : testing::StrictMock { - ScopedMock() { Mock::instance = this; } - ~ScopedMock() { Mock::instance = 0; } -}; - struct TestMock { static TestMock *instance; } *TestMock::instance; @@ -508,7 +502,7 @@ LocaleType newlocale(int category_mask, const char *locale, LocaleType base) { return LocaleMock::instance->newlocale(category_mask, locale, base); } -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(__FreeBSD__) typedef int FreeLocaleResult; #else typedef void FreeLocaleResult; diff --git a/libs/format/test/posix-test.cc b/libs/format/test/posix-test.cc index 2dd3f046f..e6332bf03 100644 --- a/libs/format/test/posix-test.cc +++ b/libs/format/test/posix-test.cc @@ -232,7 +232,7 @@ TEST(FileTest, MoveAssignmentClosesFile) { File OpenBufferedFile(int &fd) { File f = open_file(); fd = f.descriptor(); - return std::move(f); + return f; } TEST(FileTest, MoveFromTemporaryInCtor) { diff --git a/libs/format/test/printf-test.cc b/libs/format/test/printf-test.cc index c38a1e52f..81a041d77 100644 --- a/libs/format/test/printf-test.cc +++ b/libs/format/test/printf-test.cc @@ -29,6 +29,7 @@ #include #include +#include "fmt/printf.h" #include "fmt/format.h" #include "gtest-extra.h" #include "util.h" @@ -201,6 +202,8 @@ TEST(PrintfTest, HashFlag) { TEST(PrintfTest, Width) { EXPECT_PRINTF(" abc", "%5s", "abc"); + EXPECT_PRINTF(" -42", "%5s", "-42"); + EXPECT_PRINTF(" 0.123456", "%10s", 0.123456); // Width cannot be specified twice. EXPECT_THROW_MSG(fmt::sprintf("%5-5d", 42), FormatError, @@ -295,12 +298,13 @@ void TestLength(const char *length_spec, U value) { fmt::LongLong signed_value = 0; fmt::ULongLong unsigned_value = 0; // Apply integer promotion to the argument. - fmt::ULongLong max = std::numeric_limits::max(); - using fmt::internal::check; - if (check(max <= static_cast(std::numeric_limits::max()))) { + using std::numeric_limits; + fmt::ULongLong max = numeric_limits::max(); + using fmt::internal::const_check; + if (const_check(max <= static_cast(numeric_limits::max()))) { signed_value = static_cast(value); unsigned_value = static_cast(value); - } else if (check(max <= std::numeric_limits::max())) { + } else if (const_check(max <= numeric_limits::max())) { signed_value = static_cast(value); unsigned_value = static_cast(value); } @@ -379,11 +383,13 @@ TEST(PrintfTest, Bool) { TEST(PrintfTest, Int) { EXPECT_PRINTF("-42", "%d", -42); EXPECT_PRINTF("-42", "%i", -42); + EXPECT_PRINTF("-42", "%s", -42); unsigned u = 0 - 42u; EXPECT_PRINTF(fmt::format("{}", u), "%u", -42); EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42); EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42); EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42); + EXPECT_PRINTF(fmt::format("{}", u), "%s", u); } TEST(PrintfTest, LongLong) { @@ -395,7 +401,11 @@ TEST(PrintfTest, LongLong) { TEST(PrintfTest, Float) { EXPECT_PRINTF("392.650000", "%f", 392.65); + EXPECT_PRINTF("392.65", "%.2f", 392.65); + EXPECT_PRINTF("392.6", "%.1f", 392.65); + EXPECT_PRINTF("393", "%.f", 392.65); EXPECT_PRINTF("392.650000", "%F", 392.65); + EXPECT_PRINTF("392.65", "%s", 392.65); char buffer[BUFFER_SIZE]; safe_sprintf(buffer, "%e", 392.65); EXPECT_PRINTF(buffer, "%e", 392.65); @@ -420,6 +430,7 @@ TEST(PrintfTest, Inf) { TEST(PrintfTest, Char) { EXPECT_PRINTF("x", "%c", 'x'); + EXPECT_PRINTF("x", "%s", 'x'); int max = std::numeric_limits::max(); EXPECT_PRINTF(fmt::format("{}", static_cast(max)), "%c", max); //EXPECT_PRINTF("x", "%lc", L'x'); @@ -438,13 +449,17 @@ TEST(PrintfTest, Pointer) { int n; void *p = &n; EXPECT_PRINTF(fmt::format("{}", p), "%p", p); + EXPECT_PRINTF(fmt::format("{}", p), "%s", p); p = 0; EXPECT_PRINTF("(nil)", "%p", p); EXPECT_PRINTF(" (nil)", "%10p", p); + EXPECT_PRINTF("(nil)", "%s", p); + EXPECT_PRINTF(" (nil)", "%10s", p); const char *s = "test"; EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); const char *null_str = 0; EXPECT_PRINTF("(nil)", "%p", null_str); + EXPECT_PRINTF("(null)", "%s", null_str); } TEST(PrintfTest, Location) { @@ -477,3 +492,20 @@ TEST(PrintfTest, PrintfError) { TEST(PrintfTest, WideString) { EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc")); } + +TEST(PrintfTest, PrintfCustom) { + EXPECT_EQ("abc", fmt::sprintf("%s", TestString("abc"))); +} + +TEST(PrintfTest, OStream) { + std::ostringstream os; + int ret = fmt::fprintf(os, "Don't %s!", "panic"); + EXPECT_EQ("Don't panic!", os.str()); + EXPECT_EQ(12, ret); +} + +TEST(PrintfTest, Writer) { + fmt::MemoryWriter writer; + printf(writer, "%d", 42); + EXPECT_EQ("42", writer.str()); +} diff --git a/libs/format/test/string-test.cc b/libs/format/test/string-test.cc new file mode 100644 index 000000000..10e537b7a --- /dev/null +++ b/libs/format/test/string-test.cc @@ -0,0 +1,80 @@ +/* + Tests of string utilities + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +#include "fmt/string.h" +#include "gtest/gtest.h" + +using fmt::internal::StringBuffer; + +TEST(StringBufferTest, Empty) { + StringBuffer buffer; + EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(0u, buffer.capacity()); + std::string data; + // std::string may have initial capacity. + std::size_t capacity = data.capacity(); + buffer.move_to(data); + EXPECT_EQ("", data); + EXPECT_EQ(capacity, data.capacity()); +} + +TEST(StringBufferTest, Reserve) { + StringBuffer buffer; + std::size_t capacity = std::string().capacity() + 10; + buffer.reserve(capacity); + EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(capacity, buffer.capacity()); + std::string data; + buffer.move_to(data); + EXPECT_EQ("", data); +} + +TEST(StringBufferTest, Resize) { + StringBuffer buffer; + std::size_t size = std::string().capacity() + 10; + buffer.resize(size); + EXPECT_EQ(size, buffer.size()); + EXPECT_EQ(size, buffer.capacity()); + std::string data; + buffer.move_to(data); + EXPECT_EQ(size, data.size()); +} + +TEST(StringBufferTest, MoveTo) { + StringBuffer buffer; + std::size_t size = std::string().capacity() + 10; + buffer.resize(size); + const char *p = &buffer[0]; + std::string data; + buffer.move_to(data); + EXPECT_EQ(p, &data[0]); + EXPECT_EQ(0u, buffer.size()); + EXPECT_EQ(0u, buffer.capacity()); +} + +TEST(StringWriterTest, MoveTo) { + fmt::StringWriter out; + out << "The answer is " << 42 << "\n"; + std::string s; + out.move_to(s); + EXPECT_EQ("The answer is 42\n", s); + EXPECT_EQ(0u, out.size()); +} + +TEST(StringWriterTest, WString) { + fmt::WStringWriter out; + out << "The answer is " << 42 << "\n"; + std::wstring s; + out.move_to(s); + EXPECT_EQ(L"The answer is 42\n", s); +} + +TEST(StringTest, ToString) { + EXPECT_EQ("42", fmt::to_string(42)); +} diff --git a/libs/format/test/time-test.cc b/libs/format/test/time-test.cc new file mode 100644 index 000000000..8b6c36128 --- /dev/null +++ b/libs/format/test/time-test.cc @@ -0,0 +1,60 @@ +/* + Time formatting tests + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ +#ifdef WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "gmock/gmock.h" +#include "fmt/time.h" + +TEST(TimeTest, Format) { + std::tm tm = std::tm(); + tm.tm_year = 116; + tm.tm_mon = 3; + tm.tm_mday = 25; + EXPECT_EQ("The date is 2016-04-25.", + fmt::format("The date is {:%Y-%m-%d}.", tm)); +} + +TEST(TimeTest, GrowBuffer) { + std::string s = "{:"; + for (int i = 0; i < 30; ++i) + s += "%c"; + s += "}\n"; + std::time_t t = std::time(0); + fmt::format(s, *std::localtime(&t)); +} + +TEST(TimeTest, EmptyResult) { + EXPECT_EQ("", fmt::format("{}", std::tm())); +} + +bool EqualTime(const std::tm &lhs, const std::tm &rhs) { + return lhs.tm_sec == rhs.tm_sec && + lhs.tm_min == rhs.tm_min && + lhs.tm_hour == rhs.tm_hour && + lhs.tm_mday == rhs.tm_mday && + lhs.tm_mon == rhs.tm_mon && + lhs.tm_year == rhs.tm_year && + lhs.tm_wday == rhs.tm_wday && + lhs.tm_yday == rhs.tm_yday && + lhs.tm_isdst == rhs.tm_isdst; +} + +TEST(TimeTest, LocalTime) { + std::time_t t = std::time(0); + std::tm tm = *std::localtime(&t); + EXPECT_TRUE(EqualTime(tm, fmt::localtime(t))); +} + +TEST(TimeTest, GMTime) { + std::time_t t = std::time(0); + std::tm tm = *std::gmtime(&t); + EXPECT_TRUE(EqualTime(tm, fmt::gmtime(t))); +} diff --git a/libs/format/test/util-test.cc b/libs/format/test/util-test.cc index 2134d0951..a38825580 100644 --- a/libs/format/test/util-test.cc +++ b/libs/format/test/util-test.cc @@ -64,7 +64,7 @@ namespace { struct Test {}; template -void format(fmt::BasicFormatter &f, const Char *, Test) { +void format_arg(fmt::BasicFormatter &f, const Char *, Test) { f.writer() << "test"; } @@ -83,8 +83,8 @@ void CheckForwarding( // Check if value_type is properly defined. AllocatorRef< MockAllocator >::value_type *ptr = &mem; // Check forwarding. - EXPECT_CALL(alloc, allocate(42)).WillOnce(Return(ptr)); - ref.allocate(42); + EXPECT_CALL(alloc, allocate(42, 0)).WillOnce(Return(ptr)); + ref.allocate(42, 0); EXPECT_CALL(alloc, deallocate(ptr, 42)); ref.deallocate(ptr, 42); } @@ -339,7 +339,7 @@ TEST(MemoryBufferTest, Grow) { EXPECT_EQ(10u, buffer.capacity()); int mem[20]; mem[7] = 0xdead; - EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem)); + EXPECT_CALL(alloc, allocate(20, 0)).WillOnce(Return(mem)); buffer.grow(20); EXPECT_EQ(20u, buffer.capacity()); // Check if size elements have been copied @@ -360,7 +360,7 @@ TEST(MemoryBufferTest, Allocator) { MemoryBuffer buffer2((TestAllocator(&alloc))); EXPECT_EQ(&alloc, buffer2.get_allocator().get()); std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE; - EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem)); + EXPECT_CALL(alloc, allocate(size, 0)).WillOnce(Return(&mem)); buffer2.reserve(size); EXPECT_CALL(alloc, deallocate(&mem, size)); } @@ -373,13 +373,13 @@ TEST(MemoryBufferTest, ExceptionInDeallocate) { std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE; std::vector mem(size); { - EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem[0])); + EXPECT_CALL(alloc, allocate(size, 0)).WillOnce(Return(&mem[0])); buffer.resize(size); std::fill(&buffer[0], &buffer[0] + size, 'x'); } std::vector mem2(2 * size); { - EXPECT_CALL(alloc, allocate(2 * size)).WillOnce(Return(&mem2[0])); + EXPECT_CALL(alloc, allocate(2 * size, 0)).WillOnce(Return(&mem2[0])); std::exception e; EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e)); EXPECT_THROW(buffer.reserve(2 * size), std::exception); @@ -581,7 +581,7 @@ struct CustomFormatter { typedef char Char; }; -void format(CustomFormatter &, const char *&s, const Test &) { +void format_arg(CustomFormatter &, const char *&s, const Test &) { s = "custom_format"; } @@ -708,7 +708,7 @@ TEST(ArgVisitorTest, VisitUnhandledArg) { TEST(ArgVisitorTest, VisitInvalidArg) { Arg arg = Arg(); - arg.type = static_cast(Arg::CUSTOM + 1); + arg.type = static_cast(Arg::NONE); EXPECT_ASSERT(TestVisitor().visit(arg), "invalid argument type"); } @@ -834,10 +834,10 @@ void check_throw_error(int error_code, FormatErrorMessage format) { TEST(UtilTest, FormatSystemError) { fmt::MemoryWriter message; - fmt::internal::format_system_error(message, EDOM, "test"); + fmt::format_system_error(message, EDOM, "test"); EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), message.str()); message.clear(); - fmt::internal::format_system_error( + fmt::format_system_error( message, EDOM, fmt::StringRef(0, std::numeric_limits::max())); EXPECT_EQ(fmt::format("error {}", EDOM), message.str()); } @@ -846,12 +846,12 @@ TEST(UtilTest, SystemError) { fmt::SystemError e(EDOM, "test"); EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), e.what()); EXPECT_EQ(EDOM, e.error_code()); - check_throw_error(EDOM, fmt::internal::format_system_error); + check_throw_error(EDOM, fmt::format_system_error); } TEST(UtilTest, ReportSystemError) { fmt::MemoryWriter out; - fmt::internal::format_system_error(out, EDOM, "test error"); + fmt::format_system_error(out, EDOM, "test error"); out << '\n'; EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), out.str()); } @@ -956,3 +956,17 @@ TEST(UtilTest, Conditional) { fmt::internal::Conditional::type *pc = &c; (void)pc; } + +struct TestLConv { + char *thousands_sep; +}; + +struct EmptyLConv {}; + +TEST(UtilTest, ThousandsSep) { + char foo[] = "foo"; + TestLConv lc = {foo}; + EXPECT_EQ("foo", fmt::internal::thousands_sep(&lc).to_string()); + EmptyLConv empty_lc; + EXPECT_EQ("", fmt::internal::thousands_sep(&empty_lc)); +} diff --git a/libs/format/test/util.h b/libs/format/test/util.h index 21d76b2d2..b7faf62ae 100644 --- a/libs/format/test/util.h +++ b/libs/format/test/util.h @@ -87,6 +87,13 @@ const Char BasicTestString::EMPTY[] = {0}; typedef BasicTestString TestString; typedef BasicTestString TestWString; +template +std::basic_ostream &operator<<( + std::basic_ostream &os, const BasicTestString &s) { + os << s.value(); + return os; +} + class Date { int year_, month_, day_; public: diff --git a/libs/recast/CMakeLists.txt b/libs/recast/CMakeLists.txt new file mode 100644 index 000000000..7f91efb38 --- /dev/null +++ b/libs/recast/CMakeLists.txt @@ -0,0 +1,77 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +SET(recast_navigation_sources + detour/src/DetourAlloc.cpp + detour/src/DetourAssert.cpp + detour/src/DetourCommon.cpp + detour/src/DetourNavMesh.cpp + detour/src/DetourNavMeshBuilder.cpp + detour/src/DetourNavMeshQuery.cpp + detour/src/DetourNode.cpp + recast/src/Recast.cpp + recast/src/RecastAlloc.cpp + recast/src/RecastArea.cpp + recast/src/RecastAssert.cpp + recast/src/RecastContour.cpp + recast/src/RecastFilter.cpp + recast/src/RecastLayers.cpp + recast/src/RecastMesh.cpp + recast/src/RecastMeshDetail.cpp + recast/src/RecastRasterization.cpp + recast/src/RecastRegion.cpp +) + +SET(recast_navigation_headers + detour/include/DetourAlloc.h + detour/include/DetourAssert.h + detour/include/DetourCommon.h + detour/include/DetourMath.h + detour/include/DetourNavMesh.h + detour/include/DetourNavMeshBuilder.h + detour/include/DetourNavMeshQuery.h + detour/include/DetourNode.h + detour/include/DetourStatus.h + recast/include/Recast.h + recast/include/RecastAlloc.h + recast/include/RecastAssert.h +) + +SOURCE_GROUP(Detour FILES + detour/src/DetourAlloc.cpp + detour/src/DetourAssert.cpp + detour/src/DetourCommon.cpp + detour/src/DetourNavMesh.cpp + detour/src/DetourNavMeshBuilder.cpp + detour/src/DetourNavMeshQuery.cpp + detour/src/DetourNode.cpp + detour/include/DetourAlloc.h + detour/include/DetourAssert.h + detour/include/DetourCommon.h + detour/include/DetourMath.h + detour/include/DetourNavMesh.h + detour/include/DetourNavMeshBuilder.h + detour/include/DetourNavMeshQuery.h + detour/include/DetourNode.h + detour/include/DetourStatus.h +) + +SOURCE_GROUP(Recast FILES + recast/src/Recast.cpp + recast/src/RecastAlloc.cpp + recast/src/RecastArea.cpp + recast/src/RecastAssert.cpp + recast/src/RecastContour.cpp + recast/src/RecastFilter.cpp + recast/src/RecastLayers.cpp + recast/src/RecastMesh.cpp + recast/src/RecastMeshDetail.cpp + recast/src/RecastRasterization.cpp + recast/src/RecastRegion.cpp + recast/include/Recast.h + recast/include/RecastAlloc.h + recast/include/RecastAssert.h +) + +ADD_LIBRARY(recast_navigation ${recast_navigation_sources} ${recast_navigation_headers}) + +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) \ No newline at end of file diff --git a/libs/recast/debug_utils/include/DebugDraw.h b/libs/recast/debug_utils/include/DebugDraw.h new file mode 100644 index 000000000..00b544d1c --- /dev/null +++ b/libs/recast/debug_utils/include/DebugDraw.h @@ -0,0 +1,223 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DEBUGDRAW_H +#define DEBUGDRAW_H + +// Some math headers don't have PI defined. +static const float DU_PI = 3.14159265f; + +enum duDebugDrawPrimitives +{ + DU_DRAW_POINTS, + DU_DRAW_LINES, + DU_DRAW_TRIS, + DU_DRAW_QUADS, +}; + +/// Abstract debug draw interface. +struct duDebugDraw +{ + virtual ~duDebugDraw() = 0; + + virtual void depthMask(bool state) = 0; + + virtual void texture(bool state) = 0; + + /// Begin drawing primitives. + /// @param prim [in] primitive type to draw, one of rcDebugDrawPrimitives. + /// @param size [in] size of a primitive, applies to point size and line width only. + virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f) = 0; + + /// Submit a vertex + /// @param pos [in] position of the verts. + /// @param color [in] color of the verts. + virtual void vertex(const float* pos, unsigned int color) = 0; + + /// Submit a vertex + /// @param x,y,z [in] position of the verts. + /// @param color [in] color of the verts. + virtual void vertex(const float x, const float y, const float z, unsigned int color) = 0; + + /// Submit a vertex + /// @param pos [in] position of the verts. + /// @param color [in] color of the verts. + virtual void vertex(const float* pos, unsigned int color, const float* uv) = 0; + + /// Submit a vertex + /// @param x,y,z [in] position of the verts. + /// @param color [in] color of the verts. + virtual void vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v) = 0; + + /// End drawing primitives. + virtual void end() = 0; + + /// Compute a color for given area. + virtual unsigned int areaToCol(unsigned int area); +}; + +inline unsigned int duRGBA(int r, int g, int b, int a) +{ + return ((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24); +} + +inline unsigned int duRGBAf(float fr, float fg, float fb, float fa) +{ + unsigned char r = (unsigned char)(fr*255.0f); + unsigned char g = (unsigned char)(fg*255.0f); + unsigned char b = (unsigned char)(fb*255.0f); + unsigned char a = (unsigned char)(fa*255.0f); + return duRGBA(r,g,b,a); +} + +unsigned int duIntToCol(int i, int a); +void duIntToCol(int i, float* col); + +inline unsigned int duMultCol(const unsigned int col, const unsigned int d) +{ + const unsigned int r = col & 0xff; + const unsigned int g = (col >> 8) & 0xff; + const unsigned int b = (col >> 16) & 0xff; + const unsigned int a = (col >> 24) & 0xff; + return duRGBA((r*d) >> 8, (g*d) >> 8, (b*d) >> 8, a); +} + +inline unsigned int duDarkenCol(unsigned int col) +{ + return ((col >> 1) & 0x007f7f7f) | (col & 0xff000000); +} + +inline unsigned int duLerpCol(unsigned int ca, unsigned int cb, unsigned int u) +{ + const unsigned int ra = ca & 0xff; + const unsigned int ga = (ca >> 8) & 0xff; + const unsigned int ba = (ca >> 16) & 0xff; + const unsigned int aa = (ca >> 24) & 0xff; + const unsigned int rb = cb & 0xff; + const unsigned int gb = (cb >> 8) & 0xff; + const unsigned int bb = (cb >> 16) & 0xff; + const unsigned int ab = (cb >> 24) & 0xff; + + unsigned int r = (ra*(255-u) + rb*u)/255; + unsigned int g = (ga*(255-u) + gb*u)/255; + unsigned int b = (ba*(255-u) + bb*u)/255; + unsigned int a = (aa*(255-u) + ab*u)/255; + return duRGBA(r,g,b,a); +} + +inline unsigned int duTransCol(unsigned int c, unsigned int a) +{ + return (a<<24) | (c & 0x00ffffff); +} + + +void duCalcBoxColors(unsigned int* colors, unsigned int colTop, unsigned int colSide); + +void duDebugDrawCylinderWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col, const float lineWidth); + +void duDebugDrawBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col, const float lineWidth); + +void duDebugDrawArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, const float h, + const float as0, const float as1, unsigned int col, const float lineWidth); + +void duDebugDrawArrow(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, + const float as0, const float as1, unsigned int col, const float lineWidth); + +void duDebugDrawCircle(struct duDebugDraw* dd, const float x, const float y, const float z, + const float r, unsigned int col, const float lineWidth); + +void duDebugDrawCross(struct duDebugDraw* dd, const float x, const float y, const float z, + const float size, unsigned int col, const float lineWidth); + +void duDebugDrawBox(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, const unsigned int* fcol); + +void duDebugDrawCylinder(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col); + +void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz, + const int w, const int h, const float size, + const unsigned int col, const float lineWidth); + + +// Versions without begin/end, can be used to draw multiple primitives. +void duAppendCylinderWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col); + +void duAppendBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col); + +void duAppendBoxPoints(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col); + +void duAppendArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, const float h, + const float as0, const float as1, unsigned int col); + +void duAppendArrow(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, + const float as0, const float as1, unsigned int col); + +void duAppendCircle(struct duDebugDraw* dd, const float x, const float y, const float z, + const float r, unsigned int col); + +void duAppendCross(struct duDebugDraw* dd, const float x, const float y, const float z, + const float size, unsigned int col); + +void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, const unsigned int* fcol); + +void duAppendCylinder(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col); + + +class duDisplayList : public duDebugDraw +{ + float* m_pos; + unsigned int* m_color; + int m_size; + int m_cap; + + bool m_depthMask; + duDebugDrawPrimitives m_prim; + float m_primSize; + + void resize(int cap); + +public: + duDisplayList(int cap = 512); + ~duDisplayList(); + virtual void depthMask(bool state); + virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f); + virtual void vertex(const float x, const float y, const float z, unsigned int color); + virtual void vertex(const float* pos, unsigned int color); + virtual void end(); + void clear(); + void draw(struct duDebugDraw* dd); +private: + // Explicitly disabled copy constructor and copy assignment operator. + duDisplayList(const duDisplayList&); + duDisplayList& operator=(const duDisplayList&); +}; + + +#endif // DEBUGDRAW_H diff --git a/libs/recast/debug_utils/include/DetourDebugDraw.h b/libs/recast/debug_utils/include/DetourDebugDraw.h new file mode 100644 index 000000000..ff2ca2f9d --- /dev/null +++ b/libs/recast/debug_utils/include/DetourDebugDraw.h @@ -0,0 +1,48 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURDEBUGDRAW_H +#define DETOURDEBUGDRAW_H + +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" +#include "DetourTileCacheBuilder.h" + +enum DrawNavMeshFlags +{ + DU_DRAWNAVMESH_OFFMESHCONS = 0x01, + DU_DRAWNAVMESH_CLOSEDLIST = 0x02, + DU_DRAWNAVMESH_COLOR_TILES = 0x04, +}; + +void duDebugDrawNavMesh(struct duDebugDraw* dd, const dtNavMesh& mesh, unsigned char flags); +void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, unsigned char flags); +void duDebugDrawNavMeshNodes(struct duDebugDraw* dd, const dtNavMeshQuery& query); +void duDebugDrawNavMeshBVTree(struct duDebugDraw* dd, const dtNavMesh& mesh); +void duDebugDrawNavMeshPortals(struct duDebugDraw* dd, const dtNavMesh& mesh); +void duDebugDrawNavMeshPolysWithFlags(struct duDebugDraw* dd, const dtNavMesh& mesh, const unsigned short polyFlags, const unsigned int col); +void duDebugDrawNavMeshPoly(struct duDebugDraw* dd, const dtNavMesh& mesh, dtPolyRef ref, const unsigned int col); + +void duDebugDrawTileCacheLayerAreas(struct duDebugDraw* dd, const dtTileCacheLayer& layer, const float cs, const float ch); +void duDebugDrawTileCacheLayerRegions(struct duDebugDraw* dd, const dtTileCacheLayer& layer, const float cs, const float ch); +void duDebugDrawTileCacheContours(duDebugDraw* dd, const struct dtTileCacheContourSet& lcset, + const float* orig, const float cs, const float ch); +void duDebugDrawTileCachePolyMesh(duDebugDraw* dd, const struct dtTileCachePolyMesh& lmesh, + const float* orig, const float cs, const float ch); + +#endif // DETOURDEBUGDRAW_H diff --git a/libs/recast/debug_utils/include/RecastDebugDraw.h b/libs/recast/debug_utils/include/RecastDebugDraw.h new file mode 100644 index 000000000..6a55fa647 --- /dev/null +++ b/libs/recast/debug_utils/include/RecastDebugDraw.h @@ -0,0 +1,42 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef RECAST_DEBUGDRAW_H +#define RECAST_DEBUGDRAW_H + +void duDebugDrawTriMesh(struct duDebugDraw* dd, const float* verts, int nverts, const int* tris, const float* normals, int ntris, const unsigned char* flags, const float texScale); +void duDebugDrawTriMeshSlope(struct duDebugDraw* dd, const float* verts, int nverts, const int* tris, const float* normals, int ntris, const float walkableSlopeAngle, const float texScale); + +void duDebugDrawHeightfieldSolid(struct duDebugDraw* dd, const struct rcHeightfield& hf); +void duDebugDrawHeightfieldWalkable(struct duDebugDraw* dd, const struct rcHeightfield& hf); + +void duDebugDrawCompactHeightfieldSolid(struct duDebugDraw* dd, const struct rcCompactHeightfield& chf); +void duDebugDrawCompactHeightfieldRegions(struct duDebugDraw* dd, const struct rcCompactHeightfield& chf); +void duDebugDrawCompactHeightfieldDistance(struct duDebugDraw* dd, const struct rcCompactHeightfield& chf); + +void duDebugDrawHeightfieldLayer(duDebugDraw* dd, const struct rcHeightfieldLayer& layer, const int idx); +void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset); +void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset); + +void duDebugDrawRegionConnections(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f); +void duDebugDrawRawContours(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f); +void duDebugDrawContours(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f); +void duDebugDrawPolyMesh(struct duDebugDraw* dd, const struct rcPolyMesh& mesh); +void duDebugDrawPolyMeshDetail(struct duDebugDraw* dd, const struct rcPolyMeshDetail& dmesh); + +#endif // RECAST_DEBUGDRAW_H diff --git a/libs/recast/debug_utils/include/RecastDump.h b/libs/recast/debug_utils/include/RecastDump.h new file mode 100644 index 000000000..6a722fdae --- /dev/null +++ b/libs/recast/debug_utils/include/RecastDump.h @@ -0,0 +1,43 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef RECAST_DUMP_H +#define RECAST_DUMP_H + +struct duFileIO +{ + virtual ~duFileIO() = 0; + virtual bool isWriting() const = 0; + virtual bool isReading() const = 0; + virtual bool write(const void* ptr, const size_t size) = 0; + virtual bool read(void* ptr, const size_t size) = 0; +}; + +bool duDumpPolyMeshToObj(struct rcPolyMesh& pmesh, duFileIO* io); +bool duDumpPolyMeshDetailToObj(struct rcPolyMeshDetail& dmesh, duFileIO* io); + +bool duDumpContourSet(struct rcContourSet& cset, duFileIO* io); +bool duReadContourSet(struct rcContourSet& cset, duFileIO* io); + +bool duDumpCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io); +bool duReadCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io); + +void duLogBuildTimes(rcContext& ctx, const int totalTileUsec); + + +#endif // RECAST_DUMP_H diff --git a/libs/recast/debug_utils/src/DebugDraw.cpp b/libs/recast/debug_utils/src/DebugDraw.cpp new file mode 100644 index 000000000..d0179bca2 --- /dev/null +++ b/libs/recast/debug_utils/src/DebugDraw.cpp @@ -0,0 +1,612 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include "DebugDraw.h" +#include "DetourMath.h" +#include "DetourNavMesh.h" + + +duDebugDraw::~duDebugDraw() +{ + // Empty +} + +unsigned int duDebugDraw::areaToCol(unsigned int area) +{ + if (area == 0) + { + // Treat zero area type as default. + return duRGBA(0, 192, 255, 255); + } + else + { + return duIntToCol(area, 255); + } +} + +inline int bit(int a, int b) +{ + return (a & (1 << b)) >> b; +} + +unsigned int duIntToCol(int i, int a) +{ + int r = bit(i, 1) + bit(i, 3) * 2 + 1; + int g = bit(i, 2) + bit(i, 4) * 2 + 1; + int b = bit(i, 0) + bit(i, 5) * 2 + 1; + return duRGBA(r*63,g*63,b*63,a); +} + +void duIntToCol(int i, float* col) +{ + int r = bit(i, 0) + bit(i, 3) * 2 + 1; + int g = bit(i, 1) + bit(i, 4) * 2 + 1; + int b = bit(i, 2) + bit(i, 5) * 2 + 1; + col[0] = 1 - r*63.0f/255.0f; + col[1] = 1 - g*63.0f/255.0f; + col[2] = 1 - b*63.0f/255.0f; +} + +void duCalcBoxColors(unsigned int* colors, unsigned int colTop, unsigned int colSide) +{ + if (!colors) return; + + colors[0] = duMultCol(colTop, 250); + colors[1] = duMultCol(colSide, 140); + colors[2] = duMultCol(colSide, 165); + colors[3] = duMultCol(colSide, 217); + colors[4] = duMultCol(colSide, 165); + colors[5] = duMultCol(colSide, 217); +} + +void duDebugDrawCylinderWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + duAppendCylinderWire(dd, minx,miny,minz, maxx,maxy,maxz, col); + dd->end(); +} + +void duDebugDrawBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + duAppendBoxWire(dd, minx,miny,minz, maxx,maxy,maxz, col); + dd->end(); +} + +void duDebugDrawArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, const float h, + const float as0, const float as1, unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + duAppendArc(dd, x0,y0,z0, x1,y1,z1, h, as0, as1, col); + dd->end(); +} + +void duDebugDrawArrow(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, + const float as0, const float as1, unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + duAppendArrow(dd, x0,y0,z0, x1,y1,z1, as0, as1, col); + dd->end(); +} + +void duDebugDrawCircle(struct duDebugDraw* dd, const float x, const float y, const float z, + const float r, unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + duAppendCircle(dd, x,y,z, r, col); + dd->end(); +} + +void duDebugDrawCross(struct duDebugDraw* dd, const float x, const float y, const float z, + const float size, unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + duAppendCross(dd, x,y,z, size, col); + dd->end(); +} + +void duDebugDrawBox(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, const unsigned int* fcol) +{ + if (!dd) return; + + dd->begin(DU_DRAW_QUADS); + duAppendBox(dd, minx,miny,minz, maxx,maxy,maxz, fcol); + dd->end(); +} + +void duDebugDrawCylinder(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col) +{ + if (!dd) return; + + dd->begin(DU_DRAW_TRIS); + duAppendCylinder(dd, minx,miny,minz, maxx,maxy,maxz, col); + dd->end(); +} + +void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz, + const int w, const int h, const float size, + const unsigned int col, const float lineWidth) +{ + if (!dd) return; + + dd->begin(DU_DRAW_LINES, lineWidth); + for (int i = 0; i <= h; ++i) + { + dd->vertex(ox,oy,oz+i*size, col); + dd->vertex(ox+w*size,oy,oz+i*size, col); + } + for (int i = 0; i <= w; ++i) + { + dd->vertex(ox+i*size,oy,oz, col); + dd->vertex(ox+i*size,oy,oz+h*size, col); + } + dd->end(); +} + + +void duAppendCylinderWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col) +{ + if (!dd) return; + + static const int NUM_SEG = 16; + static float dir[NUM_SEG*2]; + static bool init = false; + if (!init) + { + init = true; + for (int i = 0; i < NUM_SEG; ++i) + { + const float a = (float)i/(float)NUM_SEG*DU_PI*2; + dir[i*2] = dtMathCosf(a); + dir[i*2+1] = dtMathSinf(a); + } + } + + const float cx = (maxx + minx)/2; + const float cz = (maxz + minz)/2; + const float rx = (maxx - minx)/2; + const float rz = (maxz - minz)/2; + + for (int i = 0, j = NUM_SEG-1; i < NUM_SEG; j = i++) + { + dd->vertex(cx+dir[j*2+0]*rx, miny, cz+dir[j*2+1]*rz, col); + dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col); + dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, col); + dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, col); + } + for (int i = 0; i < NUM_SEG; i += NUM_SEG/4) + { + dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col); + dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, col); + } +} + +void duAppendBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col) +{ + if (!dd) return; + // Top + dd->vertex(minx, miny, minz, col); + dd->vertex(maxx, miny, minz, col); + dd->vertex(maxx, miny, minz, col); + dd->vertex(maxx, miny, maxz, col); + dd->vertex(maxx, miny, maxz, col); + dd->vertex(minx, miny, maxz, col); + dd->vertex(minx, miny, maxz, col); + dd->vertex(minx, miny, minz, col); + + // bottom + dd->vertex(minx, maxy, minz, col); + dd->vertex(maxx, maxy, minz, col); + dd->vertex(maxx, maxy, minz, col); + dd->vertex(maxx, maxy, maxz, col); + dd->vertex(maxx, maxy, maxz, col); + dd->vertex(minx, maxy, maxz, col); + dd->vertex(minx, maxy, maxz, col); + dd->vertex(minx, maxy, minz, col); + + // Sides + dd->vertex(minx, miny, minz, col); + dd->vertex(minx, maxy, minz, col); + dd->vertex(maxx, miny, minz, col); + dd->vertex(maxx, maxy, minz, col); + dd->vertex(maxx, miny, maxz, col); + dd->vertex(maxx, maxy, maxz, col); + dd->vertex(minx, miny, maxz, col); + dd->vertex(minx, maxy, maxz, col); +} + +void duAppendBoxPoints(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col) +{ + if (!dd) return; + // Top + dd->vertex(minx, miny, minz, col); + dd->vertex(maxx, miny, minz, col); + dd->vertex(maxx, miny, minz, col); + dd->vertex(maxx, miny, maxz, col); + dd->vertex(maxx, miny, maxz, col); + dd->vertex(minx, miny, maxz, col); + dd->vertex(minx, miny, maxz, col); + dd->vertex(minx, miny, minz, col); + + // bottom + dd->vertex(minx, maxy, minz, col); + dd->vertex(maxx, maxy, minz, col); + dd->vertex(maxx, maxy, minz, col); + dd->vertex(maxx, maxy, maxz, col); + dd->vertex(maxx, maxy, maxz, col); + dd->vertex(minx, maxy, maxz, col); + dd->vertex(minx, maxy, maxz, col); + dd->vertex(minx, maxy, minz, col); +} + +void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, const unsigned int* fcol) +{ + if (!dd) return; + const float verts[8*3] = + { + minx, miny, minz, + maxx, miny, minz, + maxx, miny, maxz, + minx, miny, maxz, + minx, maxy, minz, + maxx, maxy, minz, + maxx, maxy, maxz, + minx, maxy, maxz, + }; + static const unsigned char inds[6*4] = + { + 7, 6, 5, 4, + 0, 1, 2, 3, + 1, 5, 6, 2, + 3, 7, 4, 0, + 2, 6, 7, 3, + 0, 4, 5, 1, + }; + + const unsigned char* in = inds; + for (int i = 0; i < 6; ++i) + { + dd->vertex(&verts[*in*3], fcol[i]); in++; + dd->vertex(&verts[*in*3], fcol[i]); in++; + dd->vertex(&verts[*in*3], fcol[i]); in++; + dd->vertex(&verts[*in*3], fcol[i]); in++; + } +} + +void duAppendCylinder(struct duDebugDraw* dd, float minx, float miny, float minz, + float maxx, float maxy, float maxz, unsigned int col) +{ + if (!dd) return; + + static const int NUM_SEG = 16; + static float dir[NUM_SEG*2]; + static bool init = false; + if (!init) + { + init = true; + for (int i = 0; i < NUM_SEG; ++i) + { + const float a = (float)i/(float)NUM_SEG*DU_PI*2; + dir[i*2] = cosf(a); + dir[i*2+1] = sinf(a); + } + } + + unsigned int col2 = duMultCol(col, 160); + + const float cx = (maxx + minx)/2; + const float cz = (maxz + minz)/2; + const float rx = (maxx - minx)/2; + const float rz = (maxz - minz)/2; + + for (int i = 2; i < NUM_SEG; ++i) + { + const int a = 0, b = i-1, c = i; + dd->vertex(cx+dir[a*2+0]*rx, miny, cz+dir[a*2+1]*rz, col2); + dd->vertex(cx+dir[b*2+0]*rx, miny, cz+dir[b*2+1]*rz, col2); + dd->vertex(cx+dir[c*2+0]*rx, miny, cz+dir[c*2+1]*rz, col2); + } + for (int i = 2; i < NUM_SEG; ++i) + { + const int a = 0, b = i, c = i-1; + dd->vertex(cx+dir[a*2+0]*rx, maxy, cz+dir[a*2+1]*rz, col); + dd->vertex(cx+dir[b*2+0]*rx, maxy, cz+dir[b*2+1]*rz, col); + dd->vertex(cx+dir[c*2+0]*rx, maxy, cz+dir[c*2+1]*rz, col); + } + for (int i = 0, j = NUM_SEG-1; i < NUM_SEG; j = i++) + { + dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col2); + dd->vertex(cx+dir[j*2+0]*rx, miny, cz+dir[j*2+1]*rz, col2); + dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, col); + + dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col2); + dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, col); + dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, col); + } +} + + +inline void evalArc(const float x0, const float y0, const float z0, + const float dx, const float dy, const float dz, + const float h, const float u, float* res) +{ + res[0] = x0 + dx * u; + res[1] = y0 + dy * u + h * (1-(u*2-1)*(u*2-1)); + res[2] = z0 + dz * u; +} + + +inline void vcross(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[1]*v2[2] - v1[2]*v2[1]; + dest[1] = v1[2]*v2[0] - v1[0]*v2[2]; + dest[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +inline void vnormalize(float* v) +{ + float d = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + v[0] *= d; + v[1] *= d; + v[2] *= d; +} + +inline void vsub(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[0]-v2[0]; + dest[1] = v1[1]-v2[1]; + dest[2] = v1[2]-v2[2]; +} + +inline float vdistSqr(const float* v1, const float* v2) +{ + const float x = v1[0]-v2[0]; + const float y = v1[1]-v2[1]; + const float z = v1[2]-v2[2]; + return x*x + y*y + z*z; +} + + +void appendArrowHead(struct duDebugDraw* dd, const float* p, const float* q, + const float s, unsigned int col) +{ + const float eps = 0.001f; + if (!dd) return; + if (vdistSqr(p,q) < eps*eps) return; + float ax[3], ay[3] = {0,1,0}, az[3]; + vsub(az, q, p); + vnormalize(az); + vcross(ax, ay, az); + vcross(ay, az, ax); + vnormalize(ay); + + dd->vertex(p, col); +// dd->vertex(p[0]+az[0]*s+ay[0]*s/2, p[1]+az[1]*s+ay[1]*s/2, p[2]+az[2]*s+ay[2]*s/2, col); + dd->vertex(p[0]+az[0]*s+ax[0]*s/3, p[1]+az[1]*s+ax[1]*s/3, p[2]+az[2]*s+ax[2]*s/3, col); + + dd->vertex(p, col); +// dd->vertex(p[0]+az[0]*s-ay[0]*s/2, p[1]+az[1]*s-ay[1]*s/2, p[2]+az[2]*s-ay[2]*s/2, col); + dd->vertex(p[0]+az[0]*s-ax[0]*s/3, p[1]+az[1]*s-ax[1]*s/3, p[2]+az[2]*s-ax[2]*s/3, col); + +} + +void duAppendArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, const float h, + const float as0, const float as1, unsigned int col) +{ + if (!dd) return; + static const int NUM_ARC_PTS = 8; + static const float PAD = 0.05f; + static const float ARC_PTS_SCALE = (1.0f-PAD*2) / (float)NUM_ARC_PTS; + const float dx = x1 - x0; + const float dy = y1 - y0; + const float dz = z1 - z0; + const float len = sqrtf(dx*dx + dy*dy + dz*dz); + float prev[3]; + evalArc(x0,y0,z0, dx,dy,dz, len*h, PAD, prev); + for (int i = 1; i <= NUM_ARC_PTS; ++i) + { + const float u = PAD + i * ARC_PTS_SCALE; + float pt[3]; + evalArc(x0,y0,z0, dx,dy,dz, len*h, u, pt); + dd->vertex(prev[0],prev[1],prev[2], col); + dd->vertex(pt[0],pt[1],pt[2], col); + prev[0] = pt[0]; prev[1] = pt[1]; prev[2] = pt[2]; + } + + // End arrows + if (as0 > 0.001f) + { + float p[3], q[3]; + evalArc(x0,y0,z0, dx,dy,dz, len*h, PAD, p); + evalArc(x0,y0,z0, dx,dy,dz, len*h, PAD+0.05f, q); + appendArrowHead(dd, p, q, as0, col); + } + + if (as1 > 0.001f) + { + float p[3], q[3]; + evalArc(x0,y0,z0, dx,dy,dz, len*h, 1-PAD, p); + evalArc(x0,y0,z0, dx,dy,dz, len*h, 1-(PAD+0.05f), q); + appendArrowHead(dd, p, q, as1, col); + } +} + +void duAppendArrow(struct duDebugDraw* dd, const float x0, const float y0, const float z0, + const float x1, const float y1, const float z1, + const float as0, const float as1, unsigned int col) +{ + if (!dd) return; + + dd->vertex(x0,y0,z0, col); + dd->vertex(x1,y1,z1, col); + + // End arrows + const float p[3] = {x0,y0,z0}, q[3] = {x1,y1,z1}; + if (as0 > 0.001f) + appendArrowHead(dd, p, q, as0, col); + if (as1 > 0.001f) + appendArrowHead(dd, q, p, as1, col); +} + +void duAppendCircle(struct duDebugDraw* dd, const float x, const float y, const float z, + const float r, unsigned int col) +{ + if (!dd) return; + static const int NUM_SEG = 40; + static float dir[40*2]; + static bool init = false; + if (!init) + { + init = true; + for (int i = 0; i < NUM_SEG; ++i) + { + const float a = (float)i/(float)NUM_SEG*DU_PI*2; + dir[i*2] = cosf(a); + dir[i*2+1] = sinf(a); + } + } + + for (int i = 0, j = NUM_SEG-1; i < NUM_SEG; j = i++) + { + dd->vertex(x+dir[j*2+0]*r, y, z+dir[j*2+1]*r, col); + dd->vertex(x+dir[i*2+0]*r, y, z+dir[i*2+1]*r, col); + } +} + +void duAppendCross(struct duDebugDraw* dd, const float x, const float y, const float z, + const float s, unsigned int col) +{ + if (!dd) return; + dd->vertex(x-s,y,z, col); + dd->vertex(x+s,y,z, col); + dd->vertex(x,y-s,z, col); + dd->vertex(x,y+s,z, col); + dd->vertex(x,y,z-s, col); + dd->vertex(x,y,z+s, col); +} + +duDisplayList::duDisplayList(int cap) : + m_pos(0), + m_color(0), + m_size(0), + m_cap(0), + m_depthMask(true), + m_prim(DU_DRAW_LINES), + m_primSize(1.0f) +{ + if (cap < 8) + cap = 8; + resize(cap); +} + +duDisplayList::~duDisplayList() +{ + delete [] m_pos; + delete [] m_color; +} + +void duDisplayList::resize(int cap) +{ + float* newPos = new float[cap*3]; + if (m_size) + memcpy(newPos, m_pos, sizeof(float)*3*m_size); + delete [] m_pos; + m_pos = newPos; + + unsigned int* newColor = new unsigned int[cap]; + if (m_size) + memcpy(newColor, m_color, sizeof(unsigned int)*m_size); + delete [] m_color; + m_color = newColor; + + m_cap = cap; +} + +void duDisplayList::clear() +{ + m_size = 0; +} + +void duDisplayList::depthMask(bool state) +{ + m_depthMask = state; +} + +void duDisplayList::begin(duDebugDrawPrimitives prim, float size) +{ + clear(); + m_prim = prim; + m_primSize = size; +} + +void duDisplayList::vertex(const float x, const float y, const float z, unsigned int color) +{ + if (m_size+1 >= m_cap) + resize(m_cap*2); + float* p = &m_pos[m_size*3]; + p[0] = x; + p[1] = y; + p[2] = z; + m_color[m_size] = color; + m_size++; +} + +void duDisplayList::vertex(const float* pos, unsigned int color) +{ + vertex(pos[0],pos[1],pos[2],color); +} + +void duDisplayList::end() +{ +} + +void duDisplayList::draw(struct duDebugDraw* dd) +{ + if (!dd) return; + if (!m_size) return; + dd->depthMask(m_depthMask); + dd->begin(m_prim, m_primSize); + for (int i = 0; i < m_size; ++i) + dd->vertex(&m_pos[i*3], m_color[i]); + dd->end(); +} diff --git a/libs/recast/debug_utils/src/DetourDebugDraw.cpp b/libs/recast/debug_utils/src/DetourDebugDraw.cpp new file mode 100644 index 000000000..dd4bad3fd --- /dev/null +++ b/libs/recast/debug_utils/src/DetourDebugDraw.cpp @@ -0,0 +1,862 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include "DebugDraw.h" +#include "DetourDebugDraw.h" +#include "DetourNavMesh.h" +#include "DetourCommon.h" +#include "DetourNode.h" + + +static float distancePtLine2d(const float* pt, const float* p, const float* q) +{ + float pqx = q[0] - p[0]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqz*pqz; + float t = pqx*dx + pqz*dz; + if (d != 0) t /= d; + dx = p[0] + t*pqx - pt[0]; + dz = p[2] + t*pqz - pt[2]; + return dx*dx + dz*dz; +} + +static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshTile* tile, + const unsigned int col, const float linew, + bool inner) +{ + static const float thr = 0.01f*0.01f; + + dd->begin(DU_DRAW_LINES, linew); + + for (int i = 0; i < tile->header->polyCount; ++i) + { + const dtPoly* p = &tile->polys[i]; + + if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) continue; + + const dtPolyDetail* pd = &tile->detailMeshes[i]; + + for (int j = 0, nj = (int)p->vertCount; j < nj; ++j) + { + unsigned int c = col; + if (inner) + { + if (p->neis[j] == 0) continue; + if (p->neis[j] & DT_EXT_LINK) + { + bool con = false; + for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) + { + if (tile->links[k].edge == j) + { + con = true; + break; + } + } + if (con) + c = duRGBA(255,255,255,48); + else + c = duRGBA(0,0,0,48); + } + else + c = duRGBA(0,48,64,32); + } + else + { + if (p->neis[j] != 0) continue; + } + + const float* v0 = &tile->verts[p->verts[j]*3]; + const float* v1 = &tile->verts[p->verts[(j+1) % nj]*3]; + + // Draw detail mesh edges which align with the actual poly edge. + // This is really slow. + for (int k = 0; k < pd->triCount; ++k) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+k)*4]; + const float* tv[3]; + for (int m = 0; m < 3; ++m) + { + if (t[m] < p->vertCount) + tv[m] = &tile->verts[p->verts[t[m]]*3]; + else + tv[m] = &tile->detailVerts[(pd->vertBase+(t[m]-p->vertCount))*3]; + } + for (int m = 0, n = 2; m < 3; n=m++) + { + if (((t[3] >> (n*2)) & 0x3) == 0) continue; // Skip inner detail edges. + if (distancePtLine2d(tv[n],v0,v1) < thr && + distancePtLine2d(tv[m],v0,v1) < thr) + { + dd->vertex(tv[n], c); + dd->vertex(tv[m], c); + } + } + } + } + } + dd->end(); +} + +static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query, + const dtMeshTile* tile, unsigned char flags) +{ + dtPolyRef base = mesh.getPolyRefBase(tile); + + int tileNum = mesh.decodePolyIdTile(base); + const unsigned int tileColor = duIntToCol(tileNum, 128); + + dd->depthMask(false); + + dd->begin(DU_DRAW_TRIS); + for (int i = 0; i < tile->header->polyCount; ++i) + { + const dtPoly* p = &tile->polys[i]; + if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links. + continue; + + const dtPolyDetail* pd = &tile->detailMeshes[i]; + + unsigned int col; + if (query && query->isInClosedList(base | (dtPolyRef)i)) + col = duRGBA(255,196,0,64); + else + { + if (flags & DU_DRAWNAVMESH_COLOR_TILES) + col = tileColor; + else + col = duTransCol(dd->areaToCol(p->getArea()), 64); + } + + for (int j = 0; j < pd->triCount; ++j) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4]; + for (int k = 0; k < 3; ++k) + { + if (t[k] < p->vertCount) + dd->vertex(&tile->verts[p->verts[t[k]]*3], col); + else + dd->vertex(&tile->detailVerts[(pd->vertBase+t[k]-p->vertCount)*3], col); + } + } + } + dd->end(); + + // Draw inter poly boundaries + drawPolyBoundaries(dd, tile, duRGBA(0,48,64,32), 1.5f, true); + + // Draw outer poly boundaries + drawPolyBoundaries(dd, tile, duRGBA(0,48,64,220), 2.5f, false); + + if (flags & DU_DRAWNAVMESH_OFFMESHCONS) + { + dd->begin(DU_DRAW_LINES, 2.0f); + for (int i = 0; i < tile->header->polyCount; ++i) + { + const dtPoly* p = &tile->polys[i]; + if (p->getType() != DT_POLYTYPE_OFFMESH_CONNECTION) // Skip regular polys. + continue; + + unsigned int col, col2; + if (query && query->isInClosedList(base | (dtPolyRef)i)) + col = duRGBA(255,196,0,220); + else + col = duDarkenCol(duTransCol(dd->areaToCol(p->getArea()), 220)); + + const dtOffMeshConnection* con = &tile->offMeshCons[i - tile->header->offMeshBase]; + const float* va = &tile->verts[p->verts[0]*3]; + const float* vb = &tile->verts[p->verts[1]*3]; + + // Check to see if start and end end-points have links. + bool startSet = false; + bool endSet = false; + for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) + { + if (tile->links[k].edge == 0) + startSet = true; + if (tile->links[k].edge == 1) + endSet = true; + } + + // End points and their on-mesh locations. + dd->vertex(va[0],va[1],va[2], col); + dd->vertex(con->pos[0],con->pos[1],con->pos[2], col); + col2 = startSet ? col : duRGBA(220,32,16,196); + duAppendCircle(dd, con->pos[0],con->pos[1]+0.1f,con->pos[2], con->rad, col2); + + dd->vertex(vb[0],vb[1],vb[2], col); + dd->vertex(con->pos[3],con->pos[4],con->pos[5], col); + col2 = endSet ? col : duRGBA(220,32,16,196); + duAppendCircle(dd, con->pos[3],con->pos[4]+0.1f,con->pos[5], con->rad, col2); + + // End point vertices. + dd->vertex(con->pos[0],con->pos[1],con->pos[2], duRGBA(0,48,64,196)); + dd->vertex(con->pos[0],con->pos[1]+0.2f,con->pos[2], duRGBA(0,48,64,196)); + + dd->vertex(con->pos[3],con->pos[4],con->pos[5], duRGBA(0,48,64,196)); + dd->vertex(con->pos[3],con->pos[4]+0.2f,con->pos[5], duRGBA(0,48,64,196)); + + // Connection arc. + duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f, + (con->flags & 1) ? 0.6f : 0, 0.6f, col); + } + dd->end(); + } + + const unsigned int vcol = duRGBA(0,0,0,196); + dd->begin(DU_DRAW_POINTS, 3.0f); + for (int i = 0; i < tile->header->vertCount; ++i) + { + const float* v = &tile->verts[i*3]; + dd->vertex(v[0], v[1], v[2], vcol); + } + dd->end(); + + dd->depthMask(true); +} + +void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh& mesh, unsigned char flags) +{ + if (!dd) return; + + for (int i = 0; i < mesh.getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh.getTile(i); + if (!tile->header) continue; + drawMeshTile(dd, mesh, 0, tile, flags); + } +} + +void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, unsigned char flags) +{ + if (!dd) return; + + const dtNavMeshQuery* q = (flags & DU_DRAWNAVMESH_CLOSEDLIST) ? &query : 0; + + for (int i = 0; i < mesh.getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh.getTile(i); + if (!tile->header) continue; + drawMeshTile(dd, mesh, q, tile, flags); + } +} + +void duDebugDrawNavMeshNodes(struct duDebugDraw* dd, const dtNavMeshQuery& query) +{ + if (!dd) return; + + const dtNodePool* pool = query.getNodePool(); + if (pool) + { + const float off = 0.5f; + dd->begin(DU_DRAW_POINTS, 4.0f); + for (int i = 0; i < pool->getHashSize(); ++i) + { + for (dtNodeIndex j = pool->getFirst(i); j != DT_NULL_IDX; j = pool->getNext(j)) + { + const dtNode* node = pool->getNodeAtIdx(j+1); + if (!node) continue; + dd->vertex(node->pos[0],node->pos[1]+off,node->pos[2], duRGBA(255,192,0,255)); + } + } + dd->end(); + + dd->begin(DU_DRAW_LINES, 2.0f); + for (int i = 0; i < pool->getHashSize(); ++i) + { + for (dtNodeIndex j = pool->getFirst(i); j != DT_NULL_IDX; j = pool->getNext(j)) + { + const dtNode* node = pool->getNodeAtIdx(j+1); + if (!node) continue; + if (!node->pidx) continue; + const dtNode* parent = pool->getNodeAtIdx(node->pidx); + if (!parent) continue; + dd->vertex(node->pos[0],node->pos[1]+off,node->pos[2], duRGBA(255,192,0,128)); + dd->vertex(parent->pos[0],parent->pos[1]+off,parent->pos[2], duRGBA(255,192,0,128)); + } + } + dd->end(); + } +} + + +static void drawMeshTileBVTree(duDebugDraw* dd, const dtMeshTile* tile) +{ + // Draw BV nodes. + const float cs = 1.0f / tile->header->bvQuantFactor; + dd->begin(DU_DRAW_LINES, 1.0f); + for (int i = 0; i < tile->header->bvNodeCount; ++i) + { + const dtBVNode* n = &tile->bvTree[i]; + if (n->i < 0) // Leaf indices are positive. + continue; + duAppendBoxWire(dd, tile->header->bmin[0] + n->bmin[0]*cs, + tile->header->bmin[1] + n->bmin[1]*cs, + tile->header->bmin[2] + n->bmin[2]*cs, + tile->header->bmin[0] + n->bmax[0]*cs, + tile->header->bmin[1] + n->bmax[1]*cs, + tile->header->bmin[2] + n->bmax[2]*cs, + duRGBA(255,255,255,128)); + } + dd->end(); +} + +void duDebugDrawNavMeshBVTree(duDebugDraw* dd, const dtNavMesh& mesh) +{ + if (!dd) return; + + for (int i = 0; i < mesh.getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh.getTile(i); + if (!tile->header) continue; + drawMeshTileBVTree(dd, tile); + } +} + +static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile) +{ + // Draw portals + const float padx = 0.04f; + const float pady = tile->header->walkableClimb; + + dd->begin(DU_DRAW_LINES, 2.0f); + + for (int side = 0; side < 8; ++side) + { + unsigned short m = DT_EXT_LINK | (unsigned short)side; + + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* poly = &tile->polys[i]; + + // Create new links. + const int nv = poly->vertCount; + for (int j = 0; j < nv; ++j) + { + // Skip edges which do not point to the right side. + if (poly->neis[j] != m) + continue; + + // Create new links + const float* va = &tile->verts[poly->verts[j]*3]; + const float* vb = &tile->verts[poly->verts[(j+1) % nv]*3]; + + if (side == 0 || side == 4) + { + unsigned int col = side == 0 ? duRGBA(128,0,0,128) : duRGBA(128,0,128,128); + + const float x = va[0] + ((side == 0) ? -padx : padx); + + dd->vertex(x,va[1]-pady,va[2], col); + dd->vertex(x,va[1]+pady,va[2], col); + + dd->vertex(x,va[1]+pady,va[2], col); + dd->vertex(x,vb[1]+pady,vb[2], col); + + dd->vertex(x,vb[1]+pady,vb[2], col); + dd->vertex(x,vb[1]-pady,vb[2], col); + + dd->vertex(x,vb[1]-pady,vb[2], col); + dd->vertex(x,va[1]-pady,va[2], col); + } + else if (side == 2 || side == 6) + { + unsigned int col = side == 2 ? duRGBA(0,128,0,128) : duRGBA(0,128,128,128); + + const float z = va[2] + ((side == 2) ? -padx : padx); + + dd->vertex(va[0],va[1]-pady,z, col); + dd->vertex(va[0],va[1]+pady,z, col); + + dd->vertex(va[0],va[1]+pady,z, col); + dd->vertex(vb[0],vb[1]+pady,z, col); + + dd->vertex(vb[0],vb[1]+pady,z, col); + dd->vertex(vb[0],vb[1]-pady,z, col); + + dd->vertex(vb[0],vb[1]-pady,z, col); + dd->vertex(va[0],va[1]-pady,z, col); + } + + } + } + } + + dd->end(); +} + +void duDebugDrawNavMeshPortals(duDebugDraw* dd, const dtNavMesh& mesh) +{ + if (!dd) return; + + for (int i = 0; i < mesh.getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh.getTile(i); + if (!tile->header) continue; + drawMeshTilePortal(dd, tile); + } +} + +void duDebugDrawNavMeshPolysWithFlags(struct duDebugDraw* dd, const dtNavMesh& mesh, + const unsigned short polyFlags, const unsigned int col) +{ + if (!dd) return; + + for (int i = 0; i < mesh.getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh.getTile(i); + if (!tile->header) continue; + dtPolyRef base = mesh.getPolyRefBase(tile); + + for (int j = 0; j < tile->header->polyCount; ++j) + { + const dtPoly* p = &tile->polys[j]; + if ((p->flags & polyFlags) == 0) continue; + duDebugDrawNavMeshPoly(dd, mesh, base|(dtPolyRef)j, col); + } + } +} + +void duDebugDrawNavMeshPoly(duDebugDraw* dd, const dtNavMesh& mesh, dtPolyRef ref, const unsigned int col) +{ + if (!dd) return; + + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + if (dtStatusFailed(mesh.getTileAndPolyByRef(ref, &tile, &poly))) + return; + + dd->depthMask(false); + + const unsigned int c = duTransCol(col, 64); + const unsigned int ip = (unsigned int)(poly - tile->polys); + + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + dtOffMeshConnection* con = &tile->offMeshCons[ip - tile->header->offMeshBase]; + + dd->begin(DU_DRAW_LINES, 2.0f); + + // Connection arc. + duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f, + (con->flags & 1) ? 0.6f : 0.0f, 0.6f, c); + + dd->end(); + } + else + { + const dtPolyDetail* pd = &tile->detailMeshes[ip]; + + dd->begin(DU_DRAW_TRIS); + for (int i = 0; i < pd->triCount; ++i) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+i)*4]; + for (int j = 0; j < 3; ++j) + { + if (t[j] < poly->vertCount) + dd->vertex(&tile->verts[poly->verts[t[j]]*3], c); + else + dd->vertex(&tile->detailVerts[(pd->vertBase+t[j]-poly->vertCount)*3], c); + } + } + dd->end(); + } + + dd->depthMask(true); + +} + +static void debugDrawTileCachePortals(struct duDebugDraw* dd, const dtTileCacheLayer& layer, const float cs, const float ch) +{ + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + const float* bmin = layer.header->bmin; + + // Portals + unsigned int pcol = duRGBA(255,255,255,255); + + const int segs[4*4] = {0,0,0,1, 0,1,1,1, 1,1,1,0, 1,0,0,0}; + + // Layer portals + dd->begin(DU_DRAW_LINES, 2.0f); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int idx = x+y*w; + const int lh = (int)layer.heights[idx]; + if (lh == 0xff) continue; + + for (int dir = 0; dir < 4; ++dir) + { + if (layer.cons[idx] & (1<<(dir+4))) + { + const int* seg = &segs[dir*4]; + const float ax = bmin[0] + (x+seg[0])*cs; + const float ay = bmin[1] + (lh+2)*ch; + const float az = bmin[2] + (y+seg[1])*cs; + const float bx = bmin[0] + (x+seg[2])*cs; + const float by = bmin[1] + (lh+2)*ch; + const float bz = bmin[2] + (y+seg[3])*cs; + dd->vertex(ax, ay, az, pcol); + dd->vertex(bx, by, bz, pcol); + } + } + } + } + dd->end(); +} + +void duDebugDrawTileCacheLayerAreas(struct duDebugDraw* dd, const dtTileCacheLayer& layer, const float cs, const float ch) +{ + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + const float* bmin = layer.header->bmin; + const float* bmax = layer.header->bmax; + const int idx = layer.header->tlayer; + + unsigned int color = duIntToCol(idx+1, 255); + + // Layer bounds + float lbmin[3], lbmax[3]; + lbmin[0] = bmin[0] + layer.header->minx*cs; + lbmin[1] = bmin[1]; + lbmin[2] = bmin[2] + layer.header->miny*cs; + lbmax[0] = bmin[0] + (layer.header->maxx+1)*cs; + lbmax[1] = bmax[1]; + lbmax[2] = bmin[2] + (layer.header->maxy+1)*cs; + duDebugDrawBoxWire(dd, lbmin[0],lbmin[1],lbmin[2], lbmax[0],lbmax[1],lbmax[2], duTransCol(color,128), 2.0f); + + // Layer height + dd->begin(DU_DRAW_QUADS); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int lidx = x+y*w; + const int lh = (int)layer.heights[lidx]; + if (lh == 0xff) continue; + + const unsigned char area = layer.areas[lidx]; + unsigned int col; + if (area == 63) + col = duLerpCol(color, duRGBA(0,192,255,64), 32); + else if (area == 0) + col = duLerpCol(color, duRGBA(0,0,0,64), 32); + else + col = duLerpCol(color, dd->areaToCol(area), 32); + + const float fx = bmin[0] + x*cs; + const float fy = bmin[1] + (lh+1)*ch; + const float fz = bmin[2] + y*cs; + + dd->vertex(fx, fy, fz, col); + dd->vertex(fx, fy, fz+cs, col); + dd->vertex(fx+cs, fy, fz+cs, col); + dd->vertex(fx+cs, fy, fz, col); + } + } + dd->end(); + + debugDrawTileCachePortals(dd, layer, cs, ch); +} + +void duDebugDrawTileCacheLayerRegions(struct duDebugDraw* dd, const dtTileCacheLayer& layer, const float cs, const float ch) +{ + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + const float* bmin = layer.header->bmin; + const float* bmax = layer.header->bmax; + const int idx = layer.header->tlayer; + + unsigned int color = duIntToCol(idx+1, 255); + + // Layer bounds + float lbmin[3], lbmax[3]; + lbmin[0] = bmin[0] + layer.header->minx*cs; + lbmin[1] = bmin[1]; + lbmin[2] = bmin[2] + layer.header->miny*cs; + lbmax[0] = bmin[0] + (layer.header->maxx+1)*cs; + lbmax[1] = bmax[1]; + lbmax[2] = bmin[2] + (layer.header->maxy+1)*cs; + duDebugDrawBoxWire(dd, lbmin[0],lbmin[1],lbmin[2], lbmax[0],lbmax[1],lbmax[2], duTransCol(color,128), 2.0f); + + // Layer height + dd->begin(DU_DRAW_QUADS); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int lidx = x+y*w; + const int lh = (int)layer.heights[lidx]; + if (lh == 0xff) continue; + const unsigned char reg = layer.regs[lidx]; + + unsigned int col = duLerpCol(color, duIntToCol(reg, 255), 192); + + const float fx = bmin[0] + x*cs; + const float fy = bmin[1] + (lh+1)*ch; + const float fz = bmin[2] + y*cs; + + dd->vertex(fx, fy, fz, col); + dd->vertex(fx, fy, fz+cs, col); + dd->vertex(fx+cs, fy, fz+cs, col); + dd->vertex(fx+cs, fy, fz, col); + } + } + dd->end(); + + debugDrawTileCachePortals(dd, layer, cs, ch); +} + + + + +/*struct dtTileCacheContour +{ + int nverts; + unsigned char* verts; + unsigned char reg; + unsigned char area; +}; + +struct dtTileCacheContourSet +{ + int nconts; + dtTileCacheContour* conts; +};*/ + +void duDebugDrawTileCacheContours(duDebugDraw* dd, const struct dtTileCacheContourSet& lcset, + const float* orig, const float cs, const float ch) +{ + if (!dd) return; + + const unsigned char a = 255;// (unsigned char)(alpha*255.0f); + + const int offs[2*4] = {-1,0, 0,1, 1,0, 0,-1}; + + dd->begin(DU_DRAW_LINES, 2.0f); + + for (int i = 0; i < lcset.nconts; ++i) + { + const dtTileCacheContour& c = lcset.conts[i]; + unsigned int color = 0; + + color = duIntToCol(i, a); + + for (int j = 0; j < c.nverts; ++j) + { + const int k = (j+1) % c.nverts; + const unsigned char* va = &c.verts[j*4]; + const unsigned char* vb = &c.verts[k*4]; + const float ax = orig[0] + va[0]*cs; + const float ay = orig[1] + (va[1]+1+(i&1))*ch; + const float az = orig[2] + va[2]*cs; + const float bx = orig[0] + vb[0]*cs; + const float by = orig[1] + (vb[1]+1+(i&1))*ch; + const float bz = orig[2] + vb[2]*cs; + unsigned int col = color; + if ((va[3] & 0xf) != 0xf) + { + // Portal segment + col = duRGBA(255,255,255,128); + int d = va[3] & 0xf; + + const float cx = (ax+bx)*0.5f; + const float cy = (ay+by)*0.5f; + const float cz = (az+bz)*0.5f; + + const float dx = cx + offs[d*2+0]*2*cs; + const float dy = cy; + const float dz = cz + offs[d*2+1]*2*cs; + + dd->vertex(cx,cy,cz,duRGBA(255,0,0,255)); + dd->vertex(dx,dy,dz,duRGBA(255,0,0,255)); + } + + duAppendArrow(dd, ax,ay,az, bx,by,bz, 0.0f, cs*0.5f, col); + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 4.0f); + + for (int i = 0; i < lcset.nconts; ++i) + { + const dtTileCacheContour& c = lcset.conts[i]; + unsigned int color = 0; + + for (int j = 0; j < c.nverts; ++j) + { + const unsigned char* va = &c.verts[j*4]; + + color = duDarkenCol(duIntToCol(i, a)); + if (va[3] & 0x80) + { + // Border vertex + color = duRGBA(255,0,0,255); + } + + float fx = orig[0] + va[0]*cs; + float fy = orig[1] + (va[1]+1+(i&1))*ch; + float fz = orig[2] + va[2]*cs; + dd->vertex(fx,fy,fz, color); + } + } + dd->end(); +} + +void duDebugDrawTileCachePolyMesh(duDebugDraw* dd, const struct dtTileCachePolyMesh& lmesh, + const float* orig, const float cs, const float ch) +{ + if (!dd) return; + + const int nvp = lmesh.nvp; + + const int offs[2*4] = {-1,0, 0,1, 1,0, 0,-1}; + + dd->begin(DU_DRAW_TRIS); + + for (int i = 0; i < lmesh.npolys; ++i) + { + const unsigned short* p = &lmesh.polys[i*nvp*2]; + const unsigned char area = lmesh.areas[i]; + + unsigned int color; + if (area == DT_TILECACHE_WALKABLE_AREA) + color = duRGBA(0,192,255,64); + else if (area == DT_TILECACHE_NULL_AREA) + color = duRGBA(0,0,0,64); + else + color = dd->areaToCol(area); + + unsigned short vi[3]; + for (int j = 2; j < nvp; ++j) + { + if (p[j] == DT_TILECACHE_NULL_IDX) break; + vi[0] = p[0]; + vi[1] = p[j-1]; + vi[2] = p[j]; + for (int k = 0; k < 3; ++k) + { + const unsigned short* v = &lmesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch; + const float z = orig[2] + v[2]*cs; + dd->vertex(x,y,z, color); + } + } + } + dd->end(); + + // Draw neighbours edges + const unsigned int coln = duRGBA(0,48,64,32); + dd->begin(DU_DRAW_LINES, 1.5f); + for (int i = 0; i < lmesh.npolys; ++i) + { + const unsigned short* p = &lmesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == DT_TILECACHE_NULL_IDX) break; + if (p[nvp+j] & 0x8000) continue; + const int nj = (j+1 >= nvp || p[j+1] == DT_TILECACHE_NULL_IDX) ? 0 : j+1; + int vi[2] = {p[j], p[nj]}; + + for (int k = 0; k < 2; ++k) + { + const unsigned short* v = &lmesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x, y, z, coln); + } + } + } + dd->end(); + + // Draw boundary edges + const unsigned int colb = duRGBA(0,48,64,220); + dd->begin(DU_DRAW_LINES, 2.5f); + for (int i = 0; i < lmesh.npolys; ++i) + { + const unsigned short* p = &lmesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == DT_TILECACHE_NULL_IDX) break; + if ((p[nvp+j] & 0x8000) == 0) continue; + const int nj = (j+1 >= nvp || p[j+1] == DT_TILECACHE_NULL_IDX) ? 0 : j+1; + int vi[2] = {p[j], p[nj]}; + + unsigned int col = colb; + if ((p[nvp+j] & 0xf) != 0xf) + { + const unsigned short* va = &lmesh.verts[vi[0]*3]; + const unsigned short* vb = &lmesh.verts[vi[1]*3]; + + const float ax = orig[0] + va[0]*cs; + const float ay = orig[1] + (va[1]+1+(i&1))*ch; + const float az = orig[2] + va[2]*cs; + const float bx = orig[0] + vb[0]*cs; + const float by = orig[1] + (vb[1]+1+(i&1))*ch; + const float bz = orig[2] + vb[2]*cs; + + const float cx = (ax+bx)*0.5f; + const float cy = (ay+by)*0.5f; + const float cz = (az+bz)*0.5f; + + int d = p[nvp+j] & 0xf; + + const float dx = cx + offs[d*2+0]*2*cs; + const float dy = cy; + const float dz = cz + offs[d*2+1]*2*cs; + + dd->vertex(cx,cy,cz,duRGBA(255,0,0,255)); + dd->vertex(dx,dy,dz,duRGBA(255,0,0,255)); + + col = duRGBA(255,255,255,128); + } + + for (int k = 0; k < 2; ++k) + { + const unsigned short* v = &lmesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x, y, z, col); + } + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 3.0f); + const unsigned int colv = duRGBA(0,0,0,220); + for (int i = 0; i < lmesh.nverts; ++i) + { + const unsigned short* v = &lmesh.verts[i*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x,y,z, colv); + } + dd->end(); +} + + + diff --git a/libs/recast/debug_utils/src/RecastDebugDraw.cpp b/libs/recast/debug_utils/src/RecastDebugDraw.cpp new file mode 100644 index 000000000..c1a73a168 --- /dev/null +++ b/libs/recast/debug_utils/src/RecastDebugDraw.cpp @@ -0,0 +1,1064 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include "DebugDraw.h" +#include "RecastDebugDraw.h" +#include "Recast.h" + +void duDebugDrawTriMesh(duDebugDraw* dd, const float* verts, int /*nverts*/, + const int* tris, const float* normals, int ntris, + const unsigned char* flags, const float texScale) +{ + if (!dd) return; + if (!verts) return; + if (!tris) return; + if (!normals) return; + + float uva[2]; + float uvb[2]; + float uvc[2]; + + const unsigned int unwalkable = duRGBA(192,128,0,255); + + dd->texture(true); + + dd->begin(DU_DRAW_TRIS); + for (int i = 0; i < ntris*3; i += 3) + { + const float* norm = &normals[i]; + unsigned int color; + unsigned char a = (unsigned char)(220*(2+norm[0]+norm[1])/4); + if (flags && !flags[i/3]) + color = duLerpCol(duRGBA(a,a,a,255), unwalkable, 64); + else + color = duRGBA(a,a,a,255); + + const float* va = &verts[tris[i+0]*3]; + const float* vb = &verts[tris[i+1]*3]; + const float* vc = &verts[tris[i+2]*3]; + + int ax = 0, ay = 0; + if (rcAbs(norm[1]) > rcAbs(norm[ax])) + ax = 1; + if (rcAbs(norm[2]) > rcAbs(norm[ax])) + ax = 2; + ax = (1<vertex(va, color, uva); + dd->vertex(vb, color, uvb); + dd->vertex(vc, color, uvc); + } + dd->end(); + dd->texture(false); +} + +void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int /*nverts*/, + const int* tris, const float* normals, int ntris, + const float walkableSlopeAngle, const float texScale) +{ + if (!dd) return; + if (!verts) return; + if (!tris) return; + if (!normals) return; + + const float walkableThr = cosf(walkableSlopeAngle/180.0f*DU_PI); + + float uva[2]; + float uvb[2]; + float uvc[2]; + + dd->texture(true); + + const unsigned int unwalkable = duRGBA(192,128,0,255); + + dd->begin(DU_DRAW_TRIS); + for (int i = 0; i < ntris*3; i += 3) + { + const float* norm = &normals[i]; + unsigned int color; + unsigned char a = (unsigned char)(220*(2+norm[0]+norm[1])/4); + if (norm[1] < walkableThr) + color = duLerpCol(duRGBA(a,a,a,255), unwalkable, 64); + else + color = duRGBA(a,a,a,255); + + const float* va = &verts[tris[i+0]*3]; + const float* vb = &verts[tris[i+1]*3]; + const float* vc = &verts[tris[i+2]*3]; + + int ax = 0, ay = 0; + if (rcAbs(norm[1]) > rcAbs(norm[ax])) + ax = 1; + if (rcAbs(norm[2]) > rcAbs(norm[ax])) + ax = 2; + ax = (1<vertex(va, color, uva); + dd->vertex(vb, color, uvb); + dd->vertex(vc, color, uvc); + } + dd->end(); + + dd->texture(false); +} + +void duDebugDrawHeightfieldSolid(duDebugDraw* dd, const rcHeightfield& hf) +{ + if (!dd) return; + + const float* orig = hf.bmin; + const float cs = hf.cs; + const float ch = hf.ch; + + const int w = hf.width; + const int h = hf.height; + + unsigned int fcol[6]; + duCalcBoxColors(fcol, duRGBA(255,255,255,255), duRGBA(255,255,255,255)); + + dd->begin(DU_DRAW_QUADS); + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + float fx = orig[0] + x*cs; + float fz = orig[2] + y*cs; + const rcSpan* s = hf.spans[x + y*w]; + while (s) + { + duAppendBox(dd, fx, orig[1]+s->smin*ch, fz, fx+cs, orig[1] + s->smax*ch, fz+cs, fcol); + s = s->next; + } + } + } + dd->end(); +} + +void duDebugDrawHeightfieldWalkable(duDebugDraw* dd, const rcHeightfield& hf) +{ + if (!dd) return; + + const float* orig = hf.bmin; + const float cs = hf.cs; + const float ch = hf.ch; + + const int w = hf.width; + const int h = hf.height; + + unsigned int fcol[6]; + duCalcBoxColors(fcol, duRGBA(255,255,255,255), duRGBA(217,217,217,255)); + + dd->begin(DU_DRAW_QUADS); + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + float fx = orig[0] + x*cs; + float fz = orig[2] + y*cs; + const rcSpan* s = hf.spans[x + y*w]; + while (s) + { + if (s->area == RC_WALKABLE_AREA) + fcol[0] = duRGBA(64,128,160,255); + else if (s->area == RC_NULL_AREA) + fcol[0] = duRGBA(64,64,64,255); + else + fcol[0] = duMultCol(dd->areaToCol(s->area), 200); + + duAppendBox(dd, fx, orig[1]+s->smin*ch, fz, fx+cs, orig[1] + s->smax*ch, fz+cs, fcol); + s = s->next; + } + } + } + + dd->end(); +} + +void duDebugDrawCompactHeightfieldSolid(duDebugDraw* dd, const rcCompactHeightfield& chf) +{ + if (!dd) return; + + const float cs = chf.cs; + const float ch = chf.ch; + + dd->begin(DU_DRAW_QUADS); + + for (int y = 0; y < chf.height; ++y) + { + for (int x = 0; x < chf.width; ++x) + { + const float fx = chf.bmin[0] + x*cs; + const float fz = chf.bmin[2] + y*cs; + const rcCompactCell& c = chf.cells[x+y*chf.width]; + + for (unsigned i = c.index, ni = c.index+c.count; i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + + const unsigned char area = chf.areas[i]; + unsigned int color; + if (area == RC_WALKABLE_AREA) + color = duRGBA(0,192,255,64); + else if (area == RC_NULL_AREA) + color = duRGBA(0,0,0,64); + else + color = dd->areaToCol(area); + + const float fy = chf.bmin[1] + (s.y+1)*ch; + dd->vertex(fx, fy, fz, color); + dd->vertex(fx, fy, fz+cs, color); + dd->vertex(fx+cs, fy, fz+cs, color); + dd->vertex(fx+cs, fy, fz, color); + } + } + } + dd->end(); +} + +void duDebugDrawCompactHeightfieldRegions(duDebugDraw* dd, const rcCompactHeightfield& chf) +{ + if (!dd) return; + + const float cs = chf.cs; + const float ch = chf.ch; + + dd->begin(DU_DRAW_QUADS); + + for (int y = 0; y < chf.height; ++y) + { + for (int x = 0; x < chf.width; ++x) + { + const float fx = chf.bmin[0] + x*cs; + const float fz = chf.bmin[2] + y*cs; + const rcCompactCell& c = chf.cells[x+y*chf.width]; + + for (unsigned i = c.index, ni = c.index+c.count; i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + const float fy = chf.bmin[1] + (s.y)*ch; + unsigned int color; + if (s.reg) + color = duIntToCol(s.reg, 192); + else + color = duRGBA(0,0,0,64); + + dd->vertex(fx, fy, fz, color); + dd->vertex(fx, fy, fz+cs, color); + dd->vertex(fx+cs, fy, fz+cs, color); + dd->vertex(fx+cs, fy, fz, color); + } + } + } + + dd->end(); +} + + +void duDebugDrawCompactHeightfieldDistance(duDebugDraw* dd, const rcCompactHeightfield& chf) +{ + if (!dd) return; + if (!chf.dist) return; + + const float cs = chf.cs; + const float ch = chf.ch; + + float maxd = chf.maxDistance; + if (maxd < 1.0f) maxd = 1; + const float dscale = 255.0f / maxd; + + dd->begin(DU_DRAW_QUADS); + + for (int y = 0; y < chf.height; ++y) + { + for (int x = 0; x < chf.width; ++x) + { + const float fx = chf.bmin[0] + x*cs; + const float fz = chf.bmin[2] + y*cs; + const rcCompactCell& c = chf.cells[x+y*chf.width]; + + for (unsigned i = c.index, ni = c.index+c.count; i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + const float fy = chf.bmin[1] + (s.y+1)*ch; + const unsigned char cd = (unsigned char)(chf.dist[i] * dscale); + const unsigned int color = duRGBA(cd,cd,cd,255); + dd->vertex(fx, fy, fz, color); + dd->vertex(fx, fy, fz+cs, color); + dd->vertex(fx+cs, fy, fz+cs, color); + dd->vertex(fx+cs, fy, fz, color); + } + } + } + dd->end(); +} + +static void drawLayerPortals(duDebugDraw* dd, const rcHeightfieldLayer* layer) +{ + const float cs = layer->cs; + const float ch = layer->ch; + const int w = layer->width; + const int h = layer->height; + + unsigned int pcol = duRGBA(255,255,255,255); + + const int segs[4*4] = {0,0,0,1, 0,1,1,1, 1,1,1,0, 1,0,0,0}; + + // Layer portals + dd->begin(DU_DRAW_LINES, 2.0f); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int idx = x+y*w; + const int lh = (int)layer->heights[idx]; + if (lh == 255) continue; + + for (int dir = 0; dir < 4; ++dir) + { + if (layer->cons[idx] & (1<<(dir+4))) + { + const int* seg = &segs[dir*4]; + const float ax = layer->bmin[0] + (x+seg[0])*cs; + const float ay = layer->bmin[1] + (lh+2)*ch; + const float az = layer->bmin[2] + (y+seg[1])*cs; + const float bx = layer->bmin[0] + (x+seg[2])*cs; + const float by = layer->bmin[1] + (lh+2)*ch; + const float bz = layer->bmin[2] + (y+seg[3])*cs; + dd->vertex(ax, ay, az, pcol); + dd->vertex(bx, by, bz, pcol); + } + } + } + } + dd->end(); +} + +void duDebugDrawHeightfieldLayer(duDebugDraw* dd, const struct rcHeightfieldLayer& layer, const int idx) +{ + const float cs = layer.cs; + const float ch = layer.ch; + const int w = layer.width; + const int h = layer.height; + + unsigned int color = duIntToCol(idx+1, 255); + + // Layer bounds + float bmin[3], bmax[3]; + bmin[0] = layer.bmin[0] + layer.minx*cs; + bmin[1] = layer.bmin[1]; + bmin[2] = layer.bmin[2] + layer.miny*cs; + bmax[0] = layer.bmin[0] + (layer.maxx+1)*cs; + bmax[1] = layer.bmax[1]; + bmax[2] = layer.bmin[2] + (layer.maxy+1)*cs; + duDebugDrawBoxWire(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duTransCol(color,128), 2.0f); + + // Layer height + dd->begin(DU_DRAW_QUADS); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int lidx = x+y*w; + const int lh = (int)layer.heights[lidx]; + if (h == 0xff) continue; + const unsigned char area = layer.areas[lidx]; + + unsigned int col; + if (area == RC_WALKABLE_AREA) + col = duLerpCol(color, duRGBA(0,192,255,64), 32); + else if (area == RC_NULL_AREA) + col = duLerpCol(color, duRGBA(0,0,0,64), 32); + else + col = duLerpCol(color, dd->areaToCol(area), 32); + + const float fx = layer.bmin[0] + x*cs; + const float fy = layer.bmin[1] + (lh+1)*ch; + const float fz = layer.bmin[2] + y*cs; + + dd->vertex(fx, fy, fz, col); + dd->vertex(fx, fy, fz+cs, col); + dd->vertex(fx+cs, fy, fz+cs, col); + dd->vertex(fx+cs, fy, fz, col); + } + } + dd->end(); + + // Portals + drawLayerPortals(dd, &layer); +} + +void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset) +{ + if (!dd) return; + for (int i = 0; i < lset.nlayers; ++i) + duDebugDrawHeightfieldLayer(dd, lset.layers[i], i); +} + +/* +void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& lcset) +{ + if (!dd) return; + + const float* orig = lcset.bmin; + const float cs = lcset.cs; + const float ch = lcset.ch; + + const unsigned char a = 255;// (unsigned char)(alpha*255.0f); + + const int offs[2*4] = {-1,0, 0,1, 1,0, 0,-1}; + + dd->begin(DU_DRAW_LINES, 2.0f); + + for (int i = 0; i < lcset.nconts; ++i) + { + const rcLayerContour& c = lcset.conts[i]; + unsigned int color = 0; + + color = duIntToCol(i, a); + + for (int j = 0; j < c.nverts; ++j) + { + const int k = (j+1) % c.nverts; + const unsigned char* va = &c.verts[j*4]; + const unsigned char* vb = &c.verts[k*4]; + const float ax = orig[0] + va[0]*cs; + const float ay = orig[1] + (va[1]+1+(i&1))*ch; + const float az = orig[2] + va[2]*cs; + const float bx = orig[0] + vb[0]*cs; + const float by = orig[1] + (vb[1]+1+(i&1))*ch; + const float bz = orig[2] + vb[2]*cs; + unsigned int col = color; + if ((va[3] & 0xf) != 0xf) + { + col = duRGBA(255,255,255,128); + int d = va[3] & 0xf; + + const float cx = (ax+bx)*0.5f; + const float cy = (ay+by)*0.5f; + const float cz = (az+bz)*0.5f; + + const float dx = cx + offs[d*2+0]*2*cs; + const float dy = cy; + const float dz = cz + offs[d*2+1]*2*cs; + + dd->vertex(cx,cy,cz,duRGBA(255,0,0,255)); + dd->vertex(dx,dy,dz,duRGBA(255,0,0,255)); + } + + duAppendArrow(dd, ax,ay,az, bx,by,bz, 0.0f, cs*0.5f, col); + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 4.0f); + + for (int i = 0; i < lcset.nconts; ++i) + { + const rcLayerContour& c = lcset.conts[i]; + unsigned int color = 0; + + for (int j = 0; j < c.nverts; ++j) + { + const unsigned char* va = &c.verts[j*4]; + + color = duDarkenCol(duIntToCol(i, a)); + if (va[3] & 0x80) + color = duRGBA(255,0,0,255); + + float fx = orig[0] + va[0]*cs; + float fy = orig[1] + (va[1]+1+(i&1))*ch; + float fz = orig[2] + va[2]*cs; + dd->vertex(fx,fy,fz, color); + } + } + dd->end(); +} + +void duDebugDrawLayerPolyMesh(duDebugDraw* dd, const struct rcLayerPolyMesh& lmesh) +{ + if (!dd) return; + + const int nvp = lmesh.nvp; + const float cs = lmesh.cs; + const float ch = lmesh.ch; + const float* orig = lmesh.bmin; + + const int offs[2*4] = {-1,0, 0,1, 1,0, 0,-1}; + + dd->begin(DU_DRAW_TRIS); + + for (int i = 0; i < lmesh.npolys; ++i) + { + const unsigned short* p = &lmesh.polys[i*nvp*2]; + + unsigned int color; + if (lmesh.areas[i] == RC_WALKABLE_AREA) + color = duRGBA(0,192,255,64); + else if (lmesh.areas[i] == RC_NULL_AREA) + color = duRGBA(0,0,0,64); + else + color = duIntToCol(lmesh.areas[i], 255); + + unsigned short vi[3]; + for (int j = 2; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + vi[0] = p[0]; + vi[1] = p[j-1]; + vi[2] = p[j]; + for (int k = 0; k < 3; ++k) + { + const unsigned short* v = &lmesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch; + const float z = orig[2] + v[2]*cs; + dd->vertex(x,y,z, color); + } + } + } + dd->end(); + + // Draw neighbours edges + const unsigned int coln = duRGBA(0,48,64,32); + dd->begin(DU_DRAW_LINES, 1.5f); + for (int i = 0; i < lmesh.npolys; ++i) + { + const unsigned short* p = &lmesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + if (p[nvp+j] & 0x8000) continue; + const int nj = (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX) ? 0 : j+1; + int vi[2] = {p[j], p[nj]}; + + for (int k = 0; k < 2; ++k) + { + const unsigned short* v = &lmesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x, y, z, coln); + } + } + } + dd->end(); + + // Draw boundary edges + const unsigned int colb = duRGBA(0,48,64,220); + dd->begin(DU_DRAW_LINES, 2.5f); + for (int i = 0; i < lmesh.npolys; ++i) + { + const unsigned short* p = &lmesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + if ((p[nvp+j] & 0x8000) == 0) continue; + const int nj = (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX) ? 0 : j+1; + int vi[2] = {p[j], p[nj]}; + + unsigned int col = colb; + if ((p[nvp+j] & 0xf) != 0xf) + { + const unsigned short* va = &lmesh.verts[vi[0]*3]; + const unsigned short* vb = &lmesh.verts[vi[1]*3]; + + const float ax = orig[0] + va[0]*cs; + const float ay = orig[1] + (va[1]+1+(i&1))*ch; + const float az = orig[2] + va[2]*cs; + const float bx = orig[0] + vb[0]*cs; + const float by = orig[1] + (vb[1]+1+(i&1))*ch; + const float bz = orig[2] + vb[2]*cs; + + const float cx = (ax+bx)*0.5f; + const float cy = (ay+by)*0.5f; + const float cz = (az+bz)*0.5f; + + int d = p[nvp+j] & 0xf; + + const float dx = cx + offs[d*2+0]*2*cs; + const float dy = cy; + const float dz = cz + offs[d*2+1]*2*cs; + + dd->vertex(cx,cy,cz,duRGBA(255,0,0,255)); + dd->vertex(dx,dy,dz,duRGBA(255,0,0,255)); + + col = duRGBA(255,255,255,128); + } + + for (int k = 0; k < 2; ++k) + { + const unsigned short* v = &lmesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x, y, z, col); + } + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 3.0f); + const unsigned int colv = duRGBA(0,0,0,220); + for (int i = 0; i < lmesh.nverts; ++i) + { + const unsigned short* v = &lmesh.verts[i*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x,y,z, colv); + } + dd->end(); +} +*/ + +static void getContourCenter(const rcContour* cont, const float* orig, float cs, float ch, float* center) +{ + center[0] = 0; + center[1] = 0; + center[2] = 0; + if (!cont->nverts) + return; + for (int i = 0; i < cont->nverts; ++i) + { + const int* v = &cont->verts[i*4]; + center[0] += (float)v[0]; + center[1] += (float)v[1]; + center[2] += (float)v[2]; + } + const float s = 1.0f / cont->nverts; + center[0] *= s * cs; + center[1] *= s * ch; + center[2] *= s * cs; + center[0] += orig[0]; + center[1] += orig[1] + 4*ch; + center[2] += orig[2]; +} + +static const rcContour* findContourFromSet(const rcContourSet& cset, unsigned short reg) +{ + for (int i = 0; i < cset.nconts; ++i) + { + if (cset.conts[i].reg == reg) + return &cset.conts[i]; + } + return 0; +} + +void duDebugDrawRegionConnections(duDebugDraw* dd, const rcContourSet& cset, const float alpha) +{ + if (!dd) return; + + const float* orig = cset.bmin; + const float cs = cset.cs; + const float ch = cset.ch; + + // Draw centers + float pos[3], pos2[3]; + + unsigned int color = duRGBA(0,0,0,196); + + dd->begin(DU_DRAW_LINES, 2.0f); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour* cont = &cset.conts[i]; + getContourCenter(cont, orig, cs, ch, pos); + for (int j = 0; j < cont->nverts; ++j) + { + const int* v = &cont->verts[j*4]; + if (v[3] == 0 || (unsigned short)v[3] < cont->reg) continue; + const rcContour* cont2 = findContourFromSet(cset, (unsigned short)v[3]); + if (cont2) + { + getContourCenter(cont2, orig, cs, ch, pos2); + duAppendArc(dd, pos[0],pos[1],pos[2], pos2[0],pos2[1],pos2[2], 0.25f, 0.6f, 0.6f, color); + } + } + } + + dd->end(); + + unsigned char a = (unsigned char)(alpha * 255.0f); + + dd->begin(DU_DRAW_POINTS, 7.0f); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour* cont = &cset.conts[i]; + unsigned int col = duDarkenCol(duIntToCol(cont->reg,a)); + getContourCenter(cont, orig, cs, ch, pos); + dd->vertex(pos, col); + } + dd->end(); +} + +void duDebugDrawRawContours(duDebugDraw* dd, const rcContourSet& cset, const float alpha) +{ + if (!dd) return; + + const float* orig = cset.bmin; + const float cs = cset.cs; + const float ch = cset.ch; + + const unsigned char a = (unsigned char)(alpha*255.0f); + + dd->begin(DU_DRAW_LINES, 2.0f); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour& c = cset.conts[i]; + unsigned int color = duIntToCol(c.reg, a); + + for (int j = 0; j < c.nrverts; ++j) + { + const int* v = &c.rverts[j*4]; + float fx = orig[0] + v[0]*cs; + float fy = orig[1] + (v[1]+1+(i&1))*ch; + float fz = orig[2] + v[2]*cs; + dd->vertex(fx,fy,fz,color); + if (j > 0) + dd->vertex(fx,fy,fz,color); + } + // Loop last segment. + const int* v = &c.rverts[0]; + float fx = orig[0] + v[0]*cs; + float fy = orig[1] + (v[1]+1+(i&1))*ch; + float fz = orig[2] + v[2]*cs; + dd->vertex(fx,fy,fz,color); + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 2.0f); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour& c = cset.conts[i]; + unsigned int color = duDarkenCol(duIntToCol(c.reg, a)); + + for (int j = 0; j < c.nrverts; ++j) + { + const int* v = &c.rverts[j*4]; + float off = 0; + unsigned int colv = color; + if (v[3] & RC_BORDER_VERTEX) + { + colv = duRGBA(255,255,255,a); + off = ch*2; + } + + float fx = orig[0] + v[0]*cs; + float fy = orig[1] + (v[1]+1+(i&1))*ch + off; + float fz = orig[2] + v[2]*cs; + dd->vertex(fx,fy,fz, colv); + } + } + dd->end(); +} + +void duDebugDrawContours(duDebugDraw* dd, const rcContourSet& cset, const float alpha) +{ + if (!dd) return; + + const float* orig = cset.bmin; + const float cs = cset.cs; + const float ch = cset.ch; + + const unsigned char a = (unsigned char)(alpha*255.0f); + + dd->begin(DU_DRAW_LINES, 2.5f); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour& c = cset.conts[i]; + if (!c.nverts) + continue; + const unsigned int color = duIntToCol(c.reg, a); + const unsigned int bcolor = duLerpCol(color,duRGBA(255,255,255,a),128); + for (int j = 0, k = c.nverts-1; j < c.nverts; k=j++) + { + const int* va = &c.verts[k*4]; + const int* vb = &c.verts[j*4]; + unsigned int col = (va[3] & RC_AREA_BORDER) ? bcolor : color; + float fx,fy,fz; + fx = orig[0] + va[0]*cs; + fy = orig[1] + (va[1]+1+(i&1))*ch; + fz = orig[2] + va[2]*cs; + dd->vertex(fx,fy,fz, col); + fx = orig[0] + vb[0]*cs; + fy = orig[1] + (vb[1]+1+(i&1))*ch; + fz = orig[2] + vb[2]*cs; + dd->vertex(fx,fy,fz, col); + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 3.0f); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour& c = cset.conts[i]; + unsigned int color = duDarkenCol(duIntToCol(c.reg, a)); + for (int j = 0; j < c.nverts; ++j) + { + const int* v = &c.verts[j*4]; + float off = 0; + unsigned int colv = color; + if (v[3] & RC_BORDER_VERTEX) + { + colv = duRGBA(255,255,255,a); + off = ch*2; + } + + float fx = orig[0] + v[0]*cs; + float fy = orig[1] + (v[1]+1+(i&1))*ch + off; + float fz = orig[2] + v[2]*cs; + dd->vertex(fx,fy,fz, colv); + } + } + dd->end(); +} + +void duDebugDrawPolyMesh(duDebugDraw* dd, const struct rcPolyMesh& mesh) +{ + if (!dd) return; + + const int nvp = mesh.nvp; + const float cs = mesh.cs; + const float ch = mesh.ch; + const float* orig = mesh.bmin; + + dd->begin(DU_DRAW_TRIS); + + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + const unsigned char area = mesh.areas[i]; + + unsigned int color; + if (area == RC_WALKABLE_AREA) + color = duRGBA(0,192,255,64); + else if (area == RC_NULL_AREA) + color = duRGBA(0,0,0,64); + else + color = dd->areaToCol(area); + + unsigned short vi[3]; + for (int j = 2; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + vi[0] = p[0]; + vi[1] = p[j-1]; + vi[2] = p[j]; + for (int k = 0; k < 3; ++k) + { + const unsigned short* v = &mesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch; + const float z = orig[2] + v[2]*cs; + dd->vertex(x,y,z, color); + } + } + } + dd->end(); + + // Draw neighbours edges + const unsigned int coln = duRGBA(0,48,64,32); + dd->begin(DU_DRAW_LINES, 1.5f); + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + if (p[nvp+j] & 0x8000) continue; + const int nj = (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX) ? 0 : j+1; + const int vi[2] = {p[j], p[nj]}; + + for (int k = 0; k < 2; ++k) + { + const unsigned short* v = &mesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x, y, z, coln); + } + } + } + dd->end(); + + // Draw boundary edges + const unsigned int colb = duRGBA(0,48,64,220); + dd->begin(DU_DRAW_LINES, 2.5f); + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + if ((p[nvp+j] & 0x8000) == 0) continue; + const int nj = (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX) ? 0 : j+1; + const int vi[2] = {p[j], p[nj]}; + + unsigned int col = colb; + if ((p[nvp+j] & 0xf) != 0xf) + col = duRGBA(255,255,255,128); + for (int k = 0; k < 2; ++k) + { + const unsigned short* v = &mesh.verts[vi[k]*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x, y, z, col); + } + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 3.0f); + const unsigned int colv = duRGBA(0,0,0,220); + for (int i = 0; i < mesh.nverts; ++i) + { + const unsigned short* v = &mesh.verts[i*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + dd->vertex(x,y,z, colv); + } + dd->end(); +} + +void duDebugDrawPolyMeshDetail(duDebugDraw* dd, const struct rcPolyMeshDetail& dmesh) +{ + if (!dd) return; + + dd->begin(DU_DRAW_TRIS); + + for (int i = 0; i < dmesh.nmeshes; ++i) + { + const unsigned int* m = &dmesh.meshes[i*4]; + const unsigned int bverts = m[0]; + const unsigned int btris = m[2]; + const int ntris = (int)m[3]; + const float* verts = &dmesh.verts[bverts*3]; + const unsigned char* tris = &dmesh.tris[btris*4]; + + unsigned int color = duIntToCol(i, 192); + + for (int j = 0; j < ntris; ++j) + { + dd->vertex(&verts[tris[j*4+0]*3], color); + dd->vertex(&verts[tris[j*4+1]*3], color); + dd->vertex(&verts[tris[j*4+2]*3], color); + } + } + dd->end(); + + // Internal edges. + dd->begin(DU_DRAW_LINES, 1.0f); + const unsigned int coli = duRGBA(0,0,0,64); + for (int i = 0; i < dmesh.nmeshes; ++i) + { + const unsigned int* m = &dmesh.meshes[i*4]; + const unsigned int bverts = m[0]; + const unsigned int btris = m[2]; + const int ntris = (int)m[3]; + const float* verts = &dmesh.verts[bverts*3]; + const unsigned char* tris = &dmesh.tris[btris*4]; + + for (int j = 0; j < ntris; ++j) + { + const unsigned char* t = &tris[j*4]; + for (int k = 0, kp = 2; k < 3; kp=k++) + { + unsigned char ef = (t[3] >> (kp*2)) & 0x3; + if (ef == 0) + { + // Internal edge + if (t[kp] < t[k]) + { + dd->vertex(&verts[t[kp]*3], coli); + dd->vertex(&verts[t[k]*3], coli); + } + } + } + } + } + dd->end(); + + // External edges. + dd->begin(DU_DRAW_LINES, 2.0f); + const unsigned int cole = duRGBA(0,0,0,64); + for (int i = 0; i < dmesh.nmeshes; ++i) + { + const unsigned int* m = &dmesh.meshes[i*4]; + const unsigned int bverts = m[0]; + const unsigned int btris = m[2]; + const int ntris = (int)m[3]; + const float* verts = &dmesh.verts[bverts*3]; + const unsigned char* tris = &dmesh.tris[btris*4]; + + for (int j = 0; j < ntris; ++j) + { + const unsigned char* t = &tris[j*4]; + for (int k = 0, kp = 2; k < 3; kp=k++) + { + unsigned char ef = (t[3] >> (kp*2)) & 0x3; + if (ef != 0) + { + // Ext edge + dd->vertex(&verts[t[kp]*3], cole); + dd->vertex(&verts[t[k]*3], cole); + } + } + } + } + dd->end(); + + dd->begin(DU_DRAW_POINTS, 3.0f); + const unsigned int colv = duRGBA(0,0,0,64); + for (int i = 0; i < dmesh.nmeshes; ++i) + { + const unsigned int* m = &dmesh.meshes[i*4]; + const unsigned int bverts = m[0]; + const int nverts = (int)m[1]; + const float* verts = &dmesh.verts[bverts*3]; + for (int j = 0; j < nverts; ++j) + dd->vertex(&verts[j*3], colv); + } + dd->end(); +} diff --git a/libs/recast/debug_utils/src/RecastDump.cpp b/libs/recast/debug_utils/src/RecastDump.cpp new file mode 100644 index 000000000..209382515 --- /dev/null +++ b/libs/recast/debug_utils/src/RecastDump.cpp @@ -0,0 +1,451 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastDump.h" + + +duFileIO::~duFileIO() +{ + // Empty +} + +static void ioprintf(duFileIO* io, const char* format, ...) +{ + char line[256]; + va_list ap; + va_start(ap, format); + const int n = vsnprintf(line, sizeof(line), format, ap); + va_end(ap); + if (n > 0) + io->write(line, sizeof(char)*n); +} + +bool duDumpPolyMeshToObj(rcPolyMesh& pmesh, duFileIO* io) +{ + if (!io) + { + printf("duDumpPolyMeshToObj: input IO is null.\n"); + return false; + } + if (!io->isWriting()) + { + printf("duDumpPolyMeshToObj: input IO not writing.\n"); + return false; + } + + const int nvp = pmesh.nvp; + const float cs = pmesh.cs; + const float ch = pmesh.ch; + const float* orig = pmesh.bmin; + + ioprintf(io, "# Recast Navmesh\n"); + ioprintf(io, "o NavMesh\n"); + + ioprintf(io, "\n"); + + for (int i = 0; i < pmesh.nverts; ++i) + { + const unsigned short* v = &pmesh.verts[i*3]; + const float x = orig[0] + v[0]*cs; + const float y = orig[1] + (v[1]+1)*ch + 0.1f; + const float z = orig[2] + v[2]*cs; + ioprintf(io, "v %f %f %f\n", x,y,z); + } + + ioprintf(io, "\n"); + + for (int i = 0; i < pmesh.npolys; ++i) + { + const unsigned short* p = &pmesh.polys[i*nvp*2]; + for (int j = 2; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + ioprintf(io, "f %d %d %d\n", p[0]+1, p[j-1]+1, p[j]+1); + } + } + + return true; +} + +bool duDumpPolyMeshDetailToObj(rcPolyMeshDetail& dmesh, duFileIO* io) +{ + if (!io) + { + printf("duDumpPolyMeshDetailToObj: input IO is null.\n"); + return false; + } + if (!io->isWriting()) + { + printf("duDumpPolyMeshDetailToObj: input IO not writing.\n"); + return false; + } + + ioprintf(io, "# Recast Navmesh\n"); + ioprintf(io, "o NavMesh\n"); + + ioprintf(io, "\n"); + + for (int i = 0; i < dmesh.nverts; ++i) + { + const float* v = &dmesh.verts[i*3]; + ioprintf(io, "v %f %f %f\n", v[0],v[1],v[2]); + } + + ioprintf(io, "\n"); + + for (int i = 0; i < dmesh.nmeshes; ++i) + { + const unsigned int* m = &dmesh.meshes[i*4]; + const unsigned int bverts = m[0]; + const unsigned int btris = m[2]; + const unsigned int ntris = m[3]; + const unsigned char* tris = &dmesh.tris[btris*4]; + for (unsigned int j = 0; j < ntris; ++j) + { + ioprintf(io, "f %d %d %d\n", + (int)(bverts+tris[j*4+0])+1, + (int)(bverts+tris[j*4+1])+1, + (int)(bverts+tris[j*4+2])+1); + } + } + + return true; +} + +static const int CSET_MAGIC = ('c' << 24) | ('s' << 16) | ('e' << 8) | 't'; +static const int CSET_VERSION = 2; + +bool duDumpContourSet(struct rcContourSet& cset, duFileIO* io) +{ + if (!io) + { + printf("duDumpContourSet: input IO is null.\n"); + return false; + } + if (!io->isWriting()) + { + printf("duDumpContourSet: input IO not writing.\n"); + return false; + } + + io->write(&CSET_MAGIC, sizeof(CSET_MAGIC)); + io->write(&CSET_VERSION, sizeof(CSET_VERSION)); + + io->write(&cset.nconts, sizeof(cset.nconts)); + + io->write(cset.bmin, sizeof(cset.bmin)); + io->write(cset.bmax, sizeof(cset.bmax)); + + io->write(&cset.cs, sizeof(cset.cs)); + io->write(&cset.ch, sizeof(cset.ch)); + + io->write(&cset.width, sizeof(cset.width)); + io->write(&cset.height, sizeof(cset.height)); + io->write(&cset.borderSize, sizeof(cset.borderSize)); + + for (int i = 0; i < cset.nconts; ++i) + { + const rcContour& cont = cset.conts[i]; + io->write(&cont.nverts, sizeof(cont.nverts)); + io->write(&cont.nrverts, sizeof(cont.nrverts)); + io->write(&cont.reg, sizeof(cont.reg)); + io->write(&cont.area, sizeof(cont.area)); + io->write(cont.verts, sizeof(int)*4*cont.nverts); + io->write(cont.rverts, sizeof(int)*4*cont.nrverts); + } + + return true; +} + +bool duReadContourSet(struct rcContourSet& cset, duFileIO* io) +{ + if (!io) + { + printf("duReadContourSet: input IO is null.\n"); + return false; + } + if (!io->isReading()) + { + printf("duReadContourSet: input IO not reading.\n"); + return false; + } + + int magic = 0; + int version = 0; + + io->read(&magic, sizeof(magic)); + io->read(&version, sizeof(version)); + + if (magic != CSET_MAGIC) + { + printf("duReadContourSet: Bad voodoo.\n"); + return false; + } + if (version != CSET_VERSION) + { + printf("duReadContourSet: Bad version.\n"); + return false; + } + + io->read(&cset.nconts, sizeof(cset.nconts)); + + cset.conts = (rcContour*)rcAlloc(sizeof(rcContour)*cset.nconts, RC_ALLOC_PERM); + if (!cset.conts) + { + printf("duReadContourSet: Could not alloc contours (%d)\n", cset.nconts); + return false; + } + memset(cset.conts, 0, sizeof(rcContour)*cset.nconts); + + io->read(cset.bmin, sizeof(cset.bmin)); + io->read(cset.bmax, sizeof(cset.bmax)); + + io->read(&cset.cs, sizeof(cset.cs)); + io->read(&cset.ch, sizeof(cset.ch)); + + io->read(&cset.width, sizeof(cset.width)); + io->read(&cset.height, sizeof(cset.height)); + io->read(&cset.borderSize, sizeof(cset.borderSize)); + + for (int i = 0; i < cset.nconts; ++i) + { + rcContour& cont = cset.conts[i]; + io->read(&cont.nverts, sizeof(cont.nverts)); + io->read(&cont.nrverts, sizeof(cont.nrverts)); + io->read(&cont.reg, sizeof(cont.reg)); + io->read(&cont.area, sizeof(cont.area)); + + cont.verts = (int*)rcAlloc(sizeof(int)*4*cont.nverts, RC_ALLOC_PERM); + if (!cont.verts) + { + printf("duReadContourSet: Could not alloc contour verts (%d)\n", cont.nverts); + return false; + } + cont.rverts = (int*)rcAlloc(sizeof(int)*4*cont.nrverts, RC_ALLOC_PERM); + if (!cont.rverts) + { + printf("duReadContourSet: Could not alloc contour rverts (%d)\n", cont.nrverts); + return false; + } + + io->read(cont.verts, sizeof(int)*4*cont.nverts); + io->read(cont.rverts, sizeof(int)*4*cont.nrverts); + } + + return true; +} + + +static const int CHF_MAGIC = ('r' << 24) | ('c' << 16) | ('h' << 8) | 'f'; +static const int CHF_VERSION = 3; + +bool duDumpCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io) +{ + if (!io) + { + printf("duDumpCompactHeightfield: input IO is null.\n"); + return false; + } + if (!io->isWriting()) + { + printf("duDumpCompactHeightfield: input IO not writing.\n"); + return false; + } + + io->write(&CHF_MAGIC, sizeof(CHF_MAGIC)); + io->write(&CHF_VERSION, sizeof(CHF_VERSION)); + + io->write(&chf.width, sizeof(chf.width)); + io->write(&chf.height, sizeof(chf.height)); + io->write(&chf.spanCount, sizeof(chf.spanCount)); + + io->write(&chf.walkableHeight, sizeof(chf.walkableHeight)); + io->write(&chf.walkableClimb, sizeof(chf.walkableClimb)); + io->write(&chf.borderSize, sizeof(chf.borderSize)); + + io->write(&chf.maxDistance, sizeof(chf.maxDistance)); + io->write(&chf.maxRegions, sizeof(chf.maxRegions)); + + io->write(chf.bmin, sizeof(chf.bmin)); + io->write(chf.bmax, sizeof(chf.bmax)); + + io->write(&chf.cs, sizeof(chf.cs)); + io->write(&chf.ch, sizeof(chf.ch)); + + int tmp = 0; + if (chf.cells) tmp |= 1; + if (chf.spans) tmp |= 2; + if (chf.dist) tmp |= 4; + if (chf.areas) tmp |= 8; + + io->write(&tmp, sizeof(tmp)); + + if (chf.cells) + io->write(chf.cells, sizeof(rcCompactCell)*chf.width*chf.height); + if (chf.spans) + io->write(chf.spans, sizeof(rcCompactSpan)*chf.spanCount); + if (chf.dist) + io->write(chf.dist, sizeof(unsigned short)*chf.spanCount); + if (chf.areas) + io->write(chf.areas, sizeof(unsigned char)*chf.spanCount); + + return true; +} + +bool duReadCompactHeightfield(struct rcCompactHeightfield& chf, duFileIO* io) +{ + if (!io) + { + printf("duReadCompactHeightfield: input IO is null.\n"); + return false; + } + if (!io->isReading()) + { + printf("duReadCompactHeightfield: input IO not reading.\n"); + return false; + } + + int magic = 0; + int version = 0; + + io->read(&magic, sizeof(magic)); + io->read(&version, sizeof(version)); + + if (magic != CHF_MAGIC) + { + printf("duReadCompactHeightfield: Bad voodoo.\n"); + return false; + } + if (version != CHF_VERSION) + { + printf("duReadCompactHeightfield: Bad version.\n"); + return false; + } + + io->read(&chf.width, sizeof(chf.width)); + io->read(&chf.height, sizeof(chf.height)); + io->read(&chf.spanCount, sizeof(chf.spanCount)); + + io->read(&chf.walkableHeight, sizeof(chf.walkableHeight)); + io->read(&chf.walkableClimb, sizeof(chf.walkableClimb)); + io->read(&chf.borderSize, sizeof(chf.borderSize)); + + io->read(&chf.maxDistance, sizeof(chf.maxDistance)); + io->read(&chf.maxRegions, sizeof(chf.maxRegions)); + + io->read(chf.bmin, sizeof(chf.bmin)); + io->read(chf.bmax, sizeof(chf.bmax)); + + io->read(&chf.cs, sizeof(chf.cs)); + io->read(&chf.ch, sizeof(chf.ch)); + + int tmp = 0; + io->read(&tmp, sizeof(tmp)); + + if (tmp & 1) + { + chf.cells = (rcCompactCell*)rcAlloc(sizeof(rcCompactCell)*chf.width*chf.height, RC_ALLOC_PERM); + if (!chf.cells) + { + printf("duReadCompactHeightfield: Could not alloc cells (%d)\n", chf.width*chf.height); + return false; + } + io->read(chf.cells, sizeof(rcCompactCell)*chf.width*chf.height); + } + if (tmp & 2) + { + chf.spans = (rcCompactSpan*)rcAlloc(sizeof(rcCompactSpan)*chf.spanCount, RC_ALLOC_PERM); + if (!chf.spans) + { + printf("duReadCompactHeightfield: Could not alloc spans (%d)\n", chf.spanCount); + return false; + } + io->read(chf.spans, sizeof(rcCompactSpan)*chf.spanCount); + } + if (tmp & 4) + { + chf.dist = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_PERM); + if (!chf.dist) + { + printf("duReadCompactHeightfield: Could not alloc dist (%d)\n", chf.spanCount); + return false; + } + io->read(chf.dist, sizeof(unsigned short)*chf.spanCount); + } + if (tmp & 8) + { + chf.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_PERM); + if (!chf.areas) + { + printf("duReadCompactHeightfield: Could not alloc areas (%d)\n", chf.spanCount); + return false; + } + io->read(chf.areas, sizeof(unsigned char)*chf.spanCount); + } + + return true; +} + + +static void logLine(rcContext& ctx, rcTimerLabel label, const char* name, const float pc) +{ + const int t = ctx.getAccumulatedTime(label); + if (t < 0) return; + ctx.log(RC_LOG_PROGRESS, "%s:\t%.2fms\t(%.1f%%)", name, t/1000.0f, t*pc); +} + +void duLogBuildTimes(rcContext& ctx, const int totalTimeUsec) +{ + const float pc = 100.0f / totalTimeUsec; + + ctx.log(RC_LOG_PROGRESS, "Build Times"); + logLine(ctx, RC_TIMER_RASTERIZE_TRIANGLES, "- Rasterize", pc); + logLine(ctx, RC_TIMER_BUILD_COMPACTHEIGHTFIELD, "- Build Compact", pc); + logLine(ctx, RC_TIMER_FILTER_BORDER, "- Filter Border", pc); + logLine(ctx, RC_TIMER_FILTER_WALKABLE, "- Filter Walkable", pc); + logLine(ctx, RC_TIMER_ERODE_AREA, "- Erode Area", pc); + logLine(ctx, RC_TIMER_MEDIAN_AREA, "- Median Area", pc); + logLine(ctx, RC_TIMER_MARK_BOX_AREA, "- Mark Box Area", pc); + logLine(ctx, RC_TIMER_MARK_CONVEXPOLY_AREA, "- Mark Convex Area", pc); + logLine(ctx, RC_TIMER_MARK_CYLINDER_AREA, "- Mark Cylinder Area", pc); + logLine(ctx, RC_TIMER_BUILD_DISTANCEFIELD, "- Build Distance Field", pc); + logLine(ctx, RC_TIMER_BUILD_DISTANCEFIELD_DIST, " - Distance", pc); + logLine(ctx, RC_TIMER_BUILD_DISTANCEFIELD_BLUR, " - Blur", pc); + logLine(ctx, RC_TIMER_BUILD_REGIONS, "- Build Regions", pc); + logLine(ctx, RC_TIMER_BUILD_REGIONS_WATERSHED, " - Watershed", pc); + logLine(ctx, RC_TIMER_BUILD_REGIONS_EXPAND, " - Expand", pc); + logLine(ctx, RC_TIMER_BUILD_REGIONS_FLOOD, " - Find Basins", pc); + logLine(ctx, RC_TIMER_BUILD_REGIONS_FILTER, " - Filter", pc); + logLine(ctx, RC_TIMER_BUILD_LAYERS, "- Build Layers", pc); + logLine(ctx, RC_TIMER_BUILD_CONTOURS, "- Build Contours", pc); + logLine(ctx, RC_TIMER_BUILD_CONTOURS_TRACE, " - Trace", pc); + logLine(ctx, RC_TIMER_BUILD_CONTOURS_SIMPLIFY, " - Simplify", pc); + logLine(ctx, RC_TIMER_BUILD_POLYMESH, "- Build Polymesh", pc); + logLine(ctx, RC_TIMER_BUILD_POLYMESHDETAIL, "- Build Polymesh Detail", pc); + logLine(ctx, RC_TIMER_MERGE_POLYMESH, "- Merge Polymeshes", pc); + logLine(ctx, RC_TIMER_MERGE_POLYMESHDETAIL, "- Merge Polymesh Details", pc); + ctx.log(RC_LOG_PROGRESS, "=== TOTAL:\t%.2fms", totalTimeUsec/1000.0f); +} + diff --git a/libs/recast/detour/include/DetourAlloc.h b/libs/recast/detour/include/DetourAlloc.h new file mode 100644 index 000000000..f87b454ac --- /dev/null +++ b/libs/recast/detour/include/DetourAlloc.h @@ -0,0 +1,61 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURALLOCATOR_H +#define DETOURALLOCATOR_H + +#include + +/// Provides hint values to the memory allocator on how long the +/// memory is expected to be used. +enum dtAllocHint +{ + DT_ALLOC_PERM, ///< Memory persist after a function call. + DT_ALLOC_TEMP ///< Memory used temporarily within a function. +}; + +/// A memory allocation function. +// @param[in] size The size, in bytes of memory, to allocate. +// @param[in] rcAllocHint A hint to the allocator on how long the memory is expected to be in use. +// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed. +/// @see dtAllocSetCustom +typedef void* (dtAllocFunc)(size_t size, dtAllocHint hint); + +/// A memory deallocation function. +/// @param[in] ptr A pointer to a memory block previously allocated using #dtAllocFunc. +/// @see dtAllocSetCustom +typedef void (dtFreeFunc)(void* ptr); + +/// Sets the base custom allocation functions to be used by Detour. +/// @param[in] allocFunc The memory allocation function to be used by #dtAlloc +/// @param[in] freeFunc The memory de-allocation function to be used by #dtFree +void dtAllocSetCustom(dtAllocFunc *allocFunc, dtFreeFunc *freeFunc); + +/// Allocates a memory block. +/// @param[in] size The size, in bytes of memory, to allocate. +/// @param[in] hint A hint to the allocator on how long the memory is expected to be in use. +/// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed. +/// @see dtFree +void* dtAlloc(size_t size, dtAllocHint hint); + +/// Deallocates a memory block. +/// @param[in] ptr A pointer to a memory block previously allocated using #dtAlloc. +/// @see dtAlloc +void dtFree(void* ptr); + +#endif diff --git a/libs/recast/detour/include/DetourAssert.h b/libs/recast/detour/include/DetourAssert.h new file mode 100644 index 000000000..e05fd66fa --- /dev/null +++ b/libs/recast/detour/include/DetourAssert.h @@ -0,0 +1,56 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURASSERT_H +#define DETOURASSERT_H + +// Note: This header file's only purpose is to include define assert. +// Feel free to change the file and include your own implementation instead. + +#ifdef NDEBUG + +// From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ +# define dtAssert(x) do { (void)sizeof(x); } while((void)(__LINE__==-1),false) + +#else + +/// An assertion failure function. +// @param[in] expression asserted expression. +// @param[in] file Filename of the failed assertion. +// @param[in] line Line number of the failed assertion. +/// @see dtAssertFailSetCustom +typedef void (dtAssertFailFunc)(const char* expression, const char* file, int line); + +/// Sets the base custom assertion failure function to be used by Detour. +/// @param[in] assertFailFunc The function to be invoked in case of failure of #dtAssert +void dtAssertFailSetCustom(dtAssertFailFunc *assertFailFunc); + +/// Gets the base custom assertion failure function to be used by Detour. +dtAssertFailFunc* dtAssertFailGetCustom(); + +# include +# define dtAssert(expression) \ + { \ + dtAssertFailFunc* failFunc = dtAssertFailGetCustom(); \ + if(failFunc == NULL) { assert(expression); } \ + else if(!(expression)) { (*failFunc)(#expression, __FILE__, __LINE__); } \ + } + +#endif + +#endif // DETOURASSERT_H diff --git a/libs/recast/detour/include/DetourCommon.h b/libs/recast/detour/include/DetourCommon.h new file mode 100644 index 000000000..739858cd9 --- /dev/null +++ b/libs/recast/detour/include/DetourCommon.h @@ -0,0 +1,550 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURCOMMON_H +#define DETOURCOMMON_H + +#include "DetourMath.h" +#include + +/** +@defgroup detour Detour + +Members in this module are used to create, manipulate, and query navigation +meshes. + +@note This is a summary list of members. Use the index or search +feature to find minor members. +*/ + +/// @name General helper functions +/// @{ + +/// Used to ignore a function parameter. VS complains about unused parameters +/// and this silences the warning. +/// @param [in] _ Unused parameter +template void dtIgnoreUnused(const T&) { } + +/// Swaps the values of the two parameters. +/// @param[in,out] a Value A +/// @param[in,out] b Value B +template inline void dtSwap(T& a, T& b) { T t = a; a = b; b = t; } + +/// Returns the minimum of two values. +/// @param[in] a Value A +/// @param[in] b Value B +/// @return The minimum of the two values. +template inline T dtMin(T a, T b) { return a < b ? a : b; } + +/// Returns the maximum of two values. +/// @param[in] a Value A +/// @param[in] b Value B +/// @return The maximum of the two values. +template inline T dtMax(T a, T b) { return a > b ? a : b; } + +/// Returns the absolute value. +/// @param[in] a The value. +/// @return The absolute value of the specified value. +template inline T dtAbs(T a) { return a < 0 ? -a : a; } + +/// Returns the square of the value. +/// @param[in] a The value. +/// @return The square of the value. +template inline T dtSqr(T a) { return a*a; } + +/// Clamps the value to the specified range. +/// @param[in] v The value to clamp. +/// @param[in] mn The minimum permitted return value. +/// @param[in] mx The maximum permitted return value. +/// @return The value, clamped to the specified range. +template inline T dtClamp(T v, T mn, T mx) { return v < mn ? mn : (v > mx ? mx : v); } + +/// @} +/// @name Vector helper functions. +/// @{ + +/// Derives the cross product of two vectors. (@p v1 x @p v2) +/// @param[out] dest The cross product. [(x, y, z)] +/// @param[in] v1 A Vector [(x, y, z)] +/// @param[in] v2 A vector [(x, y, z)] +inline void dtVcross(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[1]*v2[2] - v1[2]*v2[1]; + dest[1] = v1[2]*v2[0] - v1[0]*v2[2]; + dest[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +/// Derives the dot product of two vectors. (@p v1 . @p v2) +/// @param[in] v1 A Vector [(x, y, z)] +/// @param[in] v2 A vector [(x, y, z)] +/// @return The dot product. +inline float dtVdot(const float* v1, const float* v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +/// Performs a scaled vector addition. (@p v1 + (@p v2 * @p s)) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector. [(x, y, z)] +/// @param[in] v2 The vector to scale and add to @p v1. [(x, y, z)] +/// @param[in] s The amount to scale @p v2 by before adding to @p v1. +inline void dtVmad(float* dest, const float* v1, const float* v2, const float s) +{ + dest[0] = v1[0]+v2[0]*s; + dest[1] = v1[1]+v2[1]*s; + dest[2] = v1[2]+v2[2]*s; +} + +/// Performs a linear interpolation between two vectors. (@p v1 toward @p v2) +/// @param[out] dest The result vector. [(x, y, x)] +/// @param[in] v1 The starting vector. +/// @param[in] v2 The destination vector. +/// @param[in] t The interpolation factor. [Limits: 0 <= value <= 1.0] +inline void dtVlerp(float* dest, const float* v1, const float* v2, const float t) +{ + dest[0] = v1[0]+(v2[0]-v1[0])*t; + dest[1] = v1[1]+(v2[1]-v1[1])*t; + dest[2] = v1[2]+(v2[2]-v1[2])*t; +} + +/// Performs a vector addition. (@p v1 + @p v2) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector. [(x, y, z)] +/// @param[in] v2 The vector to add to @p v1. [(x, y, z)] +inline void dtVadd(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[0]+v2[0]; + dest[1] = v1[1]+v2[1]; + dest[2] = v1[2]+v2[2]; +} + +/// Performs a vector subtraction. (@p v1 - @p v2) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector. [(x, y, z)] +/// @param[in] v2 The vector to subtract from @p v1. [(x, y, z)] +inline void dtVsub(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[0]-v2[0]; + dest[1] = v1[1]-v2[1]; + dest[2] = v1[2]-v2[2]; +} + +/// Scales the vector by the specified value. (@p v * @p t) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v The vector to scale. [(x, y, z)] +/// @param[in] t The scaling factor. +inline void dtVscale(float* dest, const float* v, const float t) +{ + dest[0] = v[0]*t; + dest[1] = v[1]*t; + dest[2] = v[2]*t; +} + +/// Selects the minimum value of each element from the specified vectors. +/// @param[in,out] mn A vector. (Will be updated with the result.) [(x, y, z)] +/// @param[in] v A vector. [(x, y, z)] +inline void dtVmin(float* mn, const float* v) +{ + mn[0] = dtMin(mn[0], v[0]); + mn[1] = dtMin(mn[1], v[1]); + mn[2] = dtMin(mn[2], v[2]); +} + +/// Selects the maximum value of each element from the specified vectors. +/// @param[in,out] mx A vector. (Will be updated with the result.) [(x, y, z)] +/// @param[in] v A vector. [(x, y, z)] +inline void dtVmax(float* mx, const float* v) +{ + mx[0] = dtMax(mx[0], v[0]); + mx[1] = dtMax(mx[1], v[1]); + mx[2] = dtMax(mx[2], v[2]); +} + +/// Sets the vector elements to the specified values. +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] x The x-value of the vector. +/// @param[in] y The y-value of the vector. +/// @param[in] z The z-value of the vector. +inline void dtVset(float* dest, const float x, const float y, const float z) +{ + dest[0] = x; dest[1] = y; dest[2] = z; +} + +/// Performs a vector copy. +/// @param[out] dest The result. [(x, y, z)] +/// @param[in] a The vector to copy. [(x, y, z)] +inline void dtVcopy(float* dest, const float* a) +{ + dest[0] = a[0]; + dest[1] = a[1]; + dest[2] = a[2]; +} + +/// Derives the scalar length of the vector. +/// @param[in] v The vector. [(x, y, z)] +/// @return The scalar length of the vector. +inline float dtVlen(const float* v) +{ + return dtMathSqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +/// Derives the square of the scalar length of the vector. (len * len) +/// @param[in] v The vector. [(x, y, z)] +/// @return The square of the scalar length of the vector. +inline float dtVlenSqr(const float* v) +{ + return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; +} + +/// Returns the distance between two points. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The distance between the two points. +inline float dtVdist(const float* v1, const float* v2) +{ + const float dx = v2[0] - v1[0]; + const float dy = v2[1] - v1[1]; + const float dz = v2[2] - v1[2]; + return dtMathSqrtf(dx*dx + dy*dy + dz*dz); +} + +/// Returns the square of the distance between two points. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The square of the distance between the two points. +inline float dtVdistSqr(const float* v1, const float* v2) +{ + const float dx = v2[0] - v1[0]; + const float dy = v2[1] - v1[1]; + const float dz = v2[2] - v1[2]; + return dx*dx + dy*dy + dz*dz; +} + +/// Derives the distance between the specified points on the xz-plane. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The distance between the point on the xz-plane. +/// +/// The vectors are projected onto the xz-plane, so the y-values are ignored. +inline float dtVdist2D(const float* v1, const float* v2) +{ + const float dx = v2[0] - v1[0]; + const float dz = v2[2] - v1[2]; + return dtMathSqrtf(dx*dx + dz*dz); +} + +/// Derives the square of the distance between the specified points on the xz-plane. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The square of the distance between the point on the xz-plane. +inline float dtVdist2DSqr(const float* v1, const float* v2) +{ + const float dx = v2[0] - v1[0]; + const float dz = v2[2] - v1[2]; + return dx*dx + dz*dz; +} + +/// Normalizes the vector. +/// @param[in,out] v The vector to normalize. [(x, y, z)] +inline void dtVnormalize(float* v) +{ + float d = 1.0f / dtMathSqrtf(dtSqr(v[0]) + dtSqr(v[1]) + dtSqr(v[2])); + v[0] *= d; + v[1] *= d; + v[2] *= d; +} + +/// Performs a 'sloppy' colocation check of the specified points. +/// @param[in] p0 A point. [(x, y, z)] +/// @param[in] p1 A point. [(x, y, z)] +/// @return True if the points are considered to be at the same location. +/// +/// Basically, this function will return true if the specified points are +/// close enough to eachother to be considered colocated. +inline bool dtVequal(const float* p0, const float* p1) +{ + static const float thr = dtSqr(1.0f/16384.0f); + const float d = dtVdistSqr(p0, p1); + return d < thr; +} + +/// Derives the dot product of two vectors on the xz-plane. (@p u . @p v) +/// @param[in] u A vector [(x, y, z)] +/// @param[in] v A vector [(x, y, z)] +/// @return The dot product on the xz-plane. +/// +/// The vectors are projected onto the xz-plane, so the y-values are ignored. +inline float dtVdot2D(const float* u, const float* v) +{ + return u[0]*v[0] + u[2]*v[2]; +} + +/// Derives the xz-plane 2D perp product of the two vectors. (uz*vx - ux*vz) +/// @param[in] u The LHV vector [(x, y, z)] +/// @param[in] v The RHV vector [(x, y, z)] +/// @return The dot product on the xz-plane. +/// +/// The vectors are projected onto the xz-plane, so the y-values are ignored. +inline float dtVperp2D(const float* u, const float* v) +{ + return u[2]*v[0] - u[0]*v[2]; +} + +/// @} +/// @name Computational geometry helper functions. +/// @{ + +/// Derives the signed xz-plane area of the triangle ABC, or the relationship of line AB to point C. +/// @param[in] a Vertex A. [(x, y, z)] +/// @param[in] b Vertex B. [(x, y, z)] +/// @param[in] c Vertex C. [(x, y, z)] +/// @return The signed xz-plane area of the triangle. +inline float dtTriArea2D(const float* a, const float* b, const float* c) +{ + const float abx = b[0] - a[0]; + const float abz = b[2] - a[2]; + const float acx = c[0] - a[0]; + const float acz = c[2] - a[2]; + return acx*abz - abx*acz; +} + +/// Determines if two axis-aligned bounding boxes overlap. +/// @param[in] amin Minimum bounds of box A. [(x, y, z)] +/// @param[in] amax Maximum bounds of box A. [(x, y, z)] +/// @param[in] bmin Minimum bounds of box B. [(x, y, z)] +/// @param[in] bmax Maximum bounds of box B. [(x, y, z)] +/// @return True if the two AABB's overlap. +/// @see dtOverlapBounds +inline bool dtOverlapQuantBounds(const unsigned short amin[3], const unsigned short amax[3], + const unsigned short bmin[3], const unsigned short bmax[3]) +{ + bool overlap = true; + overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap; + overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap; + overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap; + return overlap; +} + +/// Determines if two axis-aligned bounding boxes overlap. +/// @param[in] amin Minimum bounds of box A. [(x, y, z)] +/// @param[in] amax Maximum bounds of box A. [(x, y, z)] +/// @param[in] bmin Minimum bounds of box B. [(x, y, z)] +/// @param[in] bmax Maximum bounds of box B. [(x, y, z)] +/// @return True if the two AABB's overlap. +/// @see dtOverlapQuantBounds +inline bool dtOverlapBounds(const float* amin, const float* amax, + const float* bmin, const float* bmax) +{ + bool overlap = true; + overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap; + overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap; + overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap; + return overlap; +} + +/// Derives the closest point on a triangle from the specified reference point. +/// @param[out] closest The closest point on the triangle. +/// @param[in] p The reference point from which to test. [(x, y, z)] +/// @param[in] a Vertex A of triangle ABC. [(x, y, z)] +/// @param[in] b Vertex B of triangle ABC. [(x, y, z)] +/// @param[in] c Vertex C of triangle ABC. [(x, y, z)] +void dtClosestPtPointTriangle(float* closest, const float* p, + const float* a, const float* b, const float* c); + +/// Derives the y-axis height of the closest point on the triangle from the specified reference point. +/// @param[in] p The reference point from which to test. [(x, y, z)] +/// @param[in] a Vertex A of triangle ABC. [(x, y, z)] +/// @param[in] b Vertex B of triangle ABC. [(x, y, z)] +/// @param[in] c Vertex C of triangle ABC. [(x, y, z)] +/// @param[out] h The resulting height. +bool dtClosestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h); + +bool dtIntersectSegmentPoly2D(const float* p0, const float* p1, + const float* verts, int nverts, + float& tmin, float& tmax, + int& segMin, int& segMax); + +bool dtIntersectSegSeg2D(const float* ap, const float* aq, + const float* bp, const float* bq, + float& s, float& t); + +/// Determines if the specified point is inside the convex polygon on the xz-plane. +/// @param[in] pt The point to check. [(x, y, z)] +/// @param[in] verts The polygon vertices. [(x, y, z) * @p nverts] +/// @param[in] nverts The number of vertices. [Limit: >= 3] +/// @return True if the point is inside the polygon. +bool dtPointInPolygon(const float* pt, const float* verts, const int nverts); + +bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nverts, + float* ed, float* et); + +float dtDistancePtSegSqr2D(const float* pt, const float* p, const float* q, float& t); + +/// Derives the centroid of a convex polygon. +/// @param[out] tc The centroid of the polgyon. [(x, y, z)] +/// @param[in] idx The polygon indices. [(vertIndex) * @p nidx] +/// @param[in] nidx The number of indices in the polygon. [Limit: >= 3] +/// @param[in] verts The polygon vertices. [(x, y, z) * vertCount] +void dtCalcPolyCenter(float* tc, const unsigned short* idx, int nidx, const float* verts); + +/// Determines if the two convex polygons overlap on the xz-plane. +/// @param[in] polya Polygon A vertices. [(x, y, z) * @p npolya] +/// @param[in] npolya The number of vertices in polygon A. +/// @param[in] polyb Polygon B vertices. [(x, y, z) * @p npolyb] +/// @param[in] npolyb The number of vertices in polygon B. +/// @return True if the two polygons overlap. +bool dtOverlapPolyPoly2D(const float* polya, const int npolya, + const float* polyb, const int npolyb); + +/// @} +/// @name Miscellanious functions. +/// @{ + +inline unsigned int dtNextPow2(unsigned int v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} + +inline unsigned int dtIlog2(unsigned int v) +{ + unsigned int r; + unsigned int shift; + r = (v > 0xffff) << 4; v >>= r; + shift = (v > 0xff) << 3; v >>= shift; r |= shift; + shift = (v > 0xf) << 2; v >>= shift; r |= shift; + shift = (v > 0x3) << 1; v >>= shift; r |= shift; + r |= (v >> 1); + return r; +} + +inline int dtAlign4(int x) { return (x+3) & ~3; } + +inline int dtOppositeTile(int side) { return (side+4) & 0x7; } + +inline void dtSwapByte(unsigned char* a, unsigned char* b) +{ + unsigned char tmp = *a; + *a = *b; + *b = tmp; +} + +inline void dtSwapEndian(unsigned short* v) +{ + unsigned char* x = (unsigned char*)v; + dtSwapByte(x+0, x+1); +} + +inline void dtSwapEndian(short* v) +{ + unsigned char* x = (unsigned char*)v; + dtSwapByte(x+0, x+1); +} + +inline void dtSwapEndian(unsigned int* v) +{ + unsigned char* x = (unsigned char*)v; + dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2); +} + +inline void dtSwapEndian(int* v) +{ + unsigned char* x = (unsigned char*)v; + dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2); +} + +inline void dtSwapEndian(float* v) +{ + unsigned char* x = (unsigned char*)v; + dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2); +} + +void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas, + const float s, const float t, float* out); + +template +TypeToRetrieveAs* dtGetThenAdvanceBufferPointer(const unsigned char*& buffer, const size_t distanceToAdvance) +{ + TypeToRetrieveAs* returnPointer = reinterpret_cast(buffer); + buffer += distanceToAdvance; + return returnPointer; +} + +template +TypeToRetrieveAs* dtGetThenAdvanceBufferPointer(unsigned char*& buffer, const size_t distanceToAdvance) +{ + TypeToRetrieveAs* returnPointer = reinterpret_cast(buffer); + buffer += distanceToAdvance; + return returnPointer; +} + + +/// @} + +#endif // DETOURCOMMON_H + +/////////////////////////////////////////////////////////////////////////// + +// This section contains detailed documentation for members that don't have +// a source file. It reduces clutter in the main section of the header. + +/** + +@fn float dtTriArea2D(const float* a, const float* b, const float* c) +@par + +The vertices are projected onto the xz-plane, so the y-values are ignored. + +This is a low cost function than can be used for various purposes. Its main purpose +is for point/line relationship testing. + +In all cases: A value of zero indicates that all vertices are collinear or represent the same point. +(On the xz-plane.) + +When used for point/line relationship tests, AB usually represents a line against which +the C point is to be tested. In this case: + +A positive value indicates that point C is to the left of line AB, looking from A toward B.
+A negative value indicates that point C is to the right of lineAB, looking from A toward B. + +When used for evaluating a triangle: + +The absolute value of the return value is two times the area of the triangle when it is +projected onto the xz-plane. + +A positive return value indicates: + +
    +
  • The vertices are wrapped in the normal Detour wrap direction.
  • +
  • The triangle's 3D face normal is in the general up direction.
  • +
+ +A negative return value indicates: + +
    +
  • The vertices are reverse wrapped. (Wrapped opposite the normal Detour wrap direction.)
  • +
  • The triangle's 3D face normal is in the general down direction.
  • +
+ +*/ diff --git a/libs/recast/detour/include/DetourMath.h b/libs/recast/detour/include/DetourMath.h new file mode 100644 index 000000000..95e14f884 --- /dev/null +++ b/libs/recast/detour/include/DetourMath.h @@ -0,0 +1,20 @@ +/** +@defgroup detour Detour + +Members in this module are wrappers around the standard math library +*/ + +#ifndef DETOURMATH_H +#define DETOURMATH_H + +#include + +inline float dtMathFabsf(float x) { return fabsf(x); } +inline float dtMathSqrtf(float x) { return sqrtf(x); } +inline float dtMathFloorf(float x) { return floorf(x); } +inline float dtMathCeilf(float x) { return ceilf(x); } +inline float dtMathCosf(float x) { return cosf(x); } +inline float dtMathSinf(float x) { return sinf(x); } +inline float dtMathAtan2f(float y, float x) { return atan2f(y, x); } + +#endif diff --git a/libs/recast/detour/include/DetourNavMesh.h b/libs/recast/detour/include/DetourNavMesh.h new file mode 100644 index 000000000..8ecd57e46 --- /dev/null +++ b/libs/recast/detour/include/DetourNavMesh.h @@ -0,0 +1,765 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURNAVMESH_H +#define DETOURNAVMESH_H + +#include "DetourAlloc.h" +#include "DetourStatus.h" + +// Undefine (or define in a build cofnig) the following line to use 64bit polyref. +// Generally not needed, useful for very large worlds. +// Note: tiles build using 32bit refs are not compatible with 64bit refs! +//#define DT_POLYREF64 1 + +#ifdef DT_POLYREF64 +// TODO: figure out a multiplatform version of uint64_t +// - maybe: https://code.google.com/p/msinttypes/ +// - or: http://www.azillionmonkeys.com/qed/pstdint.h +#include +#endif + +// Note: If you want to use 64-bit refs, change the types of both dtPolyRef & dtTileRef. +// It is also recommended that you change dtHashRef() to a proper 64-bit hash. + +/// A handle to a polygon within a navigation mesh tile. +/// @ingroup detour +#ifdef DT_POLYREF64 +static const unsigned int DT_SALT_BITS = 16; +static const unsigned int DT_TILE_BITS = 28; +static const unsigned int DT_POLY_BITS = 20; +typedef uint64_t dtPolyRef; +#else +typedef unsigned int dtPolyRef; +#endif + +/// A handle to a tile within a navigation mesh. +/// @ingroup detour +#ifdef DT_POLYREF64 +typedef uint64_t dtTileRef; +#else +typedef unsigned int dtTileRef; +#endif + +/// The maximum number of vertices per navigation polygon. +/// @ingroup detour +static const int DT_VERTS_PER_POLYGON = 6; + +/// @{ +/// @name Tile Serialization Constants +/// These constants are used to detect whether a navigation tile's data +/// and state format is compatible with the current build. +/// + +/// A magic number used to detect compatibility of navigation tile data. +static const int DT_NAVMESH_MAGIC = 'D'<<24 | 'N'<<16 | 'A'<<8 | 'V'; + +/// A version number used to detect compatibility of navigation tile data. +static const int DT_NAVMESH_VERSION = 7; + +/// A magic number used to detect the compatibility of navigation tile states. +static const int DT_NAVMESH_STATE_MAGIC = 'D'<<24 | 'N'<<16 | 'M'<<8 | 'S'; + +/// A version number used to detect compatibility of navigation tile states. +static const int DT_NAVMESH_STATE_VERSION = 1; + +/// @} + +/// A flag that indicates that an entity links to an external entity. +/// (E.g. A polygon edge is a portal that links to another polygon.) +static const unsigned short DT_EXT_LINK = 0x8000; + +/// A value that indicates the entity does not link to anything. +static const unsigned int DT_NULL_LINK = 0xffffffff; + +/// A flag that indicates that an off-mesh connection can be traversed in both directions. (Is bidirectional.) +static const unsigned int DT_OFFMESH_CON_BIDIR = 1; + +/// The maximum number of user defined area ids. +/// @ingroup detour +static const int DT_MAX_AREAS = 64; + +/// Tile flags used for various functions and fields. +/// For an example, see dtNavMesh::addTile(). +enum dtTileFlags +{ + /// The navigation mesh owns the tile memory and is responsible for freeing it. + DT_TILE_FREE_DATA = 0x01, +}; + +/// Vertex flags returned by dtNavMeshQuery::findStraightPath. +enum dtStraightPathFlags +{ + DT_STRAIGHTPATH_START = 0x01, ///< The vertex is the start position in the path. + DT_STRAIGHTPATH_END = 0x02, ///< The vertex is the end position in the path. + DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, ///< The vertex is the start of an off-mesh connection. +}; + +/// Options for dtNavMeshQuery::findStraightPath. +enum dtStraightPathOptions +{ + DT_STRAIGHTPATH_AREA_CROSSINGS = 0x01, ///< Add a vertex at every polygon edge crossing where area changes. + DT_STRAIGHTPATH_ALL_CROSSINGS = 0x02, ///< Add a vertex at every polygon edge crossing. +}; + + +/// Options for dtNavMeshQuery::initSlicedFindPath and updateSlicedFindPath +enum dtFindPathOptions +{ + DT_FINDPATH_ANY_ANGLE = 0x02, ///< use raycasts during pathfind to "shortcut" (raycast still consider costs) +}; + +/// Options for dtNavMeshQuery::raycast +enum dtRaycastOptions +{ + DT_RAYCAST_USE_COSTS = 0x01, ///< Raycast should calculate movement cost along the ray and fill RaycastHit::cost +}; + + +/// Limit raycasting during any angle pahfinding +/// The limit is given as a multiple of the character radius +static const float DT_RAY_CAST_LIMIT_PROPORTIONS = 50.0f; + +/// Flags representing the type of a navigation mesh polygon. +enum dtPolyTypes +{ + /// The polygon is a standard convex polygon that is part of the surface of the mesh. + DT_POLYTYPE_GROUND = 0, + /// The polygon is an off-mesh connection consisting of two vertices. + DT_POLYTYPE_OFFMESH_CONNECTION = 1, +}; + + +/// Defines a polygon within a dtMeshTile object. +/// @ingroup detour +struct dtPoly +{ + /// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.) + unsigned int firstLink; + + /// The indices of the polygon's vertices. + /// The actual vertices are located in dtMeshTile::verts. + unsigned short verts[DT_VERTS_PER_POLYGON]; + + /// Packed data representing neighbor polygons references and flags for each edge. + unsigned short neis[DT_VERTS_PER_POLYGON]; + + /// The user defined polygon flags. + unsigned short flags; + + /// The number of vertices in the polygon. + unsigned char vertCount; + + /// The bit packed area id and polygon type. + /// @note Use the structure's set and get methods to acess this value. + unsigned char areaAndtype; + + /// Sets the user defined area id. [Limit: < #DT_MAX_AREAS] + inline void setArea(unsigned char a) { areaAndtype = (areaAndtype & 0xc0) | (a & 0x3f); } + + /// Sets the polygon type. (See: #dtPolyTypes.) + inline void setType(unsigned char t) { areaAndtype = (areaAndtype & 0x3f) | (t << 6); } + + /// Gets the user defined area id. + inline unsigned char getArea() const { return areaAndtype & 0x3f; } + + /// Gets the polygon type. (See: #dtPolyTypes) + inline unsigned char getType() const { return areaAndtype >> 6; } +}; + +/// Defines the location of detail sub-mesh data within a dtMeshTile. +struct dtPolyDetail +{ + unsigned int vertBase; ///< The offset of the vertices in the dtMeshTile::detailVerts array. + unsigned int triBase; ///< The offset of the triangles in the dtMeshTile::detailTris array. + unsigned char vertCount; ///< The number of vertices in the sub-mesh. + unsigned char triCount; ///< The number of triangles in the sub-mesh. +}; + +/// Defines a link between polygons. +/// @note This structure is rarely if ever used by the end user. +/// @see dtMeshTile +struct dtLink +{ + dtPolyRef ref; ///< Neighbour reference. (The neighbor that is linked to.) + unsigned int next; ///< Index of the next link. + unsigned char edge; ///< Index of the polygon edge that owns this link. + unsigned char side; ///< If a boundary link, defines on which side the link is. + unsigned char bmin; ///< If a boundary link, defines the minimum sub-edge area. + unsigned char bmax; ///< If a boundary link, defines the maximum sub-edge area. +}; + +/// Bounding volume node. +/// @note This structure is rarely if ever used by the end user. +/// @see dtMeshTile +struct dtBVNode +{ + unsigned short bmin[3]; ///< Minimum bounds of the node's AABB. [(x, y, z)] + unsigned short bmax[3]; ///< Maximum bounds of the node's AABB. [(x, y, z)] + int i; ///< The node's index. (Negative for escape sequence.) +}; + +/// Defines an navigation mesh off-mesh connection within a dtMeshTile object. +/// An off-mesh connection is a user defined traversable connection made up to two vertices. +struct dtOffMeshConnection +{ + /// The endpoints of the connection. [(ax, ay, az, bx, by, bz)] + float pos[6]; + + /// The radius of the endpoints. [Limit: >= 0] + float rad; + + /// The polygon reference of the connection within the tile. + unsigned short poly; + + /// Link flags. + /// @note These are not the connection's user defined flags. Those are assigned via the + /// connection's dtPoly definition. These are link flags used for internal purposes. + unsigned char flags; + + /// End point side. + unsigned char side; + + /// The id of the offmesh connection. (User assigned when the navigation mesh is built.) + unsigned int userId; +}; + +/// Provides high level information related to a dtMeshTile object. +/// @ingroup detour +struct dtMeshHeader +{ + int magic; ///< Tile magic number. (Used to identify the data format.) + int version; ///< Tile data format version number. + int x; ///< The x-position of the tile within the dtNavMesh tile grid. (x, y, layer) + int y; ///< The y-position of the tile within the dtNavMesh tile grid. (x, y, layer) + int layer; ///< The layer of the tile within the dtNavMesh tile grid. (x, y, layer) + unsigned int userId; ///< The user defined id of the tile. + int polyCount; ///< The number of polygons in the tile. + int vertCount; ///< The number of vertices in the tile. + int maxLinkCount; ///< The number of allocated links. + int detailMeshCount; ///< The number of sub-meshes in the detail mesh. + + /// The number of unique vertices in the detail mesh. (In addition to the polygon vertices.) + int detailVertCount; + + int detailTriCount; ///< The number of triangles in the detail mesh. + int bvNodeCount; ///< The number of bounding volume nodes. (Zero if bounding volumes are disabled.) + int offMeshConCount; ///< The number of off-mesh connections. + int offMeshBase; ///< The index of the first polygon which is an off-mesh connection. + float walkableHeight; ///< The height of the agents using the tile. + float walkableRadius; ///< The radius of the agents using the tile. + float walkableClimb; ///< The maximum climb height of the agents using the tile. + float bmin[3]; ///< The minimum bounds of the tile's AABB. [(x, y, z)] + float bmax[3]; ///< The maximum bounds of the tile's AABB. [(x, y, z)] + + /// The bounding volume quantization factor. + float bvQuantFactor; +}; + +/// Defines a navigation mesh tile. +/// @ingroup detour +struct dtMeshTile +{ + unsigned int salt; ///< Counter describing modifications to the tile. + + unsigned int linksFreeList; ///< Index to the next free link. + dtMeshHeader* header; ///< The tile header. + dtPoly* polys; ///< The tile polygons. [Size: dtMeshHeader::polyCount] + float* verts; ///< The tile vertices. [Size: dtMeshHeader::vertCount] + dtLink* links; ///< The tile links. [Size: dtMeshHeader::maxLinkCount] + dtPolyDetail* detailMeshes; ///< The tile's detail sub-meshes. [Size: dtMeshHeader::detailMeshCount] + + /// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount] + float* detailVerts; + + /// The detail mesh's triangles. [(vertA, vertB, vertC) * dtMeshHeader::detailTriCount] + unsigned char* detailTris; + + /// The tile bounding volume nodes. [Size: dtMeshHeader::bvNodeCount] + /// (Will be null if bounding volumes are disabled.) + dtBVNode* bvTree; + + dtOffMeshConnection* offMeshCons; ///< The tile off-mesh connections. [Size: dtMeshHeader::offMeshConCount] + + unsigned char* data; ///< The tile data. (Not directly accessed under normal situations.) + int dataSize; ///< Size of the tile data. + int flags; ///< Tile flags. (See: #dtTileFlags) + dtMeshTile* next; ///< The next free tile, or the next tile in the spatial grid. +private: + dtMeshTile(const dtMeshTile&); + dtMeshTile& operator=(const dtMeshTile&); +}; + +/// Configuration parameters used to define multi-tile navigation meshes. +/// The values are used to allocate space during the initialization of a navigation mesh. +/// @see dtNavMesh::init() +/// @ingroup detour +struct dtNavMeshParams +{ + float orig[3]; ///< The world space origin of the navigation mesh's tile space. [(x, y, z)] + float tileWidth; ///< The width of each tile. (Along the x-axis.) + float tileHeight; ///< The height of each tile. (Along the z-axis.) + int maxTiles; ///< The maximum number of tiles the navigation mesh can contain. + int maxPolys; ///< The maximum number of polygons each tile can contain. +}; + +/// A navigation mesh based on tiles of convex polygons. +/// @ingroup detour +class dtNavMesh +{ +public: + dtNavMesh(); + ~dtNavMesh(); + + /// @{ + /// @name Initialization and Tile Management + + /// Initializes the navigation mesh for tiled use. + /// @param[in] params Initialization parameters. + /// @return The status flags for the operation. + dtStatus init(const dtNavMeshParams* params); + + /// Initializes the navigation mesh for single tile use. + /// @param[in] data Data of the new tile. (See: #dtCreateNavMeshData) + /// @param[in] dataSize The data size of the new tile. + /// @param[in] flags The tile flags. (See: #dtTileFlags) + /// @return The status flags for the operation. + /// @see dtCreateNavMeshData + dtStatus init(unsigned char* data, const int dataSize, const int flags); + + /// The navigation mesh initialization params. + const dtNavMeshParams* getParams() const; + + /// Adds a tile to the navigation mesh. + /// @param[in] data Data for the new tile mesh. (See: #dtCreateNavMeshData) + /// @param[in] dataSize Data size of the new tile mesh. + /// @param[in] flags Tile flags. (See: #dtTileFlags) + /// @param[in] lastRef The desired reference for the tile. (When reloading a tile.) [opt] [Default: 0] + /// @param[out] result The tile reference. (If the tile was succesfully added.) [opt] + /// @return The status flags for the operation. + dtStatus addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef, dtTileRef* result); + + /// Removes the specified tile from the navigation mesh. + /// @param[in] ref The reference of the tile to remove. + /// @param[out] data Data associated with deleted tile. + /// @param[out] dataSize Size of the data associated with deleted tile. + /// @return The status flags for the operation. + dtStatus removeTile(dtTileRef ref, unsigned char** data, int* dataSize); + + /// @} + + /// @{ + /// @name Query Functions + + /// Calculates the tile grid location for the specified world position. + /// @param[in] pos The world position for the query. [(x, y, z)] + /// @param[out] tx The tile's x-location. (x, y) + /// @param[out] ty The tile's y-location. (x, y) + void calcTileLoc(const float* pos, int* tx, int* ty) const; + + /// Gets the tile at the specified grid location. + /// @param[in] x The tile's x-location. (x, y, layer) + /// @param[in] y The tile's y-location. (x, y, layer) + /// @param[in] layer The tile's layer. (x, y, layer) + /// @return The tile, or null if the tile does not exist. + const dtMeshTile* getTileAt(const int x, const int y, const int layer) const; + + /// Gets all tiles at the specified grid location. (All layers.) + /// @param[in] x The tile's x-location. (x, y) + /// @param[in] y The tile's y-location. (x, y) + /// @param[out] tiles A pointer to an array of tiles that will hold the result. + /// @param[in] maxTiles The maximum tiles the tiles parameter can hold. + /// @return The number of tiles returned in the tiles array. + int getTilesAt(const int x, const int y, + dtMeshTile const** tiles, const int maxTiles) const; + + /// Gets the tile reference for the tile at specified grid location. + /// @param[in] x The tile's x-location. (x, y, layer) + /// @param[in] y The tile's y-location. (x, y, layer) + /// @param[in] layer The tile's layer. (x, y, layer) + /// @return The tile reference of the tile, or 0 if there is none. + dtTileRef getTileRefAt(int x, int y, int layer) const; + + /// Gets the tile reference for the specified tile. + /// @param[in] tile The tile. + /// @return The tile reference of the tile. + dtTileRef getTileRef(const dtMeshTile* tile) const; + + /// Gets the tile for the specified tile reference. + /// @param[in] ref The tile reference of the tile to retrieve. + /// @return The tile for the specified reference, or null if the + /// reference is invalid. + const dtMeshTile* getTileByRef(dtTileRef ref) const; + + /// The maximum number of tiles supported by the navigation mesh. + /// @return The maximum number of tiles supported by the navigation mesh. + int getMaxTiles() const; + + /// Gets the tile at the specified index. + /// @param[in] i The tile index. [Limit: 0 >= index < #getMaxTiles()] + /// @return The tile at the specified index. + const dtMeshTile* getTile(int i) const; + + /// Gets the tile and polygon for the specified polygon reference. + /// @param[in] ref The reference for the a polygon. + /// @param[out] tile The tile containing the polygon. + /// @param[out] poly The polygon. + /// @return The status flags for the operation. + dtStatus getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const; + + /// Returns the tile and polygon for the specified polygon reference. + /// @param[in] ref A known valid reference for a polygon. + /// @param[out] tile The tile containing the polygon. + /// @param[out] poly The polygon. + void getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const; + + /// Checks the validity of a polygon reference. + /// @param[in] ref The polygon reference to check. + /// @return True if polygon reference is valid for the navigation mesh. + bool isValidPolyRef(dtPolyRef ref) const; + + /// Gets the polygon reference for the tile's base polygon. + /// @param[in] tile The tile. + /// @return The polygon reference for the base polygon in the specified tile. + dtPolyRef getPolyRefBase(const dtMeshTile* tile) const; + + /// Gets the endpoints for an off-mesh connection, ordered by "direction of travel". + /// @param[in] prevRef The reference of the polygon before the connection. + /// @param[in] polyRef The reference of the off-mesh connection polygon. + /// @param[out] startPos The start position of the off-mesh connection. [(x, y, z)] + /// @param[out] endPos The end position of the off-mesh connection. [(x, y, z)] + /// @return The status flags for the operation. + dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const; + + /// Gets the specified off-mesh connection. + /// @param[in] ref The polygon reference of the off-mesh connection. + /// @return The specified off-mesh connection, or null if the polygon reference is not valid. + const dtOffMeshConnection* getOffMeshConnectionByRef(dtPolyRef ref) const; + + /// @} + + /// @{ + /// @name State Management + /// These functions do not effect #dtTileRef or #dtPolyRef's. + + /// Sets the user defined flags for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[in] flags The new flags for the polygon. + /// @return The status flags for the operation. + dtStatus setPolyFlags(dtPolyRef ref, unsigned short flags); + + /// Gets the user defined flags for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[out] resultFlags The polygon flags. + /// @return The status flags for the operation. + dtStatus getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const; + + /// Sets the user defined area for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[in] area The new area id for the polygon. [Limit: < #DT_MAX_AREAS] + /// @return The status flags for the operation. + dtStatus setPolyArea(dtPolyRef ref, unsigned char area); + + /// Gets the user defined area for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[out] resultArea The area id for the polygon. + /// @return The status flags for the operation. + dtStatus getPolyArea(dtPolyRef ref, unsigned char* resultArea) const; + + /// Gets the size of the buffer required by #storeTileState to store the specified tile's state. + /// @param[in] tile The tile. + /// @return The size of the buffer required to store the state. + int getTileStateSize(const dtMeshTile* tile) const; + + /// Stores the non-structural state of the tile in the specified buffer. (Flags, area ids, etc.) + /// @param[in] tile The tile. + /// @param[out] data The buffer to store the tile's state in. + /// @param[in] maxDataSize The size of the data buffer. [Limit: >= #getTileStateSize] + /// @return The status flags for the operation. + dtStatus storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const; + + /// Restores the state of the tile. + /// @param[in] tile The tile. + /// @param[in] data The new state. (Obtained from #storeTileState.) + /// @param[in] maxDataSize The size of the state within the data buffer. + /// @return The status flags for the operation. + dtStatus restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize); + + /// @} + + /// @{ + /// @name Encoding and Decoding + /// These functions are generally meant for internal use only. + + /// Derives a standard polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] salt The tile's salt value. + /// @param[in] it The index of the tile. + /// @param[in] ip The index of the polygon within the tile. + inline dtPolyRef encodePolyId(unsigned int salt, unsigned int it, unsigned int ip) const + { +#ifdef DT_POLYREF64 + return ((dtPolyRef)salt << (DT_POLY_BITS+DT_TILE_BITS)) | ((dtPolyRef)it << DT_POLY_BITS) | (dtPolyRef)ip; +#else + return ((dtPolyRef)salt << (m_polyBits+m_tileBits)) | ((dtPolyRef)it << m_polyBits) | (dtPolyRef)ip; +#endif + } + + /// Decodes a standard polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference to decode. + /// @param[out] salt The tile's salt value. + /// @param[out] it The index of the tile. + /// @param[out] ip The index of the polygon within the tile. + /// @see #encodePolyId + inline void decodePolyId(dtPolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip) const + { +#ifdef DT_POLYREF64 + const dtPolyRef saltMask = ((dtPolyRef)1<> (DT_POLY_BITS+DT_TILE_BITS)) & saltMask); + it = (unsigned int)((ref >> DT_POLY_BITS) & tileMask); + ip = (unsigned int)(ref & polyMask); +#else + const dtPolyRef saltMask = ((dtPolyRef)1<> (m_polyBits+m_tileBits)) & saltMask); + it = (unsigned int)((ref >> m_polyBits) & tileMask); + ip = (unsigned int)(ref & polyMask); +#endif + } + + /// Extracts a tile's salt value from the specified polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference. + /// @see #encodePolyId + inline unsigned int decodePolyIdSalt(dtPolyRef ref) const + { +#ifdef DT_POLYREF64 + const dtPolyRef saltMask = ((dtPolyRef)1<> (DT_POLY_BITS+DT_TILE_BITS)) & saltMask); +#else + const dtPolyRef saltMask = ((dtPolyRef)1<> (m_polyBits+m_tileBits)) & saltMask); +#endif + } + + /// Extracts the tile's index from the specified polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference. + /// @see #encodePolyId + inline unsigned int decodePolyIdTile(dtPolyRef ref) const + { +#ifdef DT_POLYREF64 + const dtPolyRef tileMask = ((dtPolyRef)1<> DT_POLY_BITS) & tileMask); +#else + const dtPolyRef tileMask = ((dtPolyRef)1<> m_polyBits) & tileMask); +#endif + } + + /// Extracts the polygon's index (within its tile) from the specified polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference. + /// @see #encodePolyId + inline unsigned int decodePolyIdPoly(dtPolyRef ref) const + { +#ifdef DT_POLYREF64 + const dtPolyRef polyMask = ((dtPolyRef)1<header->bvQuantFactor; +const dtBVNode* n = &tile->bvTree[i]; +if (n->i >= 0) +{ + // This is a leaf node. + float worldMinX = tile->header->bmin[0] + n->bmin[0]*cs; + float worldMinY = tile->header->bmin[0] + n->bmin[1]*cs; + // Etc... +} +@endcode + +@struct dtMeshTile +@par + +Tiles generally only exist within the context of a dtNavMesh object. + +Some tile content is optional. For example, a tile may not contain any +off-mesh connections. In this case the associated pointer will be null. + +If a detail mesh exists it will share vertices with the base polygon mesh. +Only the vertices unique to the detail mesh will be stored in #detailVerts. + +@warning Tiles returned by a dtNavMesh object are not guarenteed to be populated. +For example: The tile at a location might not have been loaded yet, or may have been removed. +In this case, pointers will be null. So if in doubt, check the polygon count in the +tile's header to determine if a tile has polygons defined. + +@var float dtOffMeshConnection::pos[6] +@par + +For a properly built navigation mesh, vertex A will always be within the bounds of the mesh. +Vertex B is not required to be within the bounds of the mesh. + +*/ diff --git a/libs/recast/detour/include/DetourNavMeshBuilder.h b/libs/recast/detour/include/DetourNavMeshBuilder.h new file mode 100644 index 000000000..9425a7a78 --- /dev/null +++ b/libs/recast/detour/include/DetourNavMeshBuilder.h @@ -0,0 +1,149 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURNAVMESHBUILDER_H +#define DETOURNAVMESHBUILDER_H + +#include "DetourAlloc.h" + +/// Represents the source data used to build an navigation mesh tile. +/// @ingroup detour +struct dtNavMeshCreateParams +{ + + /// @name Polygon Mesh Attributes + /// Used to create the base navigation graph. + /// See #rcPolyMesh for details related to these attributes. + /// @{ + + const unsigned short* verts; ///< The polygon mesh vertices. [(x, y, z) * #vertCount] [Unit: vx] + int vertCount; ///< The number vertices in the polygon mesh. [Limit: >= 3] + const unsigned short* polys; ///< The polygon data. [Size: #polyCount * 2 * #nvp] + const unsigned short* polyFlags; ///< The user defined flags assigned to each polygon. [Size: #polyCount] + const unsigned char* polyAreas; ///< The user defined area ids assigned to each polygon. [Size: #polyCount] + int polyCount; ///< Number of polygons in the mesh. [Limit: >= 1] + int nvp; ///< Number maximum number of vertices per polygon. [Limit: >= 3] + + /// @} + /// @name Height Detail Attributes (Optional) + /// See #rcPolyMeshDetail for details related to these attributes. + /// @{ + + const unsigned int* detailMeshes; ///< The height detail sub-mesh data. [Size: 4 * #polyCount] + const float* detailVerts; ///< The detail mesh vertices. [Size: 3 * #detailVertsCount] [Unit: wu] + int detailVertsCount; ///< The number of vertices in the detail mesh. + const unsigned char* detailTris; ///< The detail mesh triangles. [Size: 4 * #detailTriCount] + int detailTriCount; ///< The number of triangles in the detail mesh. + + /// @} + /// @name Off-Mesh Connections Attributes (Optional) + /// Used to define a custom point-to-point edge within the navigation graph, an + /// off-mesh connection is a user defined traversable connection made up to two vertices, + /// at least one of which resides within a navigation mesh polygon. + /// @{ + + /// Off-mesh connection vertices. [(ax, ay, az, bx, by, bz) * #offMeshConCount] [Unit: wu] + const float* offMeshConVerts; + /// Off-mesh connection radii. [Size: #offMeshConCount] [Unit: wu] + const float* offMeshConRad; + /// User defined flags assigned to the off-mesh connections. [Size: #offMeshConCount] + const unsigned short* offMeshConFlags; + /// User defined area ids assigned to the off-mesh connections. [Size: #offMeshConCount] + const unsigned char* offMeshConAreas; + /// The permitted travel direction of the off-mesh connections. [Size: #offMeshConCount] + /// + /// 0 = Travel only from endpoint A to endpoint B.
+ /// #DT_OFFMESH_CON_BIDIR = Bidirectional travel. + const unsigned char* offMeshConDir; + /// The user defined ids of the off-mesh connection. [Size: #offMeshConCount] + const unsigned int* offMeshConUserID; + /// The number of off-mesh connections. [Limit: >= 0] + int offMeshConCount; + + /// @} + /// @name Tile Attributes + /// @note The tile grid/layer data can be left at zero if the destination is a single tile mesh. + /// @{ + + unsigned int userId; ///< The user defined id of the tile. + int tileX; ///< The tile's x-grid location within the multi-tile destination mesh. (Along the x-axis.) + int tileY; ///< The tile's y-grid location within the multi-tile desitation mesh. (Along the z-axis.) + int tileLayer; ///< The tile's layer within the layered destination mesh. [Limit: >= 0] (Along the y-axis.) + float bmin[3]; ///< The minimum bounds of the tile. [(x, y, z)] [Unit: wu] + float bmax[3]; ///< The maximum bounds of the tile. [(x, y, z)] [Unit: wu] + + /// @} + /// @name General Configuration Attributes + /// @{ + + float walkableHeight; ///< The agent height. [Unit: wu] + float walkableRadius; ///< The agent radius. [Unit: wu] + float walkableClimb; ///< The agent maximum traversable ledge. (Up/Down) [Unit: wu] + float cs; ///< The xz-plane cell size of the polygon mesh. [Limit: > 0] [Unit: wu] + float ch; ///< The y-axis cell height of the polygon mesh. [Limit: > 0] [Unit: wu] + + /// True if a bounding volume tree should be built for the tile. + /// @note The BVTree is not normally needed for layered navigation meshes. + bool buildBvTree; + + /// @} +}; + +/// Builds navigation mesh tile data from the provided tile creation data. +/// @ingroup detour +/// @param[in] params Tile creation data. +/// @param[out] outData The resulting tile data. +/// @param[out] outDataSize The size of the tile data array. +/// @return True if the tile data was successfully created. +bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize); + +/// Swaps the endianess of the tile data's header (#dtMeshHeader). +/// @param[in,out] data The tile data array. +/// @param[in] dataSize The size of the data array. +bool dtNavMeshHeaderSwapEndian(unsigned char* data, const int dataSize); + +/// Swaps endianess of the tile data. +/// @param[in,out] data The tile data array. +/// @param[in] dataSize The size of the data array. +bool dtNavMeshDataSwapEndian(unsigned char* data, const int dataSize); + +#endif // DETOURNAVMESHBUILDER_H + +// This section contains detailed documentation for members that don't have +// a source file. It reduces clutter in the main section of the header. + +/** + +@struct dtNavMeshCreateParams +@par + +This structure is used to marshal data between the Recast mesh generation pipeline and Detour navigation components. + +See the rcPolyMesh and rcPolyMeshDetail documentation for detailed information related to mesh structure. + +Units are usually in voxels (vx) or world units (wu). The units for voxels, grid size, and cell size +are all based on the values of #cs and #ch. + +The standard navigation mesh build process is to create tile data using dtCreateNavMeshData, then add the tile +to a navigation mesh using either the dtNavMesh single tile init() function or the dtNavMesh::addTile() +function. + +@see dtCreateNavMeshData + +*/ + diff --git a/libs/recast/detour/include/DetourNavMeshQuery.h b/libs/recast/detour/include/DetourNavMeshQuery.h new file mode 100644 index 000000000..61541e83d --- /dev/null +++ b/libs/recast/detour/include/DetourNavMeshQuery.h @@ -0,0 +1,575 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURNAVMESHQUERY_H +#define DETOURNAVMESHQUERY_H + +#include "DetourNavMesh.h" +#include "DetourStatus.h" + + +// Define DT_VIRTUAL_QUERYFILTER if you wish to derive a custom filter from dtQueryFilter. +// On certain platforms indirect or virtual function call is expensive. The default +// setting is to use non-virtual functions, the actual implementations of the functions +// are declared as inline for maximum speed. + +//#define DT_VIRTUAL_QUERYFILTER 1 + +/// Defines polygon filtering and traversal costs for navigation mesh query operations. +/// @ingroup detour +class dtQueryFilter +{ + float m_areaCost[DT_MAX_AREAS]; ///< Cost per area type. (Used by default implementation.) + unsigned short m_includeFlags; ///< Flags for polygons that can be visited. (Used by default implementation.) + unsigned short m_excludeFlags; ///< Flags for polygons that should not be visted. (Used by default implementation.) + +public: + dtQueryFilter(); + +#ifdef DT_VIRTUAL_QUERYFILTER + virtual ~dtQueryFilter() { } +#endif + + /// Returns true if the polygon can be visited. (I.e. Is traversable.) + /// @param[in] ref The reference id of the polygon test. + /// @param[in] tile The tile containing the polygon. + /// @param[in] poly The polygon to test. +#ifdef DT_VIRTUAL_QUERYFILTER + virtual bool passFilter(const dtPolyRef ref, + const dtMeshTile* tile, + const dtPoly* poly) const; +#else + bool passFilter(const dtPolyRef ref, + const dtMeshTile* tile, + const dtPoly* poly) const; +#endif + + /// Returns cost to move from the beginning to the end of a line segment + /// that is fully contained within a polygon. + /// @param[in] pa The start position on the edge of the previous and current polygon. [(x, y, z)] + /// @param[in] pb The end position on the edge of the current and next polygon. [(x, y, z)] + /// @param[in] prevRef The reference id of the previous polygon. [opt] + /// @param[in] prevTile The tile containing the previous polygon. [opt] + /// @param[in] prevPoly The previous polygon. [opt] + /// @param[in] curRef The reference id of the current polygon. + /// @param[in] curTile The tile containing the current polygon. + /// @param[in] curPoly The current polygon. + /// @param[in] nextRef The refernece id of the next polygon. [opt] + /// @param[in] nextTile The tile containing the next polygon. [opt] + /// @param[in] nextPoly The next polygon. [opt] +#ifdef DT_VIRTUAL_QUERYFILTER + virtual float getCost(const float* pa, const float* pb, + const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly, + const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly, + const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const; +#else + float getCost(const float* pa, const float* pb, + const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly, + const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly, + const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const; +#endif + + /// @name Getters and setters for the default implementation data. + ///@{ + + /// Returns the traversal cost of the area. + /// @param[in] i The id of the area. + /// @returns The traversal cost of the area. + inline float getAreaCost(const int i) const { return m_areaCost[i]; } + + /// Sets the traversal cost of the area. + /// @param[in] i The id of the area. + /// @param[in] cost The new cost of traversing the area. + inline void setAreaCost(const int i, const float cost) { m_areaCost[i] = cost; } + + /// Returns the include flags for the filter. + /// Any polygons that include one or more of these flags will be + /// included in the operation. + inline unsigned short getIncludeFlags() const { return m_includeFlags; } + + /// Sets the include flags for the filter. + /// @param[in] flags The new flags. + inline void setIncludeFlags(const unsigned short flags) { m_includeFlags = flags; } + + /// Returns the exclude flags for the filter. + /// Any polygons that include one ore more of these flags will be + /// excluded from the operation. + inline unsigned short getExcludeFlags() const { return m_excludeFlags; } + + /// Sets the exclude flags for the filter. + /// @param[in] flags The new flags. + inline void setExcludeFlags(const unsigned short flags) { m_excludeFlags = flags; } + + ///@} + +}; + + + +/// Provides information about raycast hit +/// filled by dtNavMeshQuery::raycast +/// @ingroup detour +struct dtRaycastHit +{ + /// The hit parameter. (FLT_MAX if no wall hit.) + float t; + + /// hitNormal The normal of the nearest wall hit. [(x, y, z)] + float hitNormal[3]; + + /// The index of the edge on the final polygon where the wall was hit. + int hitEdgeIndex; + + /// Pointer to an array of reference ids of the visited polygons. [opt] + dtPolyRef* path; + + /// The number of visited polygons. [opt] + int pathCount; + + /// The maximum number of polygons the @p path array can hold. + int maxPath; + + /// The cost of the path until hit. + float pathCost; +}; + +/// Provides custom polygon query behavior. +/// Used by dtNavMeshQuery::queryPolygons. +/// @ingroup detour +class dtPolyQuery +{ +public: + virtual ~dtPolyQuery() { } + + /// Called for each batch of unique polygons touched by the search area in dtNavMeshQuery::queryPolygons. + /// This can be called multiple times for a single query. + virtual void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) = 0; +}; + +/// Provides the ability to perform pathfinding related queries against +/// a navigation mesh. +/// @ingroup detour +class dtNavMeshQuery +{ +public: + dtNavMeshQuery(); + ~dtNavMeshQuery(); + + /// Initializes the query object. + /// @param[in] nav Pointer to the dtNavMesh object to use for all queries. + /// @param[in] maxNodes Maximum number of search nodes. [Limits: 0 < value <= 65535] + /// @returns The status flags for the query. + dtStatus init(const dtNavMesh* nav, const int maxNodes); + + /// @name Standard Pathfinding Functions + // /@{ + + /// Finds a path from the start polygon to the end polygon. + /// @param[in] startRef The refrence id of the start polygon. + /// @param[in] endRef The reference id of the end polygon. + /// @param[in] startPos A position within the start polygon. [(x, y, z)] + /// @param[in] endPos A position within the end polygon. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 1] + dtStatus findPath(dtPolyRef startRef, dtPolyRef endRef, + const float* startPos, const float* endPos, + const dtQueryFilter* filter, + dtPolyRef* path, int* pathCount, const int maxPath) const; + + /// Finds the straight path from the start to the end position within the polygon corridor. + /// @param[in] startPos Path start position. [(x, y, z)] + /// @param[in] endPos Path end position. [(x, y, z)] + /// @param[in] path An array of polygon references that represent the path corridor. + /// @param[in] pathSize The number of polygons in the @p path array. + /// @param[out] straightPath Points describing the straight path. [(x, y, z) * @p straightPathCount]. + /// @param[out] straightPathFlags Flags describing each point. (See: #dtStraightPathFlags) [opt] + /// @param[out] straightPathRefs The reference id of the polygon that is being entered at each point. [opt] + /// @param[out] straightPathCount The number of points in the straight path. + /// @param[in] maxStraightPath The maximum number of points the straight path arrays can hold. [Limit: > 0] + /// @param[in] options Query options. (see: #dtStraightPathOptions) + /// @returns The status flags for the query. + dtStatus findStraightPath(const float* startPos, const float* endPos, + const dtPolyRef* path, const int pathSize, + float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, + int* straightPathCount, const int maxStraightPath, const int options = 0) const; + + ///@} + /// @name Sliced Pathfinding Functions + /// Common use case: + /// -# Call initSlicedFindPath() to initialize the sliced path query. + /// -# Call updateSlicedFindPath() until it returns complete. + /// -# Call finalizeSlicedFindPath() to get the path. + ///@{ + + /// Intializes a sliced path query. + /// @param[in] startRef The refrence id of the start polygon. + /// @param[in] endRef The reference id of the end polygon. + /// @param[in] startPos A position within the start polygon. [(x, y, z)] + /// @param[in] endPos A position within the end polygon. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[in] options query options (see: #dtFindPathOptions) + /// @returns The status flags for the query. + dtStatus initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, + const float* startPos, const float* endPos, + const dtQueryFilter* filter, const unsigned int options = 0); + + /// Updates an in-progress sliced path query. + /// @param[in] maxIter The maximum number of iterations to perform. + /// @param[out] doneIters The actual number of iterations completed. [opt] + /// @returns The status flags for the query. + dtStatus updateSlicedFindPath(const int maxIter, int* doneIters); + + /// Finalizes and returns the results of a sliced path query. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The max number of polygons the path array can hold. [Limit: >= 1] + /// @returns The status flags for the query. + dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath); + + /// Finalizes and returns the results of an incomplete sliced path query, returning the path to the furthest + /// polygon on the existing path that was visited during the search. + /// @param[in] existing An array of polygon references for the existing path. + /// @param[in] existingSize The number of polygon in the @p existing array. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The max number of polygons the @p path array can hold. [Limit: >= 1] + /// @returns The status flags for the query. + dtStatus finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize, + dtPolyRef* path, int* pathCount, const int maxPath); + + ///@} + /// @name Dijkstra Search Functions + /// @{ + + /// Finds the polygons along the navigation graph that touch the specified circle. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] centerPos The center of the search circle. [(x, y, z)] + /// @param[in] radius The radius of the search circle. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultRef The reference ids of the polygons touched by the circle. [opt] + /// @param[out] resultParent The reference ids of the parent polygons for each result. + /// Zero if a result polygon has no parent. [opt] + /// @param[out] resultCost The search cost from @p centerPos to the polygon. [opt] + /// @param[out] resultCount The number of polygons found. [opt] + /// @param[in] maxResult The maximum number of polygons the result arrays can hold. + /// @returns The status flags for the query. + dtStatus findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius, + const dtQueryFilter* filter, + dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, + int* resultCount, const int maxResult) const; + + /// Finds the polygons along the naviation graph that touch the specified convex polygon. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] verts The vertices describing the convex polygon. (CCW) + /// [(x, y, z) * @p nverts] + /// @param[in] nverts The number of vertices in the polygon. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultRef The reference ids of the polygons touched by the search polygon. [opt] + /// @param[out] resultParent The reference ids of the parent polygons for each result. Zero if a + /// result polygon has no parent. [opt] + /// @param[out] resultCost The search cost from the centroid point to the polygon. [opt] + /// @param[out] resultCount The number of polygons found. + /// @param[in] maxResult The maximum number of polygons the result arrays can hold. + /// @returns The status flags for the query. + dtStatus findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts, + const dtQueryFilter* filter, + dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, + int* resultCount, const int maxResult) const; + + /// Gets a path from the explored nodes in the previous search. + /// @param[in] endRef The reference id of the end polygon. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 0] + /// @returns The status flags. Returns DT_FAILURE | DT_INVALID_PARAM if any parameter is wrong, or if + /// @p endRef was not explored in the previous search. Returns DT_SUCCESS | DT_BUFFER_TOO_SMALL + /// if @p path cannot contain the entire path. In this case it is filled to capacity with a partial path. + /// Otherwise returns DT_SUCCESS. + /// @remarks The result of this function depends on the state of the query object. For that reason it should only + /// be used immediately after one of the two Dijkstra searches, findPolysAroundCircle or findPolysAroundShape. + dtStatus getPathFromDijkstraSearch(dtPolyRef endRef, dtPolyRef* path, int* pathCount, int maxPath) const; + + /// @} + /// @name Local Query Functions + ///@{ + + /// Finds the polygon nearest to the specified center point. + /// @param[in] center The center of the search box. [(x, y, z)] + /// @param[in] extents The search distance along each axis. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] nearestRef The reference id of the nearest polygon. + /// @param[out] nearestPt The nearest point on the polygon. [opt] [(x, y, z)] + /// @returns The status flags for the query. + dtStatus findNearestPoly(const float* center, const float* extents, + const dtQueryFilter* filter, + dtPolyRef* nearestRef, float* nearestPt) const; + + /// Finds polygons that overlap the search box. + /// @param[in] center The center of the search box. [(x, y, z)] + /// @param[in] extents The search distance along each axis. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] polys The reference ids of the polygons that overlap the query box. + /// @param[out] polyCount The number of polygons in the search result. + /// @param[in] maxPolys The maximum number of polygons the search result can hold. + /// @returns The status flags for the query. + dtStatus queryPolygons(const float* center, const float* extents, + const dtQueryFilter* filter, + dtPolyRef* polys, int* polyCount, const int maxPolys) const; + + /// Finds polygons that overlap the search box. + /// @param[in] center The center of the search box. [(x, y, z)] + /// @param[in] extents The search distance along each axis. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[in] query The query. Polygons found will be batched together and passed to this query. + dtStatus queryPolygons(const float* center, const float* extents, + const dtQueryFilter* filter, dtPolyQuery* query) const; + + /// Finds the non-overlapping navigation polygons in the local neighbourhood around the center position. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] centerPos The center of the query circle. [(x, y, z)] + /// @param[in] radius The radius of the query circle. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultRef The reference ids of the polygons touched by the circle. + /// @param[out] resultParent The reference ids of the parent polygons for each result. + /// Zero if a result polygon has no parent. [opt] + /// @param[out] resultCount The number of polygons found. + /// @param[in] maxResult The maximum number of polygons the result arrays can hold. + /// @returns The status flags for the query. + dtStatus findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius, + const dtQueryFilter* filter, + dtPolyRef* resultRef, dtPolyRef* resultParent, + int* resultCount, const int maxResult) const; + + /// Moves from the start to the end position constrained to the navigation mesh. + /// @param[in] startRef The reference id of the start polygon. + /// @param[in] startPos A position of the mover within the start polygon. [(x, y, x)] + /// @param[in] endPos The desired end position of the mover. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultPos The result position of the mover. [(x, y, z)] + /// @param[out] visited The reference ids of the polygons visited during the move. + /// @param[out] visitedCount The number of polygons visited during the move. + /// @param[in] maxVisitedSize The maximum number of polygons the @p visited array can hold. + /// @returns The status flags for the query. + dtStatus moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, + float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const; + + /// Casts a 'walkability' ray along the surface of the navigation mesh from + /// the start position toward the end position. + /// @note A wrapper around raycast(..., RaycastHit*). Retained for backward compatibility. + /// @param[in] startRef The reference id of the start polygon. + /// @param[in] startPos A position within the start polygon representing + /// the start of the ray. [(x, y, z)] + /// @param[in] endPos The position to cast the ray toward. [(x, y, z)] + /// @param[out] t The hit parameter. (FLT_MAX if no wall hit.) + /// @param[out] hitNormal The normal of the nearest wall hit. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] path The reference ids of the visited polygons. [opt] + /// @param[out] pathCount The number of visited polygons. [opt] + /// @param[in] maxPath The maximum number of polygons the @p path array can hold. + /// @returns The status flags for the query. + dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, + float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const; + + /// Casts a 'walkability' ray along the surface of the navigation mesh from + /// the start position toward the end position. + /// @param[in] startRef The reference id of the start polygon. + /// @param[in] startPos A position within the start polygon representing + /// the start of the ray. [(x, y, z)] + /// @param[in] endPos The position to cast the ray toward. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[in] flags govern how the raycast behaves. See dtRaycastOptions + /// @param[out] hit Pointer to a raycast hit structure which will be filled by the results. + /// @param[in] prevRef parent of start ref. Used during for cost calculation [opt] + /// @returns The status flags for the query. + dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, const unsigned int options, + dtRaycastHit* hit, dtPolyRef prevRef = 0) const; + + + /// Finds the distance from the specified position to the nearest polygon wall. + /// @param[in] startRef The reference id of the polygon containing @p centerPos. + /// @param[in] centerPos The center of the search circle. [(x, y, z)] + /// @param[in] maxRadius The radius of the search circle. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] hitDist The distance to the nearest wall from @p centerPos. + /// @param[out] hitPos The nearest position on the wall that was hit. [(x, y, z)] + /// @param[out] hitNormal The normalized ray formed from the wall point to the + /// source point. [(x, y, z)] + /// @returns The status flags for the query. + dtStatus findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius, + const dtQueryFilter* filter, + float* hitDist, float* hitPos, float* hitNormal) const; + + /// Returns the segments for the specified polygon, optionally including portals. + /// @param[in] ref The reference id of the polygon. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] segmentVerts The segments. [(ax, ay, az, bx, by, bz) * segmentCount] + /// @param[out] segmentRefs The reference ids of each segment's neighbor polygon. + /// Or zero if the segment is a wall. [opt] [(parentRef) * @p segmentCount] + /// @param[out] segmentCount The number of segments returned. + /// @param[in] maxSegments The maximum number of segments the result arrays can hold. + /// @returns The status flags for the query. + dtStatus getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, + float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount, + const int maxSegments) const; + + /// Returns random location on navmesh. + /// Polygons are chosen weighted by area. The search runs in linear related to number of polygon. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[in] frand Function returning a random number [0..1). + /// @param[out] randomRef The reference id of the random location. + /// @param[out] randomPt The random location. + /// @returns The status flags for the query. + dtStatus findRandomPoint(const dtQueryFilter* filter, float (*frand)(), + dtPolyRef* randomRef, float* randomPt) const; + + /// Returns random location on navmesh within the reach of specified location. + /// Polygons are chosen weighted by area. The search runs in linear related to number of polygon. + /// The location is not exactly constrained by the circle, but it limits the visited polygons. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] centerPos The center of the search circle. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[in] frand Function returning a random number [0..1). + /// @param[out] randomRef The reference id of the random location. + /// @param[out] randomPt The random location. [(x, y, z)] + /// @returns The status flags for the query. + dtStatus findRandomPointAroundCircle(dtPolyRef startRef, const float* centerPos, const float maxRadius, + const dtQueryFilter* filter, float (*frand)(), + dtPolyRef* randomRef, float* randomPt) const; + + /// Finds the closest point on the specified polygon. + /// @param[in] ref The reference id of the polygon. + /// @param[in] pos The position to check. [(x, y, z)] + /// @param[out] closest The closest point on the polygon. [(x, y, z)] + /// @param[out] posOverPoly True of the position is over the polygon. + /// @returns The status flags for the query. + dtStatus closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly) const; + + /// Returns a point on the boundary closest to the source point if the source point is outside the + /// polygon's xz-bounds. + /// @param[in] ref The reference id to the polygon. + /// @param[in] pos The position to check. [(x, y, z)] + /// @param[out] closest The closest point. [(x, y, z)] + /// @returns The status flags for the query. + dtStatus closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const; + + /// Gets the height of the polygon at the provided position using the height detail. (Most accurate.) + /// @param[in] ref The reference id of the polygon. + /// @param[in] pos A position within the xz-bounds of the polygon. [(x, y, z)] + /// @param[out] height The height at the surface of the polygon. + /// @returns The status flags for the query. + dtStatus getPolyHeight(dtPolyRef ref, const float* pos, float* height) const; + + /// @} + /// @name Miscellaneous Functions + /// @{ + + /// Returns true if the polygon reference is valid and passes the filter restrictions. + /// @param[in] ref The polygon reference to check. + /// @param[in] filter The filter to apply. + bool isValidPolyRef(dtPolyRef ref, const dtQueryFilter* filter) const; + + /// Returns true if the polygon reference is in the closed list. + /// @param[in] ref The reference id of the polygon to check. + /// @returns True if the polygon is in closed list. + bool isInClosedList(dtPolyRef ref) const; + + /// Gets the node pool. + /// @returns The node pool. + class dtNodePool* getNodePool() const { return m_nodePool; } + + /// Gets the navigation mesh the query object is using. + /// @return The navigation mesh the query object is using. + const dtNavMesh* getAttachedNavMesh() const { return m_nav; } + + /// @} + +private: + // Explicitly disabled copy constructor and copy assignment operator + dtNavMeshQuery(const dtNavMeshQuery&); + dtNavMeshQuery& operator=(const dtNavMeshQuery&); + + /// Queries polygons within a tile. + void queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax, + const dtQueryFilter* filter, dtPolyQuery* query) const; + + /// Returns portal points between two polygons. + dtStatus getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right, + unsigned char& fromType, unsigned char& toType) const; + dtStatus getPortalPoints(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile, + dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile, + float* left, float* right) const; + + /// Returns edge mid point between two polygons. + dtStatus getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const; + dtStatus getEdgeMidPoint(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile, + dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile, + float* mid) const; + + // Appends vertex to a straight path + dtStatus appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref, + float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, + int* straightPathCount, const int maxStraightPath) const; + + // Appends intermediate portal points to a straight path. + dtStatus appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path, + float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, + int* straightPathCount, const int maxStraightPath, const int options) const; + + // Gets the path leading to the specified end node. + dtStatus getPathToNode(struct dtNode* endNode, dtPolyRef* path, int* pathCount, int maxPath) const; + + const dtNavMesh* m_nav; ///< Pointer to navmesh data. + + struct dtQueryData + { + dtStatus status; + struct dtNode* lastBestNode; + float lastBestNodeCost; + dtPolyRef startRef, endRef; + float startPos[3], endPos[3]; + const dtQueryFilter* filter; + unsigned int options; + float raycastLimitSqr; + }; + dtQueryData m_query; ///< Sliced query state. + + class dtNodePool* m_tinyNodePool; ///< Pointer to small node pool. + class dtNodePool* m_nodePool; ///< Pointer to node pool. + class dtNodeQueue* m_openList; ///< Pointer to open list queue. +}; + +/// Allocates a query object using the Detour allocator. +/// @return An allocated query object, or null on failure. +/// @ingroup detour +dtNavMeshQuery* dtAllocNavMeshQuery(); + +/// Frees the specified query object using the Detour allocator. +/// @param[in] query A query object allocated using #dtAllocNavMeshQuery +/// @ingroup detour +void dtFreeNavMeshQuery(dtNavMeshQuery* query); + +#endif // DETOURNAVMESHQUERY_H diff --git a/libs/recast/detour/include/DetourNode.h b/libs/recast/detour/include/DetourNode.h new file mode 100644 index 000000000..db0974708 --- /dev/null +++ b/libs/recast/detour/include/DetourNode.h @@ -0,0 +1,168 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURNODE_H +#define DETOURNODE_H + +#include "DetourNavMesh.h" + +enum dtNodeFlags +{ + DT_NODE_OPEN = 0x01, + DT_NODE_CLOSED = 0x02, + DT_NODE_PARENT_DETACHED = 0x04, // parent of the node is not adjacent. Found using raycast. +}; + +typedef unsigned short dtNodeIndex; +static const dtNodeIndex DT_NULL_IDX = (dtNodeIndex)~0; + +static const int DT_NODE_PARENT_BITS = 24; +static const int DT_NODE_STATE_BITS = 2; +struct dtNode +{ + float pos[3]; ///< Position of the node. + float cost; ///< Cost from previous node to current node. + float total; ///< Cost up to the node. + unsigned int pidx : DT_NODE_PARENT_BITS; ///< Index to parent node. + unsigned int state : DT_NODE_STATE_BITS; ///< extra state information. A polyRef can have multiple nodes with different extra info. see DT_MAX_STATES_PER_NODE + unsigned int flags : 3; ///< Node flags. A combination of dtNodeFlags. + dtPolyRef id; ///< Polygon ref the node corresponds to. +}; + +static const int DT_MAX_STATES_PER_NODE = 1 << DT_NODE_STATE_BITS; // number of extra states per node. See dtNode::state + +class dtNodePool +{ +public: + dtNodePool(int maxNodes, int hashSize); + ~dtNodePool(); + void clear(); + + // Get a dtNode by ref and extra state information. If there is none then - allocate + // There can be more than one node for the same polyRef but with different extra state information + dtNode* getNode(dtPolyRef id, unsigned char state=0); + dtNode* findNode(dtPolyRef id, unsigned char state); + unsigned int findNodes(dtPolyRef id, dtNode** nodes, const int maxNodes); + + inline unsigned int getNodeIdx(const dtNode* node) const + { + if (!node) return 0; + return (unsigned int)(node - m_nodes) + 1; + } + + inline dtNode* getNodeAtIdx(unsigned int idx) + { + if (!idx) return 0; + return &m_nodes[idx - 1]; + } + + inline const dtNode* getNodeAtIdx(unsigned int idx) const + { + if (!idx) return 0; + return &m_nodes[idx - 1]; + } + + inline int getMemUsed() const + { + return sizeof(*this) + + sizeof(dtNode)*m_maxNodes + + sizeof(dtNodeIndex)*m_maxNodes + + sizeof(dtNodeIndex)*m_hashSize; + } + + inline int getMaxNodes() const { return m_maxNodes; } + + inline int getHashSize() const { return m_hashSize; } + inline dtNodeIndex getFirst(int bucket) const { return m_first[bucket]; } + inline dtNodeIndex getNext(int i) const { return m_next[i]; } + inline int getNodeCount() const { return m_nodeCount; } + +private: + // Explicitly disabled copy constructor and copy assignment operator. + dtNodePool(const dtNodePool&); + dtNodePool& operator=(const dtNodePool&); + + dtNode* m_nodes; + dtNodeIndex* m_first; + dtNodeIndex* m_next; + const int m_maxNodes; + const int m_hashSize; + int m_nodeCount; +}; + +class dtNodeQueue +{ +public: + dtNodeQueue(int n); + ~dtNodeQueue(); + + inline void clear() { m_size = 0; } + + inline dtNode* top() { return m_heap[0]; } + + inline dtNode* pop() + { + dtNode* result = m_heap[0]; + m_size--; + trickleDown(0, m_heap[m_size]); + return result; + } + + inline void push(dtNode* node) + { + m_size++; + bubbleUp(m_size-1, node); + } + + inline void modify(dtNode* node) + { + for (int i = 0; i < m_size; ++i) + { + if (m_heap[i] == node) + { + bubbleUp(i, node); + return; + } + } + } + + inline bool empty() const { return m_size == 0; } + + inline int getMemUsed() const + { + return sizeof(*this) + + sizeof(dtNode*) * (m_capacity + 1); + } + + inline int getCapacity() const { return m_capacity; } + +private: + // Explicitly disabled copy constructor and copy assignment operator. + dtNodeQueue(const dtNodeQueue&); + dtNodeQueue& operator=(const dtNodeQueue&); + + void bubbleUp(int i, dtNode* node); + void trickleDown(int i, dtNode* node); + + dtNode** m_heap; + const int m_capacity; + int m_size; +}; + + +#endif // DETOURNODE_H diff --git a/libs/recast/detour/include/DetourStatus.h b/libs/recast/detour/include/DetourStatus.h new file mode 100644 index 000000000..af822c4a9 --- /dev/null +++ b/libs/recast/detour/include/DetourStatus.h @@ -0,0 +1,64 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURSTATUS_H +#define DETOURSTATUS_H + +typedef unsigned int dtStatus; + +// High level status. +static const unsigned int DT_FAILURE = 1u << 31; // Operation failed. +static const unsigned int DT_SUCCESS = 1u << 30; // Operation succeed. +static const unsigned int DT_IN_PROGRESS = 1u << 29; // Operation still in progress. + +// Detail information for status. +static const unsigned int DT_STATUS_DETAIL_MASK = 0x0ffffff; +static const unsigned int DT_WRONG_MAGIC = 1 << 0; // Input data is not recognized. +static const unsigned int DT_WRONG_VERSION = 1 << 1; // Input data is in wrong version. +static const unsigned int DT_OUT_OF_MEMORY = 1 << 2; // Operation ran out of memory. +static const unsigned int DT_INVALID_PARAM = 1 << 3; // An input parameter was invalid. +static const unsigned int DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the query was too small to store all results. +static const unsigned int DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search. +static const unsigned int DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess. + + +// Returns true of status is success. +inline bool dtStatusSucceed(dtStatus status) +{ + return (status & DT_SUCCESS) != 0; +} + +// Returns true of status is failure. +inline bool dtStatusFailed(dtStatus status) +{ + return (status & DT_FAILURE) != 0; +} + +// Returns true of status is in progress. +inline bool dtStatusInProgress(dtStatus status) +{ + return (status & DT_IN_PROGRESS) != 0; +} + +// Returns true if specific detail is set. +inline bool dtStatusDetail(dtStatus status, unsigned int detail) +{ + return (status & detail) != 0; +} + +#endif // DETOURSTATUS_H diff --git a/libs/recast/detour/src/DetourAlloc.cpp b/libs/recast/detour/src/DetourAlloc.cpp new file mode 100644 index 000000000..d9ad1fc01 --- /dev/null +++ b/libs/recast/detour/src/DetourAlloc.cpp @@ -0,0 +1,50 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#include "DetourAlloc.h" + +static void *dtAllocDefault(size_t size, dtAllocHint) +{ + return malloc(size); +} + +static void dtFreeDefault(void *ptr) +{ + free(ptr); +} + +static dtAllocFunc* sAllocFunc = dtAllocDefault; +static dtFreeFunc* sFreeFunc = dtFreeDefault; + +void dtAllocSetCustom(dtAllocFunc *allocFunc, dtFreeFunc *freeFunc) +{ + sAllocFunc = allocFunc ? allocFunc : dtAllocDefault; + sFreeFunc = freeFunc ? freeFunc : dtFreeDefault; +} + +void* dtAlloc(size_t size, dtAllocHint hint) +{ + return sAllocFunc(size, hint); +} + +void dtFree(void* ptr) +{ + if (ptr) + sFreeFunc(ptr); +} diff --git a/libs/recast/detour/src/DetourAssert.cpp b/libs/recast/detour/src/DetourAssert.cpp new file mode 100644 index 000000000..5e019e0cf --- /dev/null +++ b/libs/recast/detour/src/DetourAssert.cpp @@ -0,0 +1,35 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include "DetourAssert.h" + +#ifndef NDEBUG + +static dtAssertFailFunc* sAssertFailFunc = 0; + +void dtAssertFailSetCustom(dtAssertFailFunc *assertFailFunc) +{ + sAssertFailFunc = assertFailFunc; +} + +dtAssertFailFunc* dtAssertFailGetCustom() +{ + return sAssertFailFunc; +} + +#endif diff --git a/libs/recast/detour/src/DetourCommon.cpp b/libs/recast/detour/src/DetourCommon.cpp new file mode 100644 index 000000000..41d0d7bd3 --- /dev/null +++ b/libs/recast/detour/src/DetourCommon.cpp @@ -0,0 +1,388 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include "DetourCommon.h" +#include "DetourMath.h" + +////////////////////////////////////////////////////////////////////////////////////////// + +void dtClosestPtPointTriangle(float* closest, const float* p, + const float* a, const float* b, const float* c) +{ + // Check if P in vertex region outside A + float ab[3], ac[3], ap[3]; + dtVsub(ab, b, a); + dtVsub(ac, c, a); + dtVsub(ap, p, a); + float d1 = dtVdot(ab, ap); + float d2 = dtVdot(ac, ap); + if (d1 <= 0.0f && d2 <= 0.0f) + { + // barycentric coordinates (1,0,0) + dtVcopy(closest, a); + return; + } + + // Check if P in vertex region outside B + float bp[3]; + dtVsub(bp, p, b); + float d3 = dtVdot(ab, bp); + float d4 = dtVdot(ac, bp); + if (d3 >= 0.0f && d4 <= d3) + { + // barycentric coordinates (0,1,0) + dtVcopy(closest, b); + return; + } + + // Check if P in edge region of AB, if so return projection of P onto AB + float vc = d1*d4 - d3*d2; + if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) + { + // barycentric coordinates (1-v,v,0) + float v = d1 / (d1 - d3); + closest[0] = a[0] + v * ab[0]; + closest[1] = a[1] + v * ab[1]; + closest[2] = a[2] + v * ab[2]; + return; + } + + // Check if P in vertex region outside C + float cp[3]; + dtVsub(cp, p, c); + float d5 = dtVdot(ab, cp); + float d6 = dtVdot(ac, cp); + if (d6 >= 0.0f && d5 <= d6) + { + // barycentric coordinates (0,0,1) + dtVcopy(closest, c); + return; + } + + // Check if P in edge region of AC, if so return projection of P onto AC + float vb = d5*d2 - d1*d6; + if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) + { + // barycentric coordinates (1-w,0,w) + float w = d2 / (d2 - d6); + closest[0] = a[0] + w * ac[0]; + closest[1] = a[1] + w * ac[1]; + closest[2] = a[2] + w * ac[2]; + return; + } + + // Check if P in edge region of BC, if so return projection of P onto BC + float va = d3*d6 - d5*d4; + if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) + { + // barycentric coordinates (0,1-w,w) + float w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + closest[0] = b[0] + w * (c[0] - b[0]); + closest[1] = b[1] + w * (c[1] - b[1]); + closest[2] = b[2] + w * (c[2] - b[2]); + return; + } + + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + float denom = 1.0f / (va + vb + vc); + float v = vb * denom; + float w = vc * denom; + closest[0] = a[0] + ab[0] * v + ac[0] * w; + closest[1] = a[1] + ab[1] * v + ac[1] * w; + closest[2] = a[2] + ab[2] * v + ac[2] * w; +} + +bool dtIntersectSegmentPoly2D(const float* p0, const float* p1, + const float* verts, int nverts, + float& tmin, float& tmax, + int& segMin, int& segMax) +{ + static const float EPS = 0.00000001f; + + tmin = 0; + tmax = 1; + segMin = -1; + segMax = -1; + + float dir[3]; + dtVsub(dir, p1, p0); + + for (int i = 0, j = nverts-1; i < nverts; j=i++) + { + float edge[3], diff[3]; + dtVsub(edge, &verts[i*3], &verts[j*3]); + dtVsub(diff, p0, &verts[j*3]); + const float n = dtVperp2D(edge, diff); + const float d = dtVperp2D(dir, edge); + if (fabsf(d) < EPS) + { + // S is nearly parallel to this edge + if (n < 0) + return false; + else + continue; + } + const float t = n / d; + if (d < 0) + { + // segment S is entering across this edge + if (t > tmin) + { + tmin = t; + segMin = j; + // S enters after leaving polygon + if (tmin > tmax) + return false; + } + } + else + { + // segment S is leaving across this edge + if (t < tmax) + { + tmax = t; + segMax = j; + // S leaves before entering polygon + if (tmax < tmin) + return false; + } + } + } + + return true; +} + +float dtDistancePtSegSqr2D(const float* pt, const float* p, const float* q, float& t) +{ + float pqx = q[0] - p[0]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqz*pqz; + t = pqx*dx + pqz*dz; + if (d > 0) t /= d; + if (t < 0) t = 0; + else if (t > 1) t = 1; + dx = p[0] + t*pqx - pt[0]; + dz = p[2] + t*pqz - pt[2]; + return dx*dx + dz*dz; +} + +void dtCalcPolyCenter(float* tc, const unsigned short* idx, int nidx, const float* verts) +{ + tc[0] = 0.0f; + tc[1] = 0.0f; + tc[2] = 0.0f; + for (int j = 0; j < nidx; ++j) + { + const float* v = &verts[idx[j]*3]; + tc[0] += v[0]; + tc[1] += v[1]; + tc[2] += v[2]; + } + const float s = 1.0f / nidx; + tc[0] *= s; + tc[1] *= s; + tc[2] *= s; +} + +bool dtClosestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h) +{ + float v0[3], v1[3], v2[3]; + dtVsub(v0, c,a); + dtVsub(v1, b,a); + dtVsub(v2, p,a); + + const float dot00 = dtVdot2D(v0, v0); + const float dot01 = dtVdot2D(v0, v1); + const float dot02 = dtVdot2D(v0, v2); + const float dot11 = dtVdot2D(v1, v1); + const float dot12 = dtVdot2D(v1, v2); + + // Compute barycentric coordinates + const float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); + const float u = (dot11 * dot02 - dot01 * dot12) * invDenom; + const float v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + // The (sloppy) epsilon is needed to allow to get height of points which + // are interpolated along the edges of the triangles. + static const float EPS = 1e-4f; + + // If point lies inside the triangle, return interpolated ycoord. + if (u >= -EPS && v >= -EPS && (u+v) <= 1+EPS) + { + h = a[1] + v0[1]*u + v1[1]*v; + return true; + } + + return false; +} + +/// @par +/// +/// All points are projected onto the xz-plane, so the y-values are ignored. +bool dtPointInPolygon(const float* pt, const float* verts, const int nverts) +{ + // TODO: Replace pnpoly with triArea2D tests? + int i, j; + bool c = false; + for (i = 0, j = nverts-1; i < nverts; j = i++) + { + const float* vi = &verts[i*3]; + const float* vj = &verts[j*3]; + if (((vi[2] > pt[2]) != (vj[2] > pt[2])) && + (pt[0] < (vj[0]-vi[0]) * (pt[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) ) + c = !c; + } + return c; +} + +bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nverts, + float* ed, float* et) +{ + // TODO: Replace pnpoly with triArea2D tests? + int i, j; + bool c = false; + for (i = 0, j = nverts-1; i < nverts; j = i++) + { + const float* vi = &verts[i*3]; + const float* vj = &verts[j*3]; + if (((vi[2] > pt[2]) != (vj[2] > pt[2])) && + (pt[0] < (vj[0]-vi[0]) * (pt[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) ) + c = !c; + ed[j] = dtDistancePtSegSqr2D(pt, vj, vi, et[j]); + } + return c; +} + +static void projectPoly(const float* axis, const float* poly, const int npoly, + float& rmin, float& rmax) +{ + rmin = rmax = dtVdot2D(axis, &poly[0]); + for (int i = 1; i < npoly; ++i) + { + const float d = dtVdot2D(axis, &poly[i*3]); + rmin = dtMin(rmin, d); + rmax = dtMax(rmax, d); + } +} + +inline bool overlapRange(const float amin, const float amax, + const float bmin, const float bmax, + const float eps) +{ + return ((amin+eps) > bmax || (amax-eps) < bmin) ? false : true; +} + +/// @par +/// +/// All vertices are projected onto the xz-plane, so the y-values are ignored. +bool dtOverlapPolyPoly2D(const float* polya, const int npolya, + const float* polyb, const int npolyb) +{ + const float eps = 1e-4f; + + for (int i = 0, j = npolya-1; i < npolya; j=i++) + { + const float* va = &polya[j*3]; + const float* vb = &polya[i*3]; + const float n[3] = { vb[2]-va[2], 0, -(vb[0]-va[0]) }; + float amin,amax,bmin,bmax; + projectPoly(n, polya, npolya, amin,amax); + projectPoly(n, polyb, npolyb, bmin,bmax); + if (!overlapRange(amin,amax, bmin,bmax, eps)) + { + // Found separating axis + return false; + } + } + for (int i = 0, j = npolyb-1; i < npolyb; j=i++) + { + const float* va = &polyb[j*3]; + const float* vb = &polyb[i*3]; + const float n[3] = { vb[2]-va[2], 0, -(vb[0]-va[0]) }; + float amin,amax,bmin,bmax; + projectPoly(n, polya, npolya, amin,amax); + projectPoly(n, polyb, npolyb, bmin,bmax); + if (!overlapRange(amin,amax, bmin,bmax, eps)) + { + // Found separating axis + return false; + } + } + return true; +} + +// Returns a random point in a convex polygon. +// Adapted from Graphics Gems article. +void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas, + const float s, const float t, float* out) +{ + // Calc triangle araes + float areasum = 0.0f; + for (int i = 2; i < npts; i++) { + areas[i] = dtTriArea2D(&pts[0], &pts[(i-1)*3], &pts[i*3]); + areasum += dtMax(0.001f, areas[i]); + } + // Find sub triangle weighted by area. + const float thr = s*areasum; + float acc = 0.0f; + float u = 1.0f; + int tri = npts - 1; + for (int i = 2; i < npts; i++) { + const float dacc = areas[i]; + if (thr >= acc && thr < (acc+dacc)) + { + u = (thr - acc) / dacc; + tri = i; + break; + } + acc += dacc; + } + + float v = dtMathSqrtf(t); + + const float a = 1 - v; + const float b = (1 - u) * v; + const float c = u * v; + const float* pa = &pts[0]; + const float* pb = &pts[(tri-1)*3]; + const float* pc = &pts[tri*3]; + + out[0] = a*pa[0] + b*pb[0] + c*pc[0]; + out[1] = a*pa[1] + b*pb[1] + c*pc[1]; + out[2] = a*pa[2] + b*pb[2] + c*pc[2]; +} + +inline float vperpXZ(const float* a, const float* b) { return a[0]*b[2] - a[2]*b[0]; } + +bool dtIntersectSegSeg2D(const float* ap, const float* aq, + const float* bp, const float* bq, + float& s, float& t) +{ + float u[3], v[3], w[3]; + dtVsub(u,aq,ap); + dtVsub(v,bq,bp); + dtVsub(w,ap,bp); + float d = vperpXZ(u,v); + if (fabsf(d) < 1e-6f) return false; + s = vperpXZ(v,w) / d; + t = vperpXZ(u,w) / d; + return true; +} + diff --git a/libs/recast/detour/src/DetourNavMesh.cpp b/libs/recast/detour/src/DetourNavMesh.cpp new file mode 100644 index 000000000..a6557f9e8 --- /dev/null +++ b/libs/recast/detour/src/DetourNavMesh.cpp @@ -0,0 +1,1522 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#include +#include +#include "DetourNavMesh.h" +#include "DetourNode.h" +#include "DetourCommon.h" +#include "DetourMath.h" +#include "DetourAlloc.h" +#include "DetourAssert.h" +#include + + +inline bool overlapSlabs(const float* amin, const float* amax, + const float* bmin, const float* bmax, + const float px, const float py) +{ + // Check for horizontal overlap. + // The segment is shrunken a little so that slabs which touch + // at end points are not connected. + const float minx = dtMax(amin[0]+px,bmin[0]+px); + const float maxx = dtMin(amax[0]-px,bmax[0]-px); + if (minx > maxx) + return false; + + // Check vertical overlap. + const float ad = (amax[1]-amin[1]) / (amax[0]-amin[0]); + const float ak = amin[1] - ad*amin[0]; + const float bd = (bmax[1]-bmin[1]) / (bmax[0]-bmin[0]); + const float bk = bmin[1] - bd*bmin[0]; + const float aminy = ad*minx + ak; + const float amaxy = ad*maxx + ak; + const float bminy = bd*minx + bk; + const float bmaxy = bd*maxx + bk; + const float dmin = bminy - aminy; + const float dmax = bmaxy - amaxy; + + // Crossing segments always overlap. + if (dmin*dmax < 0) + return true; + + // Check for overlap at endpoints. + const float thr = dtSqr(py*2); + if (dmin*dmin <= thr || dmax*dmax <= thr) + return true; + + return false; +} + +static float getSlabCoord(const float* va, const int side) +{ + if (side == 0 || side == 4) + return va[0]; + else if (side == 2 || side == 6) + return va[2]; + return 0; +} + +static void calcSlabEndPoints(const float* va, const float* vb, float* bmin, float* bmax, const int side) +{ + if (side == 0 || side == 4) + { + if (va[2] < vb[2]) + { + bmin[0] = va[2]; + bmin[1] = va[1]; + bmax[0] = vb[2]; + bmax[1] = vb[1]; + } + else + { + bmin[0] = vb[2]; + bmin[1] = vb[1]; + bmax[0] = va[2]; + bmax[1] = va[1]; + } + } + else if (side == 2 || side == 6) + { + if (va[0] < vb[0]) + { + bmin[0] = va[0]; + bmin[1] = va[1]; + bmax[0] = vb[0]; + bmax[1] = vb[1]; + } + else + { + bmin[0] = vb[0]; + bmin[1] = vb[1]; + bmax[0] = va[0]; + bmax[1] = va[1]; + } + } +} + +inline int computeTileHash(int x, int y, const int mask) +{ + const unsigned int h1 = 0x8da6b343; // Large multiplicative constants; + const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes + unsigned int n = h1 * x + h2 * y; + return (int)(n & mask); +} + +inline unsigned int allocLink(dtMeshTile* tile) +{ + if (tile->linksFreeList == DT_NULL_LINK) + return DT_NULL_LINK; + unsigned int link = tile->linksFreeList; + tile->linksFreeList = tile->links[link].next; + return link; +} + +inline void freeLink(dtMeshTile* tile, unsigned int link) +{ + tile->links[link].next = tile->linksFreeList; + tile->linksFreeList = link; +} + + +dtNavMesh* dtAllocNavMesh() +{ + void* mem = dtAlloc(sizeof(dtNavMesh), DT_ALLOC_PERM); + if (!mem) return 0; + return new(mem) dtNavMesh; +} + +/// @par +/// +/// This function will only free the memory for tiles with the #DT_TILE_FREE_DATA +/// flag set. +void dtFreeNavMesh(dtNavMesh* navmesh) +{ + if (!navmesh) return; + navmesh->~dtNavMesh(); + dtFree(navmesh); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +/** +@class dtNavMesh + +The navigation mesh consists of one or more tiles defining three primary types of structural data: + +A polygon mesh which defines most of the navigation graph. (See rcPolyMesh for its structure.) +A detail mesh used for determining surface height on the polygon mesh. (See rcPolyMeshDetail for its structure.) +Off-mesh connections, which define custom point-to-point edges within the navigation graph. + +The general build process is as follows: + +-# Create rcPolyMesh and rcPolyMeshDetail data using the Recast build pipeline. +-# Optionally, create off-mesh connection data. +-# Combine the source data into a dtNavMeshCreateParams structure. +-# Create a tile data array using dtCreateNavMeshData(). +-# Allocate at dtNavMesh object and initialize it. (For single tile navigation meshes, + the tile data is loaded during this step.) +-# For multi-tile navigation meshes, load the tile data using dtNavMesh::addTile(). + +Notes: + +- This class is usually used in conjunction with the dtNavMeshQuery class for pathfinding. +- Technically, all navigation meshes are tiled. A 'solo' mesh is simply a navigation mesh initialized + to have only a single tile. +- This class does not implement any asynchronous methods. So the ::dtStatus result of all methods will + always contain either a success or failure flag. + +@see dtNavMeshQuery, dtCreateNavMeshData, dtNavMeshCreateParams, #dtAllocNavMesh, #dtFreeNavMesh +*/ + +dtNavMesh::dtNavMesh() : + m_tileWidth(0), + m_tileHeight(0), + m_maxTiles(0), + m_tileLutSize(0), + m_tileLutMask(0), + m_posLookup(0), + m_nextFree(0), + m_tiles(0) +{ +#ifndef DT_POLYREF64 + m_saltBits = 0; + m_tileBits = 0; + m_polyBits = 0; +#endif + memset(&m_params, 0, sizeof(dtNavMeshParams)); + m_orig[0] = 0; + m_orig[1] = 0; + m_orig[2] = 0; +} + +dtNavMesh::~dtNavMesh() +{ + for (int i = 0; i < m_maxTiles; ++i) + { + if (m_tiles[i].flags & DT_TILE_FREE_DATA) + { + dtFree(m_tiles[i].data); + m_tiles[i].data = 0; + m_tiles[i].dataSize = 0; + } + } + dtFree(m_posLookup); + dtFree(m_tiles); +} + +dtStatus dtNavMesh::init(const dtNavMeshParams* params) +{ + memcpy(&m_params, params, sizeof(dtNavMeshParams)); + dtVcopy(m_orig, params->orig); + m_tileWidth = params->tileWidth; + m_tileHeight = params->tileHeight; + + // Init tiles + m_maxTiles = params->maxTiles; + m_tileLutSize = dtNextPow2(params->maxTiles/4); + if (!m_tileLutSize) m_tileLutSize = 1; + m_tileLutMask = m_tileLutSize-1; + + m_tiles = (dtMeshTile*)dtAlloc(sizeof(dtMeshTile)*m_maxTiles, DT_ALLOC_PERM); + if (!m_tiles) + return DT_FAILURE | DT_OUT_OF_MEMORY; + m_posLookup = (dtMeshTile**)dtAlloc(sizeof(dtMeshTile*)*m_tileLutSize, DT_ALLOC_PERM); + if (!m_posLookup) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(m_tiles, 0, sizeof(dtMeshTile)*m_maxTiles); + memset(m_posLookup, 0, sizeof(dtMeshTile*)*m_tileLutSize); + m_nextFree = 0; + for (int i = m_maxTiles-1; i >= 0; --i) + { + m_tiles[i].salt = 1; + m_tiles[i].next = m_nextFree; + m_nextFree = &m_tiles[i]; + } + + // Init ID generator values. +#ifndef DT_POLYREF64 + m_tileBits = dtIlog2(dtNextPow2((unsigned int)params->maxTiles)); + m_polyBits = dtIlog2(dtNextPow2((unsigned int)params->maxPolys)); + // Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow. + m_saltBits = dtMin((unsigned int)31, 32 - m_tileBits - m_polyBits); + + if (m_saltBits < 10) + return DT_FAILURE | DT_INVALID_PARAM; +#endif + + return DT_SUCCESS; +} + +dtStatus dtNavMesh::init(unsigned char* data, const int dataSize, const int flags) +{ + // Make sure the data is in right format. + dtMeshHeader* header = (dtMeshHeader*)data; + if (header->magic != DT_NAVMESH_MAGIC) + return DT_FAILURE | DT_WRONG_MAGIC; + if (header->version != DT_NAVMESH_VERSION) + return DT_FAILURE | DT_WRONG_VERSION; + + dtNavMeshParams params; + dtVcopy(params.orig, header->bmin); + params.tileWidth = header->bmax[0] - header->bmin[0]; + params.tileHeight = header->bmax[2] - header->bmin[2]; + params.maxTiles = 1; + params.maxPolys = header->polyCount; + + dtStatus status = init(¶ms); + if (dtStatusFailed(status)) + return status; + + return addTile(data, dataSize, flags, 0, 0); +} + +/// @par +/// +/// @note The parameters are created automatically when the single tile +/// initialization is performed. +const dtNavMeshParams* dtNavMesh::getParams() const +{ + return &m_params; +} + +////////////////////////////////////////////////////////////////////////////////////////// +int dtNavMesh::findConnectingPolys(const float* va, const float* vb, + const dtMeshTile* tile, int side, + dtPolyRef* con, float* conarea, int maxcon) const +{ + if (!tile) return 0; + + float amin[2], amax[2]; + calcSlabEndPoints(va, vb, amin, amax, side); + const float apos = getSlabCoord(va, side); + + // Remove links pointing to 'side' and compact the links array. + float bmin[2], bmax[2]; + unsigned short m = DT_EXT_LINK | (unsigned short)side; + int n = 0; + + dtPolyRef base = getPolyRefBase(tile); + + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* poly = &tile->polys[i]; + const int nv = poly->vertCount; + for (int j = 0; j < nv; ++j) + { + // Skip edges which do not point to the right side. + if (poly->neis[j] != m) continue; + + const float* vc = &tile->verts[poly->verts[j]*3]; + const float* vd = &tile->verts[poly->verts[(j+1) % nv]*3]; + const float bpos = getSlabCoord(vc, side); + + // Segments are not close enough. + if (dtAbs(apos-bpos) > 0.01f) + continue; + + // Check if the segments touch. + calcSlabEndPoints(vc,vd, bmin,bmax, side); + + if (!overlapSlabs(amin,amax, bmin,bmax, 0.01f, tile->header->walkableClimb)) continue; + + // Add return value. + if (n < maxcon) + { + conarea[n*2+0] = dtMax(amin[0], bmin[0]); + conarea[n*2+1] = dtMin(amax[0], bmax[0]); + con[n] = base | (dtPolyRef)i; + n++; + } + break; + } + } + return n; +} + +void dtNavMesh::unconnectLinks(dtMeshTile* tile, dtMeshTile* target) +{ + if (!tile || !target) return; + + const unsigned int targetNum = decodePolyIdTile(getTileRef(target)); + + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* poly = &tile->polys[i]; + unsigned int j = poly->firstLink; + unsigned int pj = DT_NULL_LINK; + while (j != DT_NULL_LINK) + { + if (decodePolyIdTile(tile->links[j].ref) == targetNum) + { + // Remove link. + unsigned int nj = tile->links[j].next; + if (pj == DT_NULL_LINK) + poly->firstLink = nj; + else + tile->links[pj].next = nj; + freeLink(tile, j); + j = nj; + } + else + { + // Advance + pj = j; + j = tile->links[j].next; + } + } + } +} + +void dtNavMesh::connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side) +{ + if (!tile) return; + + // Connect border links. + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* poly = &tile->polys[i]; + + // Create new links. +// unsigned short m = DT_EXT_LINK | (unsigned short)side; + + const int nv = poly->vertCount; + for (int j = 0; j < nv; ++j) + { + // Skip non-portal edges. + if ((poly->neis[j] & DT_EXT_LINK) == 0) + continue; + + const int dir = (int)(poly->neis[j] & 0xff); + if (side != -1 && dir != side) + continue; + + // Create new links + const float* va = &tile->verts[poly->verts[j]*3]; + const float* vb = &tile->verts[poly->verts[(j+1) % nv]*3]; + dtPolyRef nei[4]; + float neia[4*2]; + int nnei = findConnectingPolys(va,vb, target, dtOppositeTile(dir), nei,neia,4); + for (int k = 0; k < nnei; ++k) + { + unsigned int idx = allocLink(tile); + if (idx != DT_NULL_LINK) + { + dtLink* link = &tile->links[idx]; + link->ref = nei[k]; + link->edge = (unsigned char)j; + link->side = (unsigned char)dir; + + link->next = poly->firstLink; + poly->firstLink = idx; + + // Compress portal limits to a byte value. + if (dir == 0 || dir == 4) + { + float tmin = (neia[k*2+0]-va[2]) / (vb[2]-va[2]); + float tmax = (neia[k*2+1]-va[2]) / (vb[2]-va[2]); + if (tmin > tmax) + dtSwap(tmin,tmax); + link->bmin = (unsigned char)(dtClamp(tmin, 0.0f, 1.0f)*255.0f); + link->bmax = (unsigned char)(dtClamp(tmax, 0.0f, 1.0f)*255.0f); + } + else if (dir == 2 || dir == 6) + { + float tmin = (neia[k*2+0]-va[0]) / (vb[0]-va[0]); + float tmax = (neia[k*2+1]-va[0]) / (vb[0]-va[0]); + if (tmin > tmax) + dtSwap(tmin,tmax); + link->bmin = (unsigned char)(dtClamp(tmin, 0.0f, 1.0f)*255.0f); + link->bmax = (unsigned char)(dtClamp(tmax, 0.0f, 1.0f)*255.0f); + } + } + } + } + } +} + +void dtNavMesh::connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int side) +{ + if (!tile) return; + + // Connect off-mesh links. + // We are interested on links which land from target tile to this tile. + const unsigned char oppositeSide = (side == -1) ? 0xff : (unsigned char)dtOppositeTile(side); + + for (int i = 0; i < target->header->offMeshConCount; ++i) + { + dtOffMeshConnection* targetCon = &target->offMeshCons[i]; + if (targetCon->side != oppositeSide) + continue; + + dtPoly* targetPoly = &target->polys[targetCon->poly]; + // Skip off-mesh connections which start location could not be connected at all. + if (targetPoly->firstLink == DT_NULL_LINK) + continue; + + const float ext[3] = { targetCon->rad, target->header->walkableClimb, targetCon->rad }; + + // Find polygon to connect to. + const float* p = &targetCon->pos[3]; + float nearestPt[3]; + dtPolyRef ref = findNearestPolyInTile(tile, p, ext, nearestPt); + if (!ref) + continue; + // findNearestPoly may return too optimistic results, further check to make sure. + if (dtSqr(nearestPt[0]-p[0])+dtSqr(nearestPt[2]-p[2]) > dtSqr(targetCon->rad)) + continue; + // Make sure the location is on current mesh. + float* v = &target->verts[targetPoly->verts[1]*3]; + dtVcopy(v, nearestPt); + + // Link off-mesh connection to target poly. + unsigned int idx = allocLink(target); + if (idx != DT_NULL_LINK) + { + dtLink* link = &target->links[idx]; + link->ref = ref; + link->edge = (unsigned char)1; + link->side = oppositeSide; + link->bmin = link->bmax = 0; + // Add to linked list. + link->next = targetPoly->firstLink; + targetPoly->firstLink = idx; + } + + // Link target poly to off-mesh connection. + if (targetCon->flags & DT_OFFMESH_CON_BIDIR) + { + unsigned int tidx = allocLink(tile); + if (tidx != DT_NULL_LINK) + { + const unsigned short landPolyIdx = (unsigned short)decodePolyIdPoly(ref); + dtPoly* landPoly = &tile->polys[landPolyIdx]; + dtLink* link = &tile->links[tidx]; + link->ref = getPolyRefBase(target) | (dtPolyRef)(targetCon->poly); + link->edge = 0xff; + link->side = (unsigned char)(side == -1 ? 0xff : side); + link->bmin = link->bmax = 0; + // Add to linked list. + link->next = landPoly->firstLink; + landPoly->firstLink = tidx; + } + } + } + +} + +void dtNavMesh::connectIntLinks(dtMeshTile* tile) +{ + if (!tile) return; + + dtPolyRef base = getPolyRefBase(tile); + + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* poly = &tile->polys[i]; + poly->firstLink = DT_NULL_LINK; + + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + + // Build edge links backwards so that the links will be + // in the linked list from lowest index to highest. + for (int j = poly->vertCount-1; j >= 0; --j) + { + // Skip hard and non-internal edges. + if (poly->neis[j] == 0 || (poly->neis[j] & DT_EXT_LINK)) continue; + + unsigned int idx = allocLink(tile); + if (idx != DT_NULL_LINK) + { + dtLink* link = &tile->links[idx]; + link->ref = base | (dtPolyRef)(poly->neis[j]-1); + link->edge = (unsigned char)j; + link->side = 0xff; + link->bmin = link->bmax = 0; + // Add to linked list. + link->next = poly->firstLink; + poly->firstLink = idx; + } + } + } +} + +void dtNavMesh::baseOffMeshLinks(dtMeshTile* tile) +{ + if (!tile) return; + + dtPolyRef base = getPolyRefBase(tile); + + // Base off-mesh connection start points. + for (int i = 0; i < tile->header->offMeshConCount; ++i) + { + dtOffMeshConnection* con = &tile->offMeshCons[i]; + dtPoly* poly = &tile->polys[con->poly]; + + const float ext[3] = { con->rad, tile->header->walkableClimb, con->rad }; + + // Find polygon to connect to. + const float* p = &con->pos[0]; // First vertex + float nearestPt[3]; + dtPolyRef ref = findNearestPolyInTile(tile, p, ext, nearestPt); + if (!ref) continue; + // findNearestPoly may return too optimistic results, further check to make sure. + if (dtSqr(nearestPt[0]-p[0])+dtSqr(nearestPt[2]-p[2]) > dtSqr(con->rad)) + continue; + // Make sure the location is on current mesh. + float* v = &tile->verts[poly->verts[0]*3]; + dtVcopy(v, nearestPt); + + // Link off-mesh connection to target poly. + unsigned int idx = allocLink(tile); + if (idx != DT_NULL_LINK) + { + dtLink* link = &tile->links[idx]; + link->ref = ref; + link->edge = (unsigned char)0; + link->side = 0xff; + link->bmin = link->bmax = 0; + // Add to linked list. + link->next = poly->firstLink; + poly->firstLink = idx; + } + + // Start end-point is always connect back to off-mesh connection. + unsigned int tidx = allocLink(tile); + if (tidx != DT_NULL_LINK) + { + const unsigned short landPolyIdx = (unsigned short)decodePolyIdPoly(ref); + dtPoly* landPoly = &tile->polys[landPolyIdx]; + dtLink* link = &tile->links[tidx]; + link->ref = base | (dtPolyRef)(con->poly); + link->edge = 0xff; + link->side = 0xff; + link->bmin = link->bmax = 0; + // Add to linked list. + link->next = landPoly->firstLink; + landPoly->firstLink = tidx; + } + } +} + +void dtNavMesh::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly) const +{ + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + getTileAndPolyByRefUnsafe(ref, &tile, &poly); + + // Off-mesh connections don't have detail polygons. + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + const float* v0 = &tile->verts[poly->verts[0]*3]; + const float* v1 = &tile->verts[poly->verts[1]*3]; + const float d0 = dtVdist(pos, v0); + const float d1 = dtVdist(pos, v1); + const float u = d0 / (d0+d1); + dtVlerp(closest, v0, v1, u); + if (posOverPoly) + *posOverPoly = false; + return; + } + + const unsigned int ip = (unsigned int)(poly - tile->polys); + const dtPolyDetail* pd = &tile->detailMeshes[ip]; + + // Clamp point to be inside the polygon. + float verts[DT_VERTS_PER_POLYGON*3]; + float edged[DT_VERTS_PER_POLYGON]; + float edget[DT_VERTS_PER_POLYGON]; + const int nv = poly->vertCount; + for (int i = 0; i < nv; ++i) + dtVcopy(&verts[i*3], &tile->verts[poly->verts[i]*3]); + + dtVcopy(closest, pos); + if (!dtDistancePtPolyEdgesSqr(pos, verts, nv, edged, edget)) + { + // Point is outside the polygon, dtClamp to nearest edge. + float dmin = edged[0]; + int imin = 0; + for (int i = 1; i < nv; ++i) + { + if (edged[i] < dmin) + { + dmin = edged[i]; + imin = i; + } + } + const float* va = &verts[imin*3]; + const float* vb = &verts[((imin+1)%nv)*3]; + dtVlerp(closest, va, vb, edget[imin]); + + if (posOverPoly) + *posOverPoly = false; + } + else + { + if (posOverPoly) + *posOverPoly = true; + } + + // Find height at the location. + for (int j = 0; j < pd->triCount; ++j) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4]; + const float* v[3]; + for (int k = 0; k < 3; ++k) + { + if (t[k] < poly->vertCount) + v[k] = &tile->verts[poly->verts[t[k]]*3]; + else + v[k] = &tile->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3]; + } + float h; + if (dtClosestHeightPointTriangle(closest, v[0], v[1], v[2], h)) + { + closest[1] = h; + break; + } + } +} + +dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile, + const float* center, const float* extents, + float* nearestPt) const +{ + float bmin[3], bmax[3]; + dtVsub(bmin, center, extents); + dtVadd(bmax, center, extents); + + // Get nearby polygons from proximity grid. + dtPolyRef polys[128]; + int polyCount = queryPolygonsInTile(tile, bmin, bmax, polys, 128); + + // Find nearest polygon amongst the nearby polygons. + dtPolyRef nearest = 0; + float nearestDistanceSqr = FLT_MAX; + for (int i = 0; i < polyCount; ++i) + { + dtPolyRef ref = polys[i]; + float closestPtPoly[3]; + float diff[3]; + bool posOverPoly = false; + float d; + closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly); + + // If a point is directly over a polygon and closer than + // climb height, favor that instead of straight line nearest point. + dtVsub(diff, center, closestPtPoly); + if (posOverPoly) + { + d = dtAbs(diff[1]) - tile->header->walkableClimb; + d = d > 0 ? d*d : 0; + } + else + { + d = dtVlenSqr(diff); + } + + if (d < nearestDistanceSqr) + { + dtVcopy(nearestPt, closestPtPoly); + nearestDistanceSqr = d; + nearest = ref; + } + } + + return nearest; +} + +int dtNavMesh::queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax, + dtPolyRef* polys, const int maxPolys) const +{ + if (tile->bvTree) + { + const dtBVNode* node = &tile->bvTree[0]; + const dtBVNode* end = &tile->bvTree[tile->header->bvNodeCount]; + const float* tbmin = tile->header->bmin; + const float* tbmax = tile->header->bmax; + const float qfac = tile->header->bvQuantFactor; + + // Calculate quantized box + unsigned short bmin[3], bmax[3]; + // dtClamp query box to world box. + float minx = dtClamp(qmin[0], tbmin[0], tbmax[0]) - tbmin[0]; + float miny = dtClamp(qmin[1], tbmin[1], tbmax[1]) - tbmin[1]; + float minz = dtClamp(qmin[2], tbmin[2], tbmax[2]) - tbmin[2]; + float maxx = dtClamp(qmax[0], tbmin[0], tbmax[0]) - tbmin[0]; + float maxy = dtClamp(qmax[1], tbmin[1], tbmax[1]) - tbmin[1]; + float maxz = dtClamp(qmax[2], tbmin[2], tbmax[2]) - tbmin[2]; + // Quantize + bmin[0] = (unsigned short)(qfac * minx) & 0xfffe; + bmin[1] = (unsigned short)(qfac * miny) & 0xfffe; + bmin[2] = (unsigned short)(qfac * minz) & 0xfffe; + bmax[0] = (unsigned short)(qfac * maxx + 1) | 1; + bmax[1] = (unsigned short)(qfac * maxy + 1) | 1; + bmax[2] = (unsigned short)(qfac * maxz + 1) | 1; + + // Traverse tree + dtPolyRef base = getPolyRefBase(tile); + int n = 0; + while (node < end) + { + const bool overlap = dtOverlapQuantBounds(bmin, bmax, node->bmin, node->bmax); + const bool isLeafNode = node->i >= 0; + + if (isLeafNode && overlap) + { + if (n < maxPolys) + polys[n++] = base | (dtPolyRef)node->i; + } + + if (overlap || isLeafNode) + node++; + else + { + const int escapeIndex = -node->i; + node += escapeIndex; + } + } + + return n; + } + else + { + float bmin[3], bmax[3]; + int n = 0; + dtPolyRef base = getPolyRefBase(tile); + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* p = &tile->polys[i]; + // Do not return off-mesh connection polygons. + if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + // Calc polygon bounds. + const float* v = &tile->verts[p->verts[0]*3]; + dtVcopy(bmin, v); + dtVcopy(bmax, v); + for (int j = 1; j < p->vertCount; ++j) + { + v = &tile->verts[p->verts[j]*3]; + dtVmin(bmin, v); + dtVmax(bmax, v); + } + if (dtOverlapBounds(qmin,qmax, bmin,bmax)) + { + if (n < maxPolys) + polys[n++] = base | (dtPolyRef)i; + } + } + return n; + } +} + +/// @par +/// +/// The add operation will fail if the data is in the wrong format, the allocated tile +/// space is full, or there is a tile already at the specified reference. +/// +/// The lastRef parameter is used to restore a tile with the same tile +/// reference it had previously used. In this case the #dtPolyRef's for the +/// tile will be restored to the same values they were before the tile was +/// removed. +/// +/// The nav mesh assumes exclusive access to the data passed and will make +/// changes to the dynamic portion of the data. For that reason the data +/// should not be reused in other nav meshes until the tile has been successfully +/// removed from this nav mesh. +/// +/// @see dtCreateNavMeshData, #removeTile +dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, + dtTileRef lastRef, dtTileRef* result) +{ + // Make sure the data is in right format. + dtMeshHeader* header = (dtMeshHeader*)data; + if (header->magic != DT_NAVMESH_MAGIC) + return DT_FAILURE | DT_WRONG_MAGIC; + if (header->version != DT_NAVMESH_VERSION) + return DT_FAILURE | DT_WRONG_VERSION; + + // Make sure the location is free. + if (getTileAt(header->x, header->y, header->layer)) + return DT_FAILURE; + + // Allocate a tile. + dtMeshTile* tile = 0; + if (!lastRef) + { + if (m_nextFree) + { + tile = m_nextFree; + m_nextFree = tile->next; + tile->next = 0; + } + } + else + { + // Try to relocate the tile to specific index with same salt. + int tileIndex = (int)decodePolyIdTile((dtPolyRef)lastRef); + if (tileIndex >= m_maxTiles) + return DT_FAILURE | DT_OUT_OF_MEMORY; + // Try to find the specific tile id from the free list. + dtMeshTile* target = &m_tiles[tileIndex]; + dtMeshTile* prev = 0; + tile = m_nextFree; + while (tile && tile != target) + { + prev = tile; + tile = tile->next; + } + // Could not find the correct location. + if (tile != target) + return DT_FAILURE | DT_OUT_OF_MEMORY; + // Remove from freelist + if (!prev) + m_nextFree = tile->next; + else + prev->next = tile->next; + + // Restore salt. + tile->salt = decodePolyIdSalt((dtPolyRef)lastRef); + } + + // Make sure we could allocate a tile. + if (!tile) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + // Insert tile into the position lut. + int h = computeTileHash(header->x, header->y, m_tileLutMask); + tile->next = m_posLookup[h]; + m_posLookup[h] = tile; + + // Patch header pointers. + const int headerSize = dtAlign4(sizeof(dtMeshHeader)); + const int vertsSize = dtAlign4(sizeof(float)*3*header->vertCount); + const int polysSize = dtAlign4(sizeof(dtPoly)*header->polyCount); + const int linksSize = dtAlign4(sizeof(dtLink)*(header->maxLinkCount)); + const int detailMeshesSize = dtAlign4(sizeof(dtPolyDetail)*header->detailMeshCount); + const int detailVertsSize = dtAlign4(sizeof(float)*3*header->detailVertCount); + const int detailTrisSize = dtAlign4(sizeof(unsigned char)*4*header->detailTriCount); + const int bvtreeSize = dtAlign4(sizeof(dtBVNode)*header->bvNodeCount); + const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount); + + unsigned char* d = data + headerSize; + tile->verts = dtGetThenAdvanceBufferPointer(d, vertsSize); + tile->polys = dtGetThenAdvanceBufferPointer(d, polysSize); + tile->links = dtGetThenAdvanceBufferPointer(d, linksSize); + tile->detailMeshes = dtGetThenAdvanceBufferPointer(d, detailMeshesSize); + tile->detailVerts = dtGetThenAdvanceBufferPointer(d, detailVertsSize); + tile->detailTris = dtGetThenAdvanceBufferPointer(d, detailTrisSize); + tile->bvTree = dtGetThenAdvanceBufferPointer(d, bvtreeSize); + tile->offMeshCons = dtGetThenAdvanceBufferPointer(d, offMeshLinksSize); + + // If there are no items in the bvtree, reset the tree pointer. + if (!bvtreeSize) + tile->bvTree = 0; + + // Build links freelist + tile->linksFreeList = 0; + tile->links[header->maxLinkCount-1].next = DT_NULL_LINK; + for (int i = 0; i < header->maxLinkCount-1; ++i) + tile->links[i].next = i+1; + + // Init tile. + tile->header = header; + tile->data = data; + tile->dataSize = dataSize; + tile->flags = flags; + + connectIntLinks(tile); + + // Base off-mesh connections to their starting polygons and connect connections inside the tile. + baseOffMeshLinks(tile); + connectExtOffMeshLinks(tile, tile, -1); + + // Create connections with neighbour tiles. + static const int MAX_NEIS = 32; + dtMeshTile* neis[MAX_NEIS]; + int nneis; + + // Connect with layers in current tile. + nneis = getTilesAt(header->x, header->y, neis, MAX_NEIS); + for (int j = 0; j < nneis; ++j) + { + if (neis[j] == tile) + continue; + + connectExtLinks(tile, neis[j], -1); + connectExtLinks(neis[j], tile, -1); + connectExtOffMeshLinks(tile, neis[j], -1); + connectExtOffMeshLinks(neis[j], tile, -1); + } + + // Connect with neighbour tiles. + for (int i = 0; i < 8; ++i) + { + nneis = getNeighbourTilesAt(header->x, header->y, i, neis, MAX_NEIS); + for (int j = 0; j < nneis; ++j) + { + connectExtLinks(tile, neis[j], i); + connectExtLinks(neis[j], tile, dtOppositeTile(i)); + connectExtOffMeshLinks(tile, neis[j], i); + connectExtOffMeshLinks(neis[j], tile, dtOppositeTile(i)); + } + } + + if (result) + *result = getTileRef(tile); + + return DT_SUCCESS; +} + +const dtMeshTile* dtNavMesh::getTileAt(const int x, const int y, const int layer) const +{ + // Find tile based on hash. + int h = computeTileHash(x,y,m_tileLutMask); + dtMeshTile* tile = m_posLookup[h]; + while (tile) + { + if (tile->header && + tile->header->x == x && + tile->header->y == y && + tile->header->layer == layer) + { + return tile; + } + tile = tile->next; + } + return 0; +} + +int dtNavMesh::getNeighbourTilesAt(const int x, const int y, const int side, dtMeshTile** tiles, const int maxTiles) const +{ + int nx = x, ny = y; + switch (side) + { + case 0: nx++; break; + case 1: nx++; ny++; break; + case 2: ny++; break; + case 3: nx--; ny++; break; + case 4: nx--; break; + case 5: nx--; ny--; break; + case 6: ny--; break; + case 7: nx++; ny--; break; + }; + + return getTilesAt(nx, ny, tiles, maxTiles); +} + +int dtNavMesh::getTilesAt(const int x, const int y, dtMeshTile** tiles, const int maxTiles) const +{ + int n = 0; + + // Find tile based on hash. + int h = computeTileHash(x,y,m_tileLutMask); + dtMeshTile* tile = m_posLookup[h]; + while (tile) + { + if (tile->header && + tile->header->x == x && + tile->header->y == y) + { + if (n < maxTiles) + tiles[n++] = tile; + } + tile = tile->next; + } + + return n; +} + +/// @par +/// +/// This function will not fail if the tiles array is too small to hold the +/// entire result set. It will simply fill the array to capacity. +int dtNavMesh::getTilesAt(const int x, const int y, dtMeshTile const** tiles, const int maxTiles) const +{ + int n = 0; + + // Find tile based on hash. + int h = computeTileHash(x,y,m_tileLutMask); + dtMeshTile* tile = m_posLookup[h]; + while (tile) + { + if (tile->header && + tile->header->x == x && + tile->header->y == y) + { + if (n < maxTiles) + tiles[n++] = tile; + } + tile = tile->next; + } + + return n; +} + + +dtTileRef dtNavMesh::getTileRefAt(const int x, const int y, const int layer) const +{ + // Find tile based on hash. + int h = computeTileHash(x,y,m_tileLutMask); + dtMeshTile* tile = m_posLookup[h]; + while (tile) + { + if (tile->header && + tile->header->x == x && + tile->header->y == y && + tile->header->layer == layer) + { + return getTileRef(tile); + } + tile = tile->next; + } + return 0; +} + +const dtMeshTile* dtNavMesh::getTileByRef(dtTileRef ref) const +{ + if (!ref) + return 0; + unsigned int tileIndex = decodePolyIdTile((dtPolyRef)ref); + unsigned int tileSalt = decodePolyIdSalt((dtPolyRef)ref); + if ((int)tileIndex >= m_maxTiles) + return 0; + const dtMeshTile* tile = &m_tiles[tileIndex]; + if (tile->salt != tileSalt) + return 0; + return tile; +} + +int dtNavMesh::getMaxTiles() const +{ + return m_maxTiles; +} + +dtMeshTile* dtNavMesh::getTile(int i) +{ + return &m_tiles[i]; +} + +const dtMeshTile* dtNavMesh::getTile(int i) const +{ + return &m_tiles[i]; +} + +void dtNavMesh::calcTileLoc(const float* pos, int* tx, int* ty) const +{ + *tx = (int)floorf((pos[0]-m_orig[0]) / m_tileWidth); + *ty = (int)floorf((pos[2]-m_orig[2]) / m_tileHeight); +} + +dtStatus dtNavMesh::getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const +{ + if (!ref) return DT_FAILURE; + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return DT_FAILURE | DT_INVALID_PARAM; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE | DT_INVALID_PARAM; + if (ip >= (unsigned int)m_tiles[it].header->polyCount) return DT_FAILURE | DT_INVALID_PARAM; + *tile = &m_tiles[it]; + *poly = &m_tiles[it].polys[ip]; + return DT_SUCCESS; +} + +/// @par +/// +/// @warning Only use this function if it is known that the provided polygon +/// reference is valid. This function is faster than #getTileAndPolyByRef, but +/// it does not validate the reference. +void dtNavMesh::getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const +{ + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + *tile = &m_tiles[it]; + *poly = &m_tiles[it].polys[ip]; +} + +bool dtNavMesh::isValidPolyRef(dtPolyRef ref) const +{ + if (!ref) return false; + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return false; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false; + if (ip >= (unsigned int)m_tiles[it].header->polyCount) return false; + return true; +} + +/// @par +/// +/// This function returns the data for the tile so that, if desired, +/// it can be added back to the navigation mesh at a later point. +/// +/// @see #addTile +dtStatus dtNavMesh::removeTile(dtTileRef ref, unsigned char** data, int* dataSize) +{ + if (!ref) + return DT_FAILURE | DT_INVALID_PARAM; + unsigned int tileIndex = decodePolyIdTile((dtPolyRef)ref); + unsigned int tileSalt = decodePolyIdSalt((dtPolyRef)ref); + if ((int)tileIndex >= m_maxTiles) + return DT_FAILURE | DT_INVALID_PARAM; + dtMeshTile* tile = &m_tiles[tileIndex]; + if (tile->salt != tileSalt) + return DT_FAILURE | DT_INVALID_PARAM; + + // Remove tile from hash lookup. + int h = computeTileHash(tile->header->x,tile->header->y,m_tileLutMask); + dtMeshTile* prev = 0; + dtMeshTile* cur = m_posLookup[h]; + while (cur) + { + if (cur == tile) + { + if (prev) + prev->next = cur->next; + else + m_posLookup[h] = cur->next; + break; + } + prev = cur; + cur = cur->next; + } + + // Remove connections to neighbour tiles. + static const int MAX_NEIS = 32; + dtMeshTile* neis[MAX_NEIS]; + int nneis; + + // Disconnect from other layers in current tile. + nneis = getTilesAt(tile->header->x, tile->header->y, neis, MAX_NEIS); + for (int j = 0; j < nneis; ++j) + { + if (neis[j] == tile) continue; + unconnectLinks(neis[j], tile); + } + + // Disconnect from neighbour tiles. + for (int i = 0; i < 8; ++i) + { + nneis = getNeighbourTilesAt(tile->header->x, tile->header->y, i, neis, MAX_NEIS); + for (int j = 0; j < nneis; ++j) + unconnectLinks(neis[j], tile); + } + + // Reset tile. + if (tile->flags & DT_TILE_FREE_DATA) + { + // Owns data + dtFree(tile->data); + tile->data = 0; + tile->dataSize = 0; + if (data) *data = 0; + if (dataSize) *dataSize = 0; + } + else + { + if (data) *data = tile->data; + if (dataSize) *dataSize = tile->dataSize; + } + + tile->header = 0; + tile->flags = 0; + tile->linksFreeList = 0; + tile->polys = 0; + tile->verts = 0; + tile->links = 0; + tile->detailMeshes = 0; + tile->detailVerts = 0; + tile->detailTris = 0; + tile->bvTree = 0; + tile->offMeshCons = 0; + + // Update salt, salt should never be zero. +#ifdef DT_POLYREF64 + tile->salt = (tile->salt+1) & ((1<salt = (tile->salt+1) & ((1<salt == 0) + tile->salt++; + + // Add to free list. + tile->next = m_nextFree; + m_nextFree = tile; + + return DT_SUCCESS; +} + +dtTileRef dtNavMesh::getTileRef(const dtMeshTile* tile) const +{ + if (!tile) return 0; + const unsigned int it = (unsigned int)(tile - m_tiles); + return (dtTileRef)encodePolyId(tile->salt, it, 0); +} + +/// @par +/// +/// Example use case: +/// @code +/// +/// const dtPolyRef base = navmesh->getPolyRefBase(tile); +/// for (int i = 0; i < tile->header->polyCount; ++i) +/// { +/// const dtPoly* p = &tile->polys[i]; +/// const dtPolyRef ref = base | (dtPolyRef)i; +/// +/// // Use the reference to access the polygon data. +/// } +/// @endcode +dtPolyRef dtNavMesh::getPolyRefBase(const dtMeshTile* tile) const +{ + if (!tile) return 0; + const unsigned int it = (unsigned int)(tile - m_tiles); + return encodePolyId(tile->salt, it, 0); +} + +struct dtTileState +{ + int magic; // Magic number, used to identify the data. + int version; // Data version number. + dtTileRef ref; // Tile ref at the time of storing the data. +}; + +struct dtPolyState +{ + unsigned short flags; // Flags (see dtPolyFlags). + unsigned char area; // Area ID of the polygon. +}; + +/// @see #storeTileState +int dtNavMesh::getTileStateSize(const dtMeshTile* tile) const +{ + if (!tile) return 0; + const int headerSize = dtAlign4(sizeof(dtTileState)); + const int polyStateSize = dtAlign4(sizeof(dtPolyState) * tile->header->polyCount); + return headerSize + polyStateSize; +} + +/// @par +/// +/// Tile state includes non-structural data such as polygon flags, area ids, etc. +/// @note The state data is only valid until the tile reference changes. +/// @see #getTileStateSize, #restoreTileState +dtStatus dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const +{ + // Make sure there is enough space to store the state. + const int sizeReq = getTileStateSize(tile); + if (maxDataSize < sizeReq) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + + dtTileState* tileState = dtGetThenAdvanceBufferPointer(data, dtAlign4(sizeof(dtTileState))); + dtPolyState* polyStates = dtGetThenAdvanceBufferPointer(data, dtAlign4(sizeof(dtPolyState) * tile->header->polyCount)); + + // Store tile state. + tileState->magic = DT_NAVMESH_STATE_MAGIC; + tileState->version = DT_NAVMESH_STATE_VERSION; + tileState->ref = getTileRef(tile); + + // Store per poly state. + for (int i = 0; i < tile->header->polyCount; ++i) + { + const dtPoly* p = &tile->polys[i]; + dtPolyState* s = &polyStates[i]; + s->flags = p->flags; + s->area = p->getArea(); + } + + return DT_SUCCESS; +} + +/// @par +/// +/// Tile state includes non-structural data such as polygon flags, area ids, etc. +/// @note This function does not impact the tile's #dtTileRef and #dtPolyRef's. +/// @see #storeTileState +dtStatus dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize) +{ + // Make sure there is enough space to store the state. + const int sizeReq = getTileStateSize(tile); + if (maxDataSize < sizeReq) + return DT_FAILURE | DT_INVALID_PARAM; + + const dtTileState* tileState = dtGetThenAdvanceBufferPointer(data, dtAlign4(sizeof(dtTileState))); + const dtPolyState* polyStates = dtGetThenAdvanceBufferPointer(data, dtAlign4(sizeof(dtPolyState) * tile->header->polyCount)); + + // Check that the restore is possible. + if (tileState->magic != DT_NAVMESH_STATE_MAGIC) + return DT_FAILURE | DT_WRONG_MAGIC; + if (tileState->version != DT_NAVMESH_STATE_VERSION) + return DT_FAILURE | DT_WRONG_VERSION; + if (tileState->ref != getTileRef(tile)) + return DT_FAILURE | DT_INVALID_PARAM; + + // Restore per poly state. + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* p = &tile->polys[i]; + const dtPolyState* s = &polyStates[i]; + p->flags = s->flags; + p->setArea(s->area); + } + + return DT_SUCCESS; +} + +/// @par +/// +/// Off-mesh connections are stored in the navigation mesh as special 2-vertex +/// polygons with a single edge. At least one of the vertices is expected to be +/// inside a normal polygon. So an off-mesh connection is "entered" from a +/// normal polygon at one of its endpoints. This is the polygon identified by +/// the prevRef parameter. +dtStatus dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const +{ + unsigned int salt, it, ip; + + if (!polyRef) + return DT_FAILURE; + + // Get current polygon + decodePolyId(polyRef, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return DT_FAILURE | DT_INVALID_PARAM; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE | DT_INVALID_PARAM; + const dtMeshTile* tile = &m_tiles[it]; + if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE | DT_INVALID_PARAM; + const dtPoly* poly = &tile->polys[ip]; + + // Make sure that the current poly is indeed off-mesh link. + if (poly->getType() != DT_POLYTYPE_OFFMESH_CONNECTION) + return DT_FAILURE; + + // Figure out which way to hand out the vertices. + int idx0 = 0, idx1 = 1; + + // Find link that points to first vertex. + for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = tile->links[i].next) + { + if (tile->links[i].edge == 0) + { + if (tile->links[i].ref != prevRef) + { + idx0 = 1; + idx1 = 0; + } + break; + } + } + + dtVcopy(startPos, &tile->verts[poly->verts[idx0]*3]); + dtVcopy(endPos, &tile->verts[poly->verts[idx1]*3]); + + return DT_SUCCESS; +} + + +const dtOffMeshConnection* dtNavMesh::getOffMeshConnectionByRef(dtPolyRef ref) const +{ + unsigned int salt, it, ip; + + if (!ref) + return 0; + + // Get current polygon + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return 0; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0; + const dtMeshTile* tile = &m_tiles[it]; + if (ip >= (unsigned int)tile->header->polyCount) return 0; + const dtPoly* poly = &tile->polys[ip]; + + // Make sure that the current poly is indeed off-mesh link. + if (poly->getType() != DT_POLYTYPE_OFFMESH_CONNECTION) + return 0; + + const unsigned int idx = ip - tile->header->offMeshBase; + dtAssert(idx < (unsigned int)tile->header->offMeshConCount); + return &tile->offMeshCons[idx]; +} + + +dtStatus dtNavMesh::setPolyFlags(dtPolyRef ref, unsigned short flags) +{ + if (!ref) return DT_FAILURE; + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return DT_FAILURE | DT_INVALID_PARAM; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE | DT_INVALID_PARAM; + dtMeshTile* tile = &m_tiles[it]; + if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE | DT_INVALID_PARAM; + dtPoly* poly = &tile->polys[ip]; + + // Change flags. + poly->flags = flags; + + return DT_SUCCESS; +} + +dtStatus dtNavMesh::getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const +{ + if (!ref) return DT_FAILURE; + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return DT_FAILURE | DT_INVALID_PARAM; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE | DT_INVALID_PARAM; + const dtMeshTile* tile = &m_tiles[it]; + if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE | DT_INVALID_PARAM; + const dtPoly* poly = &tile->polys[ip]; + + *resultFlags = poly->flags; + + return DT_SUCCESS; +} + +dtStatus dtNavMesh::setPolyArea(dtPolyRef ref, unsigned char area) +{ + if (!ref) return DT_FAILURE; + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return DT_FAILURE | DT_INVALID_PARAM; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE | DT_INVALID_PARAM; + dtMeshTile* tile = &m_tiles[it]; + if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE | DT_INVALID_PARAM; + dtPoly* poly = &tile->polys[ip]; + + poly->setArea(area); + + return DT_SUCCESS; +} + +dtStatus dtNavMesh::getPolyArea(dtPolyRef ref, unsigned char* resultArea) const +{ + if (!ref) return DT_FAILURE; + unsigned int salt, it, ip; + decodePolyId(ref, salt, it, ip); + if (it >= (unsigned int)m_maxTiles) return DT_FAILURE | DT_INVALID_PARAM; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE | DT_INVALID_PARAM; + const dtMeshTile* tile = &m_tiles[it]; + if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE | DT_INVALID_PARAM; + const dtPoly* poly = &tile->polys[ip]; + + *resultArea = poly->getArea(); + + return DT_SUCCESS; +} + diff --git a/libs/recast/detour/src/DetourNavMeshBuilder.cpp b/libs/recast/detour/src/DetourNavMeshBuilder.cpp new file mode 100644 index 000000000..e93a97629 --- /dev/null +++ b/libs/recast/detour/src/DetourNavMeshBuilder.cpp @@ -0,0 +1,802 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#include +#include +#include +#include "DetourNavMesh.h" +#include "DetourCommon.h" +#include "DetourMath.h" +#include "DetourNavMeshBuilder.h" +#include "DetourAlloc.h" +#include "DetourAssert.h" + +static unsigned short MESH_NULL_IDX = 0xffff; + + +struct BVItem +{ + unsigned short bmin[3]; + unsigned short bmax[3]; + int i; +}; + +static int compareItemX(const void* va, const void* vb) +{ + const BVItem* a = (const BVItem*)va; + const BVItem* b = (const BVItem*)vb; + if (a->bmin[0] < b->bmin[0]) + return -1; + if (a->bmin[0] > b->bmin[0]) + return 1; + return 0; +} + +static int compareItemY(const void* va, const void* vb) +{ + const BVItem* a = (const BVItem*)va; + const BVItem* b = (const BVItem*)vb; + if (a->bmin[1] < b->bmin[1]) + return -1; + if (a->bmin[1] > b->bmin[1]) + return 1; + return 0; +} + +static int compareItemZ(const void* va, const void* vb) +{ + const BVItem* a = (const BVItem*)va; + const BVItem* b = (const BVItem*)vb; + if (a->bmin[2] < b->bmin[2]) + return -1; + if (a->bmin[2] > b->bmin[2]) + return 1; + return 0; +} + +static void calcExtends(BVItem* items, const int /*nitems*/, const int imin, const int imax, + unsigned short* bmin, unsigned short* bmax) +{ + bmin[0] = items[imin].bmin[0]; + bmin[1] = items[imin].bmin[1]; + bmin[2] = items[imin].bmin[2]; + + bmax[0] = items[imin].bmax[0]; + bmax[1] = items[imin].bmax[1]; + bmax[2] = items[imin].bmax[2]; + + for (int i = imin+1; i < imax; ++i) + { + const BVItem& it = items[i]; + if (it.bmin[0] < bmin[0]) bmin[0] = it.bmin[0]; + if (it.bmin[1] < bmin[1]) bmin[1] = it.bmin[1]; + if (it.bmin[2] < bmin[2]) bmin[2] = it.bmin[2]; + + if (it.bmax[0] > bmax[0]) bmax[0] = it.bmax[0]; + if (it.bmax[1] > bmax[1]) bmax[1] = it.bmax[1]; + if (it.bmax[2] > bmax[2]) bmax[2] = it.bmax[2]; + } +} + +inline int longestAxis(unsigned short x, unsigned short y, unsigned short z) +{ + int axis = 0; + unsigned short maxVal = x; + if (y > maxVal) + { + axis = 1; + maxVal = y; + } + if (z > maxVal) + { + axis = 2; + } + return axis; +} + +static void subdivide(BVItem* items, int nitems, int imin, int imax, int& curNode, dtBVNode* nodes) +{ + int inum = imax - imin; + int icur = curNode; + + dtBVNode& node = nodes[curNode++]; + + if (inum == 1) + { + // Leaf + node.bmin[0] = items[imin].bmin[0]; + node.bmin[1] = items[imin].bmin[1]; + node.bmin[2] = items[imin].bmin[2]; + + node.bmax[0] = items[imin].bmax[0]; + node.bmax[1] = items[imin].bmax[1]; + node.bmax[2] = items[imin].bmax[2]; + + node.i = items[imin].i; + } + else + { + // Split + calcExtends(items, nitems, imin, imax, node.bmin, node.bmax); + + int axis = longestAxis(node.bmax[0] - node.bmin[0], + node.bmax[1] - node.bmin[1], + node.bmax[2] - node.bmin[2]); + + if (axis == 0) + { + // Sort along x-axis + qsort(items+imin, inum, sizeof(BVItem), compareItemX); + } + else if (axis == 1) + { + // Sort along y-axis + qsort(items+imin, inum, sizeof(BVItem), compareItemY); + } + else + { + // Sort along z-axis + qsort(items+imin, inum, sizeof(BVItem), compareItemZ); + } + + int isplit = imin+inum/2; + + // Left + subdivide(items, nitems, imin, isplit, curNode, nodes); + // Right + subdivide(items, nitems, isplit, imax, curNode, nodes); + + int iescape = curNode - icur; + // Negative index means escape. + node.i = -iescape; + } +} + +static int createBVTree(dtNavMeshCreateParams* params, dtBVNode* nodes, int /*nnodes*/) +{ + // Build tree + float quantFactor = 1 / params->cs; + BVItem* items = (BVItem*)dtAlloc(sizeof(BVItem)*params->polyCount, DT_ALLOC_TEMP); + for (int i = 0; i < params->polyCount; i++) + { + BVItem& it = items[i]; + it.i = i; + // Calc polygon bounds. Use detail meshes if available. + if (params->detailMeshes) + { + int vb = (int)params->detailMeshes[i*4+0]; + int ndv = (int)params->detailMeshes[i*4+1]; + float bmin[3]; + float bmax[3]; + + const float* dv = ¶ms->detailVerts[vb*3]; + dtVcopy(bmin, dv); + dtVcopy(bmax, dv); + + for (int j = 1; j < ndv; j++) + { + dtVmin(bmin, &dv[j * 3]); + dtVmax(bmax, &dv[j * 3]); + } + + // BV-tree uses cs for all dimensions + it.bmin[0] = (unsigned short)dtClamp((int)((bmin[0] - params->bmin[0])*quantFactor), 0, 0xffff); + it.bmin[1] = (unsigned short)dtClamp((int)((bmin[1] - params->bmin[1])*quantFactor), 0, 0xffff); + it.bmin[2] = (unsigned short)dtClamp((int)((bmin[2] - params->bmin[2])*quantFactor), 0, 0xffff); + + it.bmax[0] = (unsigned short)dtClamp((int)((bmax[0] - params->bmin[0])*quantFactor), 0, 0xffff); + it.bmax[1] = (unsigned short)dtClamp((int)((bmax[1] - params->bmin[1])*quantFactor), 0, 0xffff); + it.bmax[2] = (unsigned short)dtClamp((int)((bmax[2] - params->bmin[2])*quantFactor), 0, 0xffff); + } + else + { + const unsigned short* p = ¶ms->polys[i*params->nvp * 2]; + it.bmin[0] = it.bmax[0] = params->verts[p[0] * 3 + 0]; + it.bmin[1] = it.bmax[1] = params->verts[p[0] * 3 + 1]; + it.bmin[2] = it.bmax[2] = params->verts[p[0] * 3 + 2]; + + for (int j = 1; j < params->nvp; ++j) + { + if (p[j] == MESH_NULL_IDX) break; + unsigned short x = params->verts[p[j] * 3 + 0]; + unsigned short y = params->verts[p[j] * 3 + 1]; + unsigned short z = params->verts[p[j] * 3 + 2]; + + if (x < it.bmin[0]) it.bmin[0] = x; + if (y < it.bmin[1]) it.bmin[1] = y; + if (z < it.bmin[2]) it.bmin[2] = z; + + if (x > it.bmax[0]) it.bmax[0] = x; + if (y > it.bmax[1]) it.bmax[1] = y; + if (z > it.bmax[2]) it.bmax[2] = z; + } + // Remap y + it.bmin[1] = (unsigned short)dtMathFloorf((float)it.bmin[1] * params->ch / params->cs); + it.bmax[1] = (unsigned short)dtMathCeilf((float)it.bmax[1] * params->ch / params->cs); + } + } + + int curNode = 0; + subdivide(items, params->polyCount, 0, params->polyCount, curNode, nodes); + + dtFree(items); + + return curNode; +} + +static unsigned char classifyOffMeshPoint(const float* pt, const float* bmin, const float* bmax) +{ + static const unsigned char XP = 1<<0; + static const unsigned char ZP = 1<<1; + static const unsigned char XM = 1<<2; + static const unsigned char ZM = 1<<3; + + unsigned char outcode = 0; + outcode |= (pt[0] >= bmax[0]) ? XP : 0; + outcode |= (pt[2] >= bmax[2]) ? ZP : 0; + outcode |= (pt[0] < bmin[0]) ? XM : 0; + outcode |= (pt[2] < bmin[2]) ? ZM : 0; + + switch (outcode) + { + case XP: return 0; + case XP|ZP: return 1; + case ZP: return 2; + case XM|ZP: return 3; + case XM: return 4; + case XM|ZM: return 5; + case ZM: return 6; + case XP|ZM: return 7; + }; + + return 0xff; +} + +// TODO: Better error handling. + +/// @par +/// +/// The output data array is allocated using the detour allocator (dtAlloc()). The method +/// used to free the memory will be determined by how the tile is added to the navigation +/// mesh. +/// +/// @see dtNavMesh, dtNavMesh::addTile() +bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize) +{ + if (params->nvp > DT_VERTS_PER_POLYGON) + return false; + if (params->vertCount >= 0xffff) + return false; + if (!params->vertCount || !params->verts) + return false; + if (!params->polyCount || !params->polys) + return false; + + const int nvp = params->nvp; + + // Classify off-mesh connection points. We store only the connections + // whose start point is inside the tile. + unsigned char* offMeshConClass = 0; + int storedOffMeshConCount = 0; + int offMeshConLinkCount = 0; + + if (params->offMeshConCount > 0) + { + offMeshConClass = (unsigned char*)dtAlloc(sizeof(unsigned char)*params->offMeshConCount*2, DT_ALLOC_TEMP); + if (!offMeshConClass) + return false; + + // Find tight heigh bounds, used for culling out off-mesh start locations. + float hmin = FLT_MAX; + float hmax = -FLT_MAX; + + if (params->detailVerts && params->detailVertsCount) + { + for (int i = 0; i < params->detailVertsCount; ++i) + { + const float h = params->detailVerts[i*3+1]; + hmin = dtMin(hmin,h); + hmax = dtMax(hmax,h); + } + } + else + { + for (int i = 0; i < params->vertCount; ++i) + { + const unsigned short* iv = ¶ms->verts[i*3]; + const float h = params->bmin[1] + iv[1] * params->ch; + hmin = dtMin(hmin,h); + hmax = dtMax(hmax,h); + } + } + hmin -= params->walkableClimb; + hmax += params->walkableClimb; + float bmin[3], bmax[3]; + dtVcopy(bmin, params->bmin); + dtVcopy(bmax, params->bmax); + bmin[1] = hmin; + bmax[1] = hmax; + + for (int i = 0; i < params->offMeshConCount; ++i) + { + const float* p0 = ¶ms->offMeshConVerts[(i*2+0)*3]; + const float* p1 = ¶ms->offMeshConVerts[(i*2+1)*3]; + offMeshConClass[i*2+0] = classifyOffMeshPoint(p0, bmin, bmax); + offMeshConClass[i*2+1] = classifyOffMeshPoint(p1, bmin, bmax); + + // Zero out off-mesh start positions which are not even potentially touching the mesh. + if (offMeshConClass[i*2+0] == 0xff) + { + if (p0[1] < bmin[1] || p0[1] > bmax[1]) + offMeshConClass[i*2+0] = 0; + } + + // Cound how many links should be allocated for off-mesh connections. + if (offMeshConClass[i*2+0] == 0xff) + offMeshConLinkCount++; + if (offMeshConClass[i*2+1] == 0xff) + offMeshConLinkCount++; + + if (offMeshConClass[i*2+0] == 0xff) + storedOffMeshConCount++; + } + } + + // Off-mesh connectionss are stored as polygons, adjust values. + const int totPolyCount = params->polyCount + storedOffMeshConCount; + const int totVertCount = params->vertCount + storedOffMeshConCount*2; + + // Find portal edges which are at tile borders. + int edgeCount = 0; + int portalCount = 0; + for (int i = 0; i < params->polyCount; ++i) + { + const unsigned short* p = ¶ms->polys[i*2*nvp]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == MESH_NULL_IDX) break; + edgeCount++; + + if (p[nvp+j] & 0x8000) + { + unsigned short dir = p[nvp+j] & 0xf; + if (dir != 0xf) + portalCount++; + } + } + } + + const int maxLinkCount = edgeCount + portalCount*2 + offMeshConLinkCount*2; + + // Find unique detail vertices. + int uniqueDetailVertCount = 0; + int detailTriCount = 0; + if (params->detailMeshes) + { + // Has detail mesh, count unique detail vertex count and use input detail tri count. + detailTriCount = params->detailTriCount; + for (int i = 0; i < params->polyCount; ++i) + { + const unsigned short* p = ¶ms->polys[i*nvp*2]; + int ndv = params->detailMeshes[i*4+1]; + int nv = 0; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == MESH_NULL_IDX) break; + nv++; + } + ndv -= nv; + uniqueDetailVertCount += ndv; + } + } + else + { + // No input detail mesh, build detail mesh from nav polys. + uniqueDetailVertCount = 0; // No extra detail verts. + detailTriCount = 0; + for (int i = 0; i < params->polyCount; ++i) + { + const unsigned short* p = ¶ms->polys[i*nvp*2]; + int nv = 0; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == MESH_NULL_IDX) break; + nv++; + } + detailTriCount += nv-2; + } + } + + // Calculate data size + const int headerSize = dtAlign4(sizeof(dtMeshHeader)); + const int vertsSize = dtAlign4(sizeof(float)*3*totVertCount); + const int polysSize = dtAlign4(sizeof(dtPoly)*totPolyCount); + const int linksSize = dtAlign4(sizeof(dtLink)*maxLinkCount); + const int detailMeshesSize = dtAlign4(sizeof(dtPolyDetail)*params->polyCount); + const int detailVertsSize = dtAlign4(sizeof(float)*3*uniqueDetailVertCount); + const int detailTrisSize = dtAlign4(sizeof(unsigned char)*4*detailTriCount); + const int bvTreeSize = params->buildBvTree ? dtAlign4(sizeof(dtBVNode)*params->polyCount*2) : 0; + const int offMeshConsSize = dtAlign4(sizeof(dtOffMeshConnection)*storedOffMeshConCount); + + const int dataSize = headerSize + vertsSize + polysSize + linksSize + + detailMeshesSize + detailVertsSize + detailTrisSize + + bvTreeSize + offMeshConsSize; + + unsigned char* data = (unsigned char*)dtAlloc(sizeof(unsigned char)*dataSize, DT_ALLOC_PERM); + if (!data) + { + dtFree(offMeshConClass); + return false; + } + memset(data, 0, dataSize); + + unsigned char* d = data; + + dtMeshHeader* header = dtGetThenAdvanceBufferPointer(d, headerSize); + float* navVerts = dtGetThenAdvanceBufferPointer(d, vertsSize); + dtPoly* navPolys = dtGetThenAdvanceBufferPointer(d, polysSize); + d += linksSize; // Ignore links; just leave enough space for them. They'll be created on load. + dtPolyDetail* navDMeshes = dtGetThenAdvanceBufferPointer(d, detailMeshesSize); + float* navDVerts = dtGetThenAdvanceBufferPointer(d, detailVertsSize); + unsigned char* navDTris = dtGetThenAdvanceBufferPointer(d, detailTrisSize); + dtBVNode* navBvtree = dtGetThenAdvanceBufferPointer(d, bvTreeSize); + dtOffMeshConnection* offMeshCons = dtGetThenAdvanceBufferPointer(d, offMeshConsSize); + + + // Store header + header->magic = DT_NAVMESH_MAGIC; + header->version = DT_NAVMESH_VERSION; + header->x = params->tileX; + header->y = params->tileY; + header->layer = params->tileLayer; + header->userId = params->userId; + header->polyCount = totPolyCount; + header->vertCount = totVertCount; + header->maxLinkCount = maxLinkCount; + dtVcopy(header->bmin, params->bmin); + dtVcopy(header->bmax, params->bmax); + header->detailMeshCount = params->polyCount; + header->detailVertCount = uniqueDetailVertCount; + header->detailTriCount = detailTriCount; + header->bvQuantFactor = 1.0f / params->cs; + header->offMeshBase = params->polyCount; + header->walkableHeight = params->walkableHeight; + header->walkableRadius = params->walkableRadius; + header->walkableClimb = params->walkableClimb; + header->offMeshConCount = storedOffMeshConCount; + header->bvNodeCount = params->buildBvTree ? params->polyCount*2 : 0; + + const int offMeshVertsBase = params->vertCount; + const int offMeshPolyBase = params->polyCount; + + // Store vertices + // Mesh vertices + for (int i = 0; i < params->vertCount; ++i) + { + const unsigned short* iv = ¶ms->verts[i*3]; + float* v = &navVerts[i*3]; + v[0] = params->bmin[0] + iv[0] * params->cs; + v[1] = params->bmin[1] + iv[1] * params->ch; + v[2] = params->bmin[2] + iv[2] * params->cs; + } + // Off-mesh link vertices. + int n = 0; + for (int i = 0; i < params->offMeshConCount; ++i) + { + // Only store connections which start from this tile. + if (offMeshConClass[i*2+0] == 0xff) + { + const float* linkv = ¶ms->offMeshConVerts[i*2*3]; + float* v = &navVerts[(offMeshVertsBase + n*2)*3]; + dtVcopy(&v[0], &linkv[0]); + dtVcopy(&v[3], &linkv[3]); + n++; + } + } + + // Store polygons + // Mesh polys + const unsigned short* src = params->polys; + for (int i = 0; i < params->polyCount; ++i) + { + dtPoly* p = &navPolys[i]; + p->vertCount = 0; + p->flags = params->polyFlags[i]; + p->setArea(params->polyAreas[i]); + p->setType(DT_POLYTYPE_GROUND); + for (int j = 0; j < nvp; ++j) + { + if (src[j] == MESH_NULL_IDX) break; + p->verts[j] = src[j]; + if (src[nvp+j] & 0x8000) + { + // Border or portal edge. + unsigned short dir = src[nvp+j] & 0xf; + if (dir == 0xf) // Border + p->neis[j] = 0; + else if (dir == 0) // Portal x- + p->neis[j] = DT_EXT_LINK | 4; + else if (dir == 1) // Portal z+ + p->neis[j] = DT_EXT_LINK | 2; + else if (dir == 2) // Portal x+ + p->neis[j] = DT_EXT_LINK | 0; + else if (dir == 3) // Portal z- + p->neis[j] = DT_EXT_LINK | 6; + } + else + { + // Normal connection + p->neis[j] = src[nvp+j]+1; + } + + p->vertCount++; + } + src += nvp*2; + } + // Off-mesh connection vertices. + n = 0; + for (int i = 0; i < params->offMeshConCount; ++i) + { + // Only store connections which start from this tile. + if (offMeshConClass[i*2+0] == 0xff) + { + dtPoly* p = &navPolys[offMeshPolyBase+n]; + p->vertCount = 2; + p->verts[0] = (unsigned short)(offMeshVertsBase + n*2+0); + p->verts[1] = (unsigned short)(offMeshVertsBase + n*2+1); + p->flags = params->offMeshConFlags[i]; + p->setArea(params->offMeshConAreas[i]); + p->setType(DT_POLYTYPE_OFFMESH_CONNECTION); + n++; + } + } + + // Store detail meshes and vertices. + // The nav polygon vertices are stored as the first vertices on each mesh. + // We compress the mesh data by skipping them and using the navmesh coordinates. + if (params->detailMeshes) + { + unsigned short vbase = 0; + for (int i = 0; i < params->polyCount; ++i) + { + dtPolyDetail& dtl = navDMeshes[i]; + const int vb = (int)params->detailMeshes[i*4+0]; + const int ndv = (int)params->detailMeshes[i*4+1]; + const int nv = navPolys[i].vertCount; + dtl.vertBase = (unsigned int)vbase; + dtl.vertCount = (unsigned char)(ndv-nv); + dtl.triBase = (unsigned int)params->detailMeshes[i*4+2]; + dtl.triCount = (unsigned char)params->detailMeshes[i*4+3]; + // Copy vertices except the first 'nv' verts which are equal to nav poly verts. + if (ndv-nv) + { + memcpy(&navDVerts[vbase*3], ¶ms->detailVerts[(vb+nv)*3], sizeof(float)*3*(ndv-nv)); + vbase += (unsigned short)(ndv-nv); + } + } + // Store triangles. + memcpy(navDTris, params->detailTris, sizeof(unsigned char)*4*params->detailTriCount); + } + else + { + // Create dummy detail mesh by triangulating polys. + int tbase = 0; + for (int i = 0; i < params->polyCount; ++i) + { + dtPolyDetail& dtl = navDMeshes[i]; + const int nv = navPolys[i].vertCount; + dtl.vertBase = 0; + dtl.vertCount = 0; + dtl.triBase = (unsigned int)tbase; + dtl.triCount = (unsigned char)(nv-2); + // Triangulate polygon (local indices). + for (int j = 2; j < nv; ++j) + { + unsigned char* t = &navDTris[tbase*4]; + t[0] = 0; + t[1] = (unsigned char)(j-1); + t[2] = (unsigned char)j; + // Bit for each edge that belongs to poly boundary. + t[3] = (1<<2); + if (j == 2) t[3] |= (1<<0); + if (j == nv-1) t[3] |= (1<<4); + tbase++; + } + } + } + + // Store and create BVtree. + if (params->buildBvTree) + { + createBVTree(params, navBvtree, 2*params->polyCount); + } + + // Store Off-Mesh connections. + n = 0; + for (int i = 0; i < params->offMeshConCount; ++i) + { + // Only store connections which start from this tile. + if (offMeshConClass[i*2+0] == 0xff) + { + dtOffMeshConnection* con = &offMeshCons[n]; + con->poly = (unsigned short)(offMeshPolyBase + n); + // Copy connection end-points. + const float* endPts = ¶ms->offMeshConVerts[i*2*3]; + dtVcopy(&con->pos[0], &endPts[0]); + dtVcopy(&con->pos[3], &endPts[3]); + con->rad = params->offMeshConRad[i]; + con->flags = params->offMeshConDir[i] ? DT_OFFMESH_CON_BIDIR : 0; + con->side = offMeshConClass[i*2+1]; + if (params->offMeshConUserID) + con->userId = params->offMeshConUserID[i]; + n++; + } + } + + dtFree(offMeshConClass); + + *outData = data; + *outDataSize = dataSize; + + return true; +} + +bool dtNavMeshHeaderSwapEndian(unsigned char* data, const int /*dataSize*/) +{ + dtMeshHeader* header = (dtMeshHeader*)data; + + int swappedMagic = DT_NAVMESH_MAGIC; + int swappedVersion = DT_NAVMESH_VERSION; + dtSwapEndian(&swappedMagic); + dtSwapEndian(&swappedVersion); + + if ((header->magic != DT_NAVMESH_MAGIC || header->version != DT_NAVMESH_VERSION) && + (header->magic != swappedMagic || header->version != swappedVersion)) + { + return false; + } + + dtSwapEndian(&header->magic); + dtSwapEndian(&header->version); + dtSwapEndian(&header->x); + dtSwapEndian(&header->y); + dtSwapEndian(&header->layer); + dtSwapEndian(&header->userId); + dtSwapEndian(&header->polyCount); + dtSwapEndian(&header->vertCount); + dtSwapEndian(&header->maxLinkCount); + dtSwapEndian(&header->detailMeshCount); + dtSwapEndian(&header->detailVertCount); + dtSwapEndian(&header->detailTriCount); + dtSwapEndian(&header->bvNodeCount); + dtSwapEndian(&header->offMeshConCount); + dtSwapEndian(&header->offMeshBase); + dtSwapEndian(&header->walkableHeight); + dtSwapEndian(&header->walkableRadius); + dtSwapEndian(&header->walkableClimb); + dtSwapEndian(&header->bmin[0]); + dtSwapEndian(&header->bmin[1]); + dtSwapEndian(&header->bmin[2]); + dtSwapEndian(&header->bmax[0]); + dtSwapEndian(&header->bmax[1]); + dtSwapEndian(&header->bmax[2]); + dtSwapEndian(&header->bvQuantFactor); + + // Freelist index and pointers are updated when tile is added, no need to swap. + + return true; +} + +/// @par +/// +/// @warning This function assumes that the header is in the correct endianess already. +/// Call #dtNavMeshHeaderSwapEndian() first on the data if the data is expected to be in wrong endianess +/// to start with. Call #dtNavMeshHeaderSwapEndian() after the data has been swapped if converting from +/// native to foreign endianess. +bool dtNavMeshDataSwapEndian(unsigned char* data, const int /*dataSize*/) +{ + // Make sure the data is in right format. + dtMeshHeader* header = (dtMeshHeader*)data; + if (header->magic != DT_NAVMESH_MAGIC) + return false; + if (header->version != DT_NAVMESH_VERSION) + return false; + + // Patch header pointers. + const int headerSize = dtAlign4(sizeof(dtMeshHeader)); + const int vertsSize = dtAlign4(sizeof(float)*3*header->vertCount); + const int polysSize = dtAlign4(sizeof(dtPoly)*header->polyCount); + const int linksSize = dtAlign4(sizeof(dtLink)*(header->maxLinkCount)); + const int detailMeshesSize = dtAlign4(sizeof(dtPolyDetail)*header->detailMeshCount); + const int detailVertsSize = dtAlign4(sizeof(float)*3*header->detailVertCount); + const int detailTrisSize = dtAlign4(sizeof(unsigned char)*4*header->detailTriCount); + const int bvtreeSize = dtAlign4(sizeof(dtBVNode)*header->bvNodeCount); + const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount); + + unsigned char* d = data + headerSize; + float* verts = dtGetThenAdvanceBufferPointer(d, vertsSize); + dtPoly* polys = dtGetThenAdvanceBufferPointer(d, polysSize); + d += linksSize; // Ignore links; they technically should be endian-swapped but all their data is overwritten on load anyway. + //dtLink* links = dtGetThenAdvanceBufferPointer(d, linksSize); + dtPolyDetail* detailMeshes = dtGetThenAdvanceBufferPointer(d, detailMeshesSize); + float* detailVerts = dtGetThenAdvanceBufferPointer(d, detailVertsSize); + d += detailTrisSize; // Ignore detail tris; single bytes can't be endian-swapped. + //unsigned char* detailTris = dtGetThenAdvanceBufferPointer(d, detailTrisSize); + dtBVNode* bvTree = dtGetThenAdvanceBufferPointer(d, bvtreeSize); + dtOffMeshConnection* offMeshCons = dtGetThenAdvanceBufferPointer(d, offMeshLinksSize); + + // Vertices + for (int i = 0; i < header->vertCount*3; ++i) + { + dtSwapEndian(&verts[i]); + } + + // Polys + for (int i = 0; i < header->polyCount; ++i) + { + dtPoly* p = &polys[i]; + // poly->firstLink is update when tile is added, no need to swap. + for (int j = 0; j < DT_VERTS_PER_POLYGON; ++j) + { + dtSwapEndian(&p->verts[j]); + dtSwapEndian(&p->neis[j]); + } + dtSwapEndian(&p->flags); + } + + // Links are rebuild when tile is added, no need to swap. + + // Detail meshes + for (int i = 0; i < header->detailMeshCount; ++i) + { + dtPolyDetail* pd = &detailMeshes[i]; + dtSwapEndian(&pd->vertBase); + dtSwapEndian(&pd->triBase); + } + + // Detail verts + for (int i = 0; i < header->detailVertCount*3; ++i) + { + dtSwapEndian(&detailVerts[i]); + } + + // BV-tree + for (int i = 0; i < header->bvNodeCount; ++i) + { + dtBVNode* node = &bvTree[i]; + for (int j = 0; j < 3; ++j) + { + dtSwapEndian(&node->bmin[j]); + dtSwapEndian(&node->bmax[j]); + } + dtSwapEndian(&node->i); + } + + // Off-mesh Connections. + for (int i = 0; i < header->offMeshConCount; ++i) + { + dtOffMeshConnection* con = &offMeshCons[i]; + for (int j = 0; j < 6; ++j) + dtSwapEndian(&con->pos[j]); + dtSwapEndian(&con->rad); + dtSwapEndian(&con->poly); + } + + return true; +} diff --git a/libs/recast/detour/src/DetourNavMeshQuery.cpp b/libs/recast/detour/src/DetourNavMeshQuery.cpp new file mode 100644 index 000000000..d27a142d0 --- /dev/null +++ b/libs/recast/detour/src/DetourNavMeshQuery.cpp @@ -0,0 +1,3666 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#include +#include "DetourNavMeshQuery.h" +#include "DetourNavMesh.h" +#include "DetourNode.h" +#include "DetourCommon.h" +#include "DetourMath.h" +#include "DetourAlloc.h" +#include "DetourAssert.h" +#include + +/// @class dtQueryFilter +/// +/// The Default Implementation +/// +/// At construction: All area costs default to 1.0. All flags are included +/// and none are excluded. +/// +/// If a polygon has both an include and an exclude flag, it will be excluded. +/// +/// The way filtering works, a navigation mesh polygon must have at least one flag +/// set to ever be considered by a query. So a polygon with no flags will never +/// be considered. +/// +/// Setting the include flags to 0 will result in all polygons being excluded. +/// +/// Custom Implementations +/// +/// DT_VIRTUAL_QUERYFILTER must be defined in order to extend this class. +/// +/// Implement a custom query filter by overriding the virtual passFilter() +/// and getCost() functions. If this is done, both functions should be as +/// fast as possible. Use cached local copies of data rather than accessing +/// your own objects where possible. +/// +/// Custom implementations do not need to adhere to the flags or cost logic +/// used by the default implementation. +/// +/// In order for A* searches to work properly, the cost should be proportional to +/// the travel distance. Implementing a cost modifier less than 1.0 is likely +/// to lead to problems during pathfinding. +/// +/// @see dtNavMeshQuery + +dtQueryFilter::dtQueryFilter() : + m_includeFlags(0xffff), + m_excludeFlags(0) +{ + for (int i = 0; i < DT_MAX_AREAS; ++i) + m_areaCost[i] = 1.0f; +} + +#ifdef DT_VIRTUAL_QUERYFILTER +bool dtQueryFilter::passFilter(const dtPolyRef /*ref*/, + const dtMeshTile* /*tile*/, + const dtPoly* poly) const +{ + return (poly->flags & m_includeFlags) != 0 && (poly->flags & m_excludeFlags) == 0; +} + +float dtQueryFilter::getCost(const float* pa, const float* pb, + const dtPolyRef /*prevRef*/, const dtMeshTile* /*prevTile*/, const dtPoly* /*prevPoly*/, + const dtPolyRef /*curRef*/, const dtMeshTile* /*curTile*/, const dtPoly* curPoly, + const dtPolyRef /*nextRef*/, const dtMeshTile* /*nextTile*/, const dtPoly* /*nextPoly*/) const +{ + return dtVdist(pa, pb) * m_areaCost[curPoly->getArea()]; +} +#else +inline bool dtQueryFilter::passFilter(const dtPolyRef /*ref*/, + const dtMeshTile* /*tile*/, + const dtPoly* poly) const +{ + return (poly->flags & m_includeFlags) != 0 && (poly->flags & m_excludeFlags) == 0; +} + +inline float dtQueryFilter::getCost(const float* pa, const float* pb, + const dtPolyRef /*prevRef*/, const dtMeshTile* /*prevTile*/, const dtPoly* /*prevPoly*/, + const dtPolyRef /*curRef*/, const dtMeshTile* /*curTile*/, const dtPoly* curPoly, + const dtPolyRef /*nextRef*/, const dtMeshTile* /*nextTile*/, const dtPoly* /*nextPoly*/) const +{ + return dtVdist(pa, pb) * m_areaCost[curPoly->getArea()]; +} +#endif + +static const float H_SCALE = 0.999f; // Search heuristic scale. + + +dtNavMeshQuery* dtAllocNavMeshQuery() +{ + void* mem = dtAlloc(sizeof(dtNavMeshQuery), DT_ALLOC_PERM); + if (!mem) return 0; + return new(mem) dtNavMeshQuery; +} + +void dtFreeNavMeshQuery(dtNavMeshQuery* navmesh) +{ + if (!navmesh) return; + navmesh->~dtNavMeshQuery(); + dtFree(navmesh); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +/// @class dtNavMeshQuery +/// +/// For methods that support undersized buffers, if the buffer is too small +/// to hold the entire result set the return status of the method will include +/// the #DT_BUFFER_TOO_SMALL flag. +/// +/// Constant member functions can be used by multiple clients without side +/// effects. (E.g. No change to the closed list. No impact on an in-progress +/// sliced path query. Etc.) +/// +/// Walls and portals: A @e wall is a polygon segment that is +/// considered impassable. A @e portal is a passable segment between polygons. +/// A portal may be treated as a wall based on the dtQueryFilter used for a query. +/// +/// @see dtNavMesh, dtQueryFilter, #dtAllocNavMeshQuery(), #dtAllocNavMeshQuery() + +dtNavMeshQuery::dtNavMeshQuery() : + m_nav(0), + m_tinyNodePool(0), + m_nodePool(0), + m_openList(0) +{ + memset(&m_query, 0, sizeof(dtQueryData)); +} + +dtNavMeshQuery::~dtNavMeshQuery() +{ + if (m_tinyNodePool) + m_tinyNodePool->~dtNodePool(); + if (m_nodePool) + m_nodePool->~dtNodePool(); + if (m_openList) + m_openList->~dtNodeQueue(); + dtFree(m_tinyNodePool); + dtFree(m_nodePool); + dtFree(m_openList); +} + +/// @par +/// +/// Must be the first function called after construction, before other +/// functions are used. +/// +/// This function can be used multiple times. +dtStatus dtNavMeshQuery::init(const dtNavMesh* nav, const int maxNodes) +{ + if (maxNodes > DT_NULL_IDX || maxNodes > (1 << DT_NODE_PARENT_BITS) - 1) + return DT_FAILURE | DT_INVALID_PARAM; + + m_nav = nav; + + if (!m_nodePool || m_nodePool->getMaxNodes() < maxNodes) + { + if (m_nodePool) + { + m_nodePool->~dtNodePool(); + dtFree(m_nodePool); + m_nodePool = 0; + } + m_nodePool = new (dtAlloc(sizeof(dtNodePool), DT_ALLOC_PERM)) dtNodePool(maxNodes, dtNextPow2(maxNodes/4)); + if (!m_nodePool) + return DT_FAILURE | DT_OUT_OF_MEMORY; + } + else + { + m_nodePool->clear(); + } + + if (!m_tinyNodePool) + { + m_tinyNodePool = new (dtAlloc(sizeof(dtNodePool), DT_ALLOC_PERM)) dtNodePool(64, 32); + if (!m_tinyNodePool) + return DT_FAILURE | DT_OUT_OF_MEMORY; + } + else + { + m_tinyNodePool->clear(); + } + + if (!m_openList || m_openList->getCapacity() < maxNodes) + { + if (m_openList) + { + m_openList->~dtNodeQueue(); + dtFree(m_openList); + m_openList = 0; + } + m_openList = new (dtAlloc(sizeof(dtNodeQueue), DT_ALLOC_PERM)) dtNodeQueue(maxNodes); + if (!m_openList) + return DT_FAILURE | DT_OUT_OF_MEMORY; + } + else + { + m_openList->clear(); + } + + return DT_SUCCESS; +} + +dtStatus dtNavMeshQuery::findRandomPoint(const dtQueryFilter* filter, float (*frand)(), + dtPolyRef* randomRef, float* randomPt) const +{ + dtAssert(m_nav); + + // Randomly pick one tile. Assume that all tiles cover roughly the same area. + const dtMeshTile* tile = 0; + float tsum = 0.0f; + for (int i = 0; i < m_nav->getMaxTiles(); i++) + { + const dtMeshTile* t = m_nav->getTile(i); + if (!t || !t->header) continue; + + // Choose random tile using reservoi sampling. + const float area = 1.0f; // Could be tile area too. + tsum += area; + const float u = frand(); + if (u*tsum <= area) + tile = t; + } + if (!tile) + return DT_FAILURE; + + // Randomly pick one polygon weighted by polygon area. + const dtPoly* poly = 0; + dtPolyRef polyRef = 0; + const dtPolyRef base = m_nav->getPolyRefBase(tile); + + float areaSum = 0.0f; + for (int i = 0; i < tile->header->polyCount; ++i) + { + const dtPoly* p = &tile->polys[i]; + // Do not return off-mesh connection polygons. + if (p->getType() != DT_POLYTYPE_GROUND) + continue; + // Must pass filter + const dtPolyRef ref = base | (dtPolyRef)i; + if (!filter->passFilter(ref, tile, p)) + continue; + + // Calc area of the polygon. + float polyArea = 0.0f; + for (int j = 2; j < p->vertCount; ++j) + { + const float* va = &tile->verts[p->verts[0]*3]; + const float* vb = &tile->verts[p->verts[j-1]*3]; + const float* vc = &tile->verts[p->verts[j]*3]; + polyArea += dtTriArea2D(va,vb,vc); + } + + // Choose random polygon weighted by area, using reservoi sampling. + areaSum += polyArea; + const float u = frand(); + if (u*areaSum <= polyArea) + { + poly = p; + polyRef = ref; + } + } + + if (!poly) + return DT_FAILURE; + + // Randomly pick point on polygon. + const float* v = &tile->verts[poly->verts[0]*3]; + float verts[3*DT_VERTS_PER_POLYGON]; + float areas[DT_VERTS_PER_POLYGON]; + dtVcopy(&verts[0*3],v); + for (int j = 1; j < poly->vertCount; ++j) + { + v = &tile->verts[poly->verts[j]*3]; + dtVcopy(&verts[j*3],v); + } + + const float s = frand(); + const float t = frand(); + + float pt[3]; + dtRandomPointInConvexPoly(verts, poly->vertCount, areas, s, t, pt); + + float h = 0.0f; + dtStatus status = getPolyHeight(polyRef, pt, &h); + if (dtStatusFailed(status)) + return status; + pt[1] = h; + + dtVcopy(randomPt, pt); + *randomRef = polyRef; + + return DT_SUCCESS; +} + +dtStatus dtNavMeshQuery::findRandomPointAroundCircle(dtPolyRef startRef, const float* centerPos, const float maxRadius, + const dtQueryFilter* filter, float (*frand)(), + dtPolyRef* randomRef, float* randomPt) const +{ + dtAssert(m_nav); + dtAssert(m_nodePool); + dtAssert(m_openList); + + // Validate input + if (!startRef || !m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + const dtMeshTile* startTile = 0; + const dtPoly* startPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(startRef, &startTile, &startPoly); + if (!filter->passFilter(startRef, startTile, startPoly)) + return DT_FAILURE | DT_INVALID_PARAM; + + m_nodePool->clear(); + m_openList->clear(); + + dtNode* startNode = m_nodePool->getNode(startRef); + dtVcopy(startNode->pos, centerPos); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = 0; + startNode->id = startRef; + startNode->flags = DT_NODE_OPEN; + m_openList->push(startNode); + + dtStatus status = DT_SUCCESS; + + const float radiusSqr = dtSqr(maxRadius); + float areaSum = 0.0f; + + const dtMeshTile* randomTile = 0; + const dtPoly* randomPoly = 0; + dtPolyRef randomPolyRef = 0; + + while (!m_openList->empty()) + { + dtNode* bestNode = m_openList->pop(); + bestNode->flags &= ~DT_NODE_OPEN; + bestNode->flags |= DT_NODE_CLOSED; + + // Get poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef bestRef = bestNode->id; + const dtMeshTile* bestTile = 0; + const dtPoly* bestPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(bestRef, &bestTile, &bestPoly); + + // Place random locations on on ground. + if (bestPoly->getType() == DT_POLYTYPE_GROUND) + { + // Calc area of the polygon. + float polyArea = 0.0f; + for (int j = 2; j < bestPoly->vertCount; ++j) + { + const float* va = &bestTile->verts[bestPoly->verts[0]*3]; + const float* vb = &bestTile->verts[bestPoly->verts[j-1]*3]; + const float* vc = &bestTile->verts[bestPoly->verts[j]*3]; + polyArea += dtTriArea2D(va,vb,vc); + } + // Choose random polygon weighted by area, using reservoi sampling. + areaSum += polyArea; + const float u = frand(); + if (u*areaSum <= polyArea) + { + randomTile = bestTile; + randomPoly = bestPoly; + randomPolyRef = bestRef; + } + } + + + // Get parent poly and tile. + dtPolyRef parentRef = 0; + const dtMeshTile* parentTile = 0; + const dtPoly* parentPoly = 0; + if (bestNode->pidx) + parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id; + if (parentRef) + m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly); + + for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next) + { + const dtLink* link = &bestTile->links[i]; + dtPolyRef neighbourRef = link->ref; + // Skip invalid neighbours and do not follow back to parent. + if (!neighbourRef || neighbourRef == parentRef) + continue; + + // Expand to neighbour + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); + + // Do not advance if the polygon is excluded by the filter. + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + // Find edge and calc distance to the edge. + float va[3], vb[3]; + if (!getPortalPoints(bestRef, bestPoly, bestTile, neighbourRef, neighbourPoly, neighbourTile, va, vb)) + continue; + + // If the circle is not touching the next polygon, skip it. + float tseg; + float distSqr = dtDistancePtSegSqr2D(centerPos, va, vb, tseg); + if (distSqr > radiusSqr) + continue; + + dtNode* neighbourNode = m_nodePool->getNode(neighbourRef); + if (!neighbourNode) + { + status |= DT_OUT_OF_NODES; + continue; + } + + if (neighbourNode->flags & DT_NODE_CLOSED) + continue; + + // Cost + if (neighbourNode->flags == 0) + dtVlerp(neighbourNode->pos, va, vb, 0.5f); + + const float total = bestNode->total + dtVdist(bestNode->pos, neighbourNode->pos); + + // The node is already in open list and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total) + continue; + + neighbourNode->id = neighbourRef; + neighbourNode->flags = (neighbourNode->flags & ~DT_NODE_CLOSED); + neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode); + neighbourNode->total = total; + + if (neighbourNode->flags & DT_NODE_OPEN) + { + m_openList->modify(neighbourNode); + } + else + { + neighbourNode->flags = DT_NODE_OPEN; + m_openList->push(neighbourNode); + } + } + } + + if (!randomPoly) + return DT_FAILURE; + + // Randomly pick point on polygon. + const float* v = &randomTile->verts[randomPoly->verts[0]*3]; + float verts[3*DT_VERTS_PER_POLYGON]; + float areas[DT_VERTS_PER_POLYGON]; + dtVcopy(&verts[0*3],v); + for (int j = 1; j < randomPoly->vertCount; ++j) + { + v = &randomTile->verts[randomPoly->verts[j]*3]; + dtVcopy(&verts[j*3],v); + } + + const float s = frand(); + const float t = frand(); + + float pt[3]; + dtRandomPointInConvexPoly(verts, randomPoly->vertCount, areas, s, t, pt); + + float h = 0.0f; + dtStatus stat = getPolyHeight(randomPolyRef, pt, &h); + if (dtStatusFailed(status)) + return stat; + pt[1] = h; + + dtVcopy(randomPt, pt); + *randomRef = randomPolyRef; + + return DT_SUCCESS; +} + + +////////////////////////////////////////////////////////////////////////////////////////// + +/// @par +/// +/// Uses the detail polygons to find the surface height. (Most accurate.) +/// +/// @p pos does not have to be within the bounds of the polygon or navigation mesh. +/// +/// See closestPointOnPolyBoundary() for a limited but faster option. +/// +dtStatus dtNavMeshQuery::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly) const +{ + dtAssert(m_nav); + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(ref, &tile, &poly))) + return DT_FAILURE | DT_INVALID_PARAM; + if (!tile) + return DT_FAILURE | DT_INVALID_PARAM; + + // Off-mesh connections don't have detail polygons. + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + const float* v0 = &tile->verts[poly->verts[0]*3]; + const float* v1 = &tile->verts[poly->verts[1]*3]; + const float d0 = dtVdist(pos, v0); + const float d1 = dtVdist(pos, v1); + const float u = d0 / (d0+d1); + dtVlerp(closest, v0, v1, u); + if (posOverPoly) + *posOverPoly = false; + return DT_SUCCESS; + } + + const unsigned int ip = (unsigned int)(poly - tile->polys); + const dtPolyDetail* pd = &tile->detailMeshes[ip]; + + // Clamp point to be inside the polygon. + float verts[DT_VERTS_PER_POLYGON*3]; + float edged[DT_VERTS_PER_POLYGON]; + float edget[DT_VERTS_PER_POLYGON]; + const int nv = poly->vertCount; + for (int i = 0; i < nv; ++i) + dtVcopy(&verts[i*3], &tile->verts[poly->verts[i]*3]); + + dtVcopy(closest, pos); + if (!dtDistancePtPolyEdgesSqr(pos, verts, nv, edged, edget)) + { + // Point is outside the polygon, dtClamp to nearest edge. + float dmin = edged[0]; + int imin = 0; + for (int i = 1; i < nv; ++i) + { + if (edged[i] < dmin) + { + dmin = edged[i]; + imin = i; + } + } + const float* va = &verts[imin*3]; + const float* vb = &verts[((imin+1)%nv)*3]; + dtVlerp(closest, va, vb, edget[imin]); + + if (posOverPoly) + *posOverPoly = false; + } + else + { + if (posOverPoly) + *posOverPoly = true; + } + + // Find height at the location. + for (int j = 0; j < pd->triCount; ++j) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4]; + const float* v[3]; + for (int k = 0; k < 3; ++k) + { + if (t[k] < poly->vertCount) + v[k] = &tile->verts[poly->verts[t[k]]*3]; + else + v[k] = &tile->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3]; + } + float h; + if (dtClosestHeightPointTriangle(closest, v[0], v[1], v[2], h)) + { + closest[1] = h; + break; + } + } + + return DT_SUCCESS; +} + +/// @par +/// +/// Much faster than closestPointOnPoly(). +/// +/// If the provided position lies within the polygon's xz-bounds (above or below), +/// then @p pos and @p closest will be equal. +/// +/// The height of @p closest will be the polygon boundary. The height detail is not used. +/// +/// @p pos does not have to be within the bounds of the polybon or the navigation mesh. +/// +dtStatus dtNavMeshQuery::closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const +{ + dtAssert(m_nav); + + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(ref, &tile, &poly))) + return DT_FAILURE | DT_INVALID_PARAM; + + // Collect vertices. + float verts[DT_VERTS_PER_POLYGON*3]; + float edged[DT_VERTS_PER_POLYGON]; + float edget[DT_VERTS_PER_POLYGON]; + int nv = 0; + for (int i = 0; i < (int)poly->vertCount; ++i) + { + dtVcopy(&verts[nv*3], &tile->verts[poly->verts[i]*3]); + nv++; + } + + bool inside = dtDistancePtPolyEdgesSqr(pos, verts, nv, edged, edget); + if (inside) + { + // Point is inside the polygon, return the point. + dtVcopy(closest, pos); + } + else + { + // Point is outside the polygon, dtClamp to nearest edge. + float dmin = edged[0]; + int imin = 0; + for (int i = 1; i < nv; ++i) + { + if (edged[i] < dmin) + { + dmin = edged[i]; + imin = i; + } + } + const float* va = &verts[imin*3]; + const float* vb = &verts[((imin+1)%nv)*3]; + dtVlerp(closest, va, vb, edget[imin]); + } + + return DT_SUCCESS; +} + +/// @par +/// +/// Will return #DT_FAILURE if the provided position is outside the xz-bounds +/// of the polygon. +/// +dtStatus dtNavMeshQuery::getPolyHeight(dtPolyRef ref, const float* pos, float* height) const +{ + dtAssert(m_nav); + + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(ref, &tile, &poly))) + return DT_FAILURE | DT_INVALID_PARAM; + + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + const float* v0 = &tile->verts[poly->verts[0]*3]; + const float* v1 = &tile->verts[poly->verts[1]*3]; + const float d0 = dtVdist2D(pos, v0); + const float d1 = dtVdist2D(pos, v1); + const float u = d0 / (d0+d1); + if (height) + *height = v0[1] + (v1[1] - v0[1]) * u; + return DT_SUCCESS; + } + else + { + const unsigned int ip = (unsigned int)(poly - tile->polys); + const dtPolyDetail* pd = &tile->detailMeshes[ip]; + for (int j = 0; j < pd->triCount; ++j) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4]; + const float* v[3]; + for (int k = 0; k < 3; ++k) + { + if (t[k] < poly->vertCount) + v[k] = &tile->verts[poly->verts[t[k]]*3]; + else + v[k] = &tile->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3]; + } + float h; + if (dtClosestHeightPointTriangle(pos, v[0], v[1], v[2], h)) + { + if (height) + *height = h; + return DT_SUCCESS; + } + } + } + + return DT_FAILURE | DT_INVALID_PARAM; +} + +class dtFindNearestPolyQuery : public dtPolyQuery +{ + const dtNavMeshQuery* m_query; + const float* m_center; + float m_nearestDistanceSqr; + dtPolyRef m_nearestRef; + float m_nearestPoint[3]; + +public: + dtFindNearestPolyQuery(const dtNavMeshQuery* query, const float* center) + : m_query(query), m_center(center), m_nearestDistanceSqr(FLT_MAX), m_nearestRef(0), m_nearestPoint() + { + } + + dtPolyRef nearestRef() const { return m_nearestRef; } + const float* nearestPoint() const { return m_nearestPoint; } + + void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) + { + dtIgnoreUnused(polys); + + for (int i = 0; i < count; ++i) + { + dtPolyRef ref = refs[i]; + float closestPtPoly[3]; + float diff[3]; + bool posOverPoly = false; + float d; + m_query->closestPointOnPoly(ref, m_center, closestPtPoly, &posOverPoly); + + // If a point is directly over a polygon and closer than + // climb height, favor that instead of straight line nearest point. + dtVsub(diff, m_center, closestPtPoly); + if (posOverPoly) + { + d = dtAbs(diff[1]) - tile->header->walkableClimb; + d = d > 0 ? d*d : 0; + } + else + { + d = dtVlenSqr(diff); + } + + if (d < m_nearestDistanceSqr) + { + dtVcopy(m_nearestPoint, closestPtPoly); + + m_nearestDistanceSqr = d; + m_nearestRef = ref; + } + } + } +}; + +/// @par +/// +/// @note If the search box does not intersect any polygons the search will +/// return #DT_SUCCESS, but @p nearestRef will be zero. So if in doubt, check +/// @p nearestRef before using @p nearestPt. +/// +dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* extents, + const dtQueryFilter* filter, + dtPolyRef* nearestRef, float* nearestPt) const +{ + dtAssert(m_nav); + + if (!nearestRef) + return DT_FAILURE | DT_INVALID_PARAM; + + dtFindNearestPolyQuery query(this, center); + + dtStatus status = queryPolygons(center, extents, filter, &query); + if (dtStatusFailed(status)) + return status; + + *nearestRef = query.nearestRef(); + // Only override nearestPt if we actually found a poly so the nearest point + // is valid. + if (nearestPt && *nearestRef) + dtVcopy(nearestPt, query.nearestPoint()); + + return DT_SUCCESS; +} + +void dtNavMeshQuery::queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax, + const dtQueryFilter* filter, dtPolyQuery* query) const +{ + dtAssert(m_nav); + static const int batchSize = 32; + dtPolyRef polyRefs[batchSize]; + dtPoly* polys[batchSize]; + int n = 0; + + if (tile->bvTree) + { + const dtBVNode* node = &tile->bvTree[0]; + const dtBVNode* end = &tile->bvTree[tile->header->bvNodeCount]; + const float* tbmin = tile->header->bmin; + const float* tbmax = tile->header->bmax; + const float qfac = tile->header->bvQuantFactor; + + // Calculate quantized box + unsigned short bmin[3], bmax[3]; + // dtClamp query box to world box. + float minx = dtClamp(qmin[0], tbmin[0], tbmax[0]) - tbmin[0]; + float miny = dtClamp(qmin[1], tbmin[1], tbmax[1]) - tbmin[1]; + float minz = dtClamp(qmin[2], tbmin[2], tbmax[2]) - tbmin[2]; + float maxx = dtClamp(qmax[0], tbmin[0], tbmax[0]) - tbmin[0]; + float maxy = dtClamp(qmax[1], tbmin[1], tbmax[1]) - tbmin[1]; + float maxz = dtClamp(qmax[2], tbmin[2], tbmax[2]) - tbmin[2]; + // Quantize + bmin[0] = (unsigned short)(qfac * minx) & 0xfffe; + bmin[1] = (unsigned short)(qfac * miny) & 0xfffe; + bmin[2] = (unsigned short)(qfac * minz) & 0xfffe; + bmax[0] = (unsigned short)(qfac * maxx + 1) | 1; + bmax[1] = (unsigned short)(qfac * maxy + 1) | 1; + bmax[2] = (unsigned short)(qfac * maxz + 1) | 1; + + // Traverse tree + const dtPolyRef base = m_nav->getPolyRefBase(tile); + while (node < end) + { + const bool overlap = dtOverlapQuantBounds(bmin, bmax, node->bmin, node->bmax); + const bool isLeafNode = node->i >= 0; + + if (isLeafNode && overlap) + { + dtPolyRef ref = base | (dtPolyRef)node->i; + if (filter->passFilter(ref, tile, &tile->polys[node->i])) + { + polyRefs[n] = ref; + polys[n] = &tile->polys[node->i]; + + if (n == batchSize - 1) + { + query->process(tile, polys, polyRefs, batchSize); + n = 0; + } + else + { + n++; + } + } + } + + if (overlap || isLeafNode) + node++; + else + { + const int escapeIndex = -node->i; + node += escapeIndex; + } + } + } + else + { + float bmin[3], bmax[3]; + const dtPolyRef base = m_nav->getPolyRefBase(tile); + for (int i = 0; i < tile->header->polyCount; ++i) + { + dtPoly* p = &tile->polys[i]; + // Do not return off-mesh connection polygons. + if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + // Must pass filter + const dtPolyRef ref = base | (dtPolyRef)i; + if (!filter->passFilter(ref, tile, p)) + continue; + // Calc polygon bounds. + const float* v = &tile->verts[p->verts[0]*3]; + dtVcopy(bmin, v); + dtVcopy(bmax, v); + for (int j = 1; j < p->vertCount; ++j) + { + v = &tile->verts[p->verts[j]*3]; + dtVmin(bmin, v); + dtVmax(bmax, v); + } + if (dtOverlapBounds(qmin, qmax, bmin, bmax)) + { + polyRefs[n] = ref; + polys[n] = p; + + if (n == batchSize - 1) + { + query->process(tile, polys, polyRefs, batchSize); + n = 0; + } + else + { + n++; + } + } + } + } + + // Process the last polygons that didn't make a full batch. + if (n > 0) + query->process(tile, polys, polyRefs, n); +} + +class dtCollectPolysQuery : public dtPolyQuery +{ + dtPolyRef* m_polys; + const int m_maxPolys; + int m_numCollected; + bool m_overflow; + +public: + dtCollectPolysQuery(dtPolyRef* polys, const int maxPolys) + : m_polys(polys), m_maxPolys(maxPolys), m_numCollected(0), m_overflow(false) + { + } + + int numCollected() const { return m_numCollected; } + bool overflowed() const { return m_overflow; } + + void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) + { + dtIgnoreUnused(tile); + dtIgnoreUnused(polys); + + int numLeft = m_maxPolys - m_numCollected; + int toCopy = count; + if (toCopy > numLeft) + { + m_overflow = true; + toCopy = numLeft; + } + + memcpy(m_polys + m_numCollected, refs, (size_t)toCopy * sizeof(dtPolyRef)); + m_numCollected += toCopy; + } +}; + +/// @par +/// +/// If no polygons are found, the function will return #DT_SUCCESS with a +/// @p polyCount of zero. +/// +/// If @p polys is too small to hold the entire result set, then the array will +/// be filled to capacity. The method of choosing which polygons from the +/// full set are included in the partial result set is undefined. +/// +dtStatus dtNavMeshQuery::queryPolygons(const float* center, const float* extents, + const dtQueryFilter* filter, + dtPolyRef* polys, int* polyCount, const int maxPolys) const +{ + if (!polys || !polyCount || maxPolys < 0) + return DT_FAILURE | DT_INVALID_PARAM; + + dtCollectPolysQuery collector(polys, maxPolys); + + dtStatus status = queryPolygons(center, extents, filter, &collector); + if (dtStatusFailed(status)) + return status; + + *polyCount = collector.numCollected(); + return collector.overflowed() ? DT_SUCCESS | DT_BUFFER_TOO_SMALL : DT_SUCCESS; +} + +/// @par +/// +/// The query will be invoked with batches of polygons. Polygons passed +/// to the query have bounding boxes that overlap with the center and extents +/// passed to this function. The dtPolyQuery::process function is invoked multiple +/// times until all overlapping polygons have been processed. +/// +dtStatus dtNavMeshQuery::queryPolygons(const float* center, const float* extents, + const dtQueryFilter* filter, dtPolyQuery* query) const +{ + dtAssert(m_nav); + + if (!center || !extents || !filter || !query) + return DT_FAILURE | DT_INVALID_PARAM; + + float bmin[3], bmax[3]; + dtVsub(bmin, center, extents); + dtVadd(bmax, center, extents); + + // Find tiles the query touches. + int minx, miny, maxx, maxy; + m_nav->calcTileLoc(bmin, &minx, &miny); + m_nav->calcTileLoc(bmax, &maxx, &maxy); + + static const int MAX_NEIS = 32; + const dtMeshTile* neis[MAX_NEIS]; + + for (int y = miny; y <= maxy; ++y) + { + for (int x = minx; x <= maxx; ++x) + { + const int nneis = m_nav->getTilesAt(x,y,neis,MAX_NEIS); + for (int j = 0; j < nneis; ++j) + { + queryPolygonsInTile(neis[j], bmin, bmax, filter, query); + } + } + } + + return DT_SUCCESS; +} + +/// @par +/// +/// If the end polygon cannot be reached through the navigation graph, +/// the last polygon in the path will be the nearest the end polygon. +/// +/// If the path array is to small to hold the full result, it will be filled as +/// far as possible from the start polygon toward the end polygon. +/// +/// The start and end positions are used to calculate traversal costs. +/// (The y-values impact the result.) +/// +dtStatus dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef, + const float* startPos, const float* endPos, + const dtQueryFilter* filter, + dtPolyRef* path, int* pathCount, const int maxPath) const +{ + dtAssert(m_nav); + dtAssert(m_nodePool); + dtAssert(m_openList); + + if (pathCount) + *pathCount = 0; + + // Validate input + if (!m_nav->isValidPolyRef(startRef) || !m_nav->isValidPolyRef(endRef) || + !startPos || !endPos || !filter || maxPath <= 0 || !path || !pathCount) + return DT_FAILURE | DT_INVALID_PARAM; + + if (startRef == endRef) + { + path[0] = startRef; + *pathCount = 1; + return DT_SUCCESS; + } + + m_nodePool->clear(); + m_openList->clear(); + + dtNode* startNode = m_nodePool->getNode(startRef); + dtVcopy(startNode->pos, startPos); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = dtVdist(startPos, endPos) * H_SCALE; + startNode->id = startRef; + startNode->flags = DT_NODE_OPEN; + m_openList->push(startNode); + + dtNode* lastBestNode = startNode; + float lastBestNodeCost = startNode->total; + + bool outOfNodes = false; + + while (!m_openList->empty()) + { + // Remove node from open list and put it in closed list. + dtNode* bestNode = m_openList->pop(); + bestNode->flags &= ~DT_NODE_OPEN; + bestNode->flags |= DT_NODE_CLOSED; + + // Reached the goal, stop searching. + if (bestNode->id == endRef) + { + lastBestNode = bestNode; + break; + } + + // Get current poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef bestRef = bestNode->id; + const dtMeshTile* bestTile = 0; + const dtPoly* bestPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(bestRef, &bestTile, &bestPoly); + + // Get parent poly and tile. + dtPolyRef parentRef = 0; + const dtMeshTile* parentTile = 0; + const dtPoly* parentPoly = 0; + if (bestNode->pidx) + parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id; + if (parentRef) + m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly); + + for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next) + { + dtPolyRef neighbourRef = bestTile->links[i].ref; + + // Skip invalid ids and do not expand back to where we came from. + if (!neighbourRef || neighbourRef == parentRef) + continue; + + // Get neighbour poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + if (m_nav->getTileAndPolyByRef(neighbourRef, &neighbourTile, &neighbourPoly) == DT_FAILURE) { + continue; + } + + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + // deal explicitly with crossing tile boundaries + unsigned char crossSide = 0; + if (bestTile->links[i].side != 0xff) + crossSide = bestTile->links[i].side >> 1; + + // get the node + dtNode* neighbourNode = m_nodePool->getNode(neighbourRef, crossSide); + if (!neighbourNode) + { + outOfNodes = true; + continue; + } + + // If the node is visited the first time, calculate node position. + if (neighbourNode->flags == 0) + { + getEdgeMidPoint(bestRef, bestPoly, bestTile, + neighbourRef, neighbourPoly, neighbourTile, + neighbourNode->pos); + } + + // Calculate cost and heuristic. + float cost = 0; + float heuristic = 0; + + // Special case for last node. + if (neighbourRef == endRef) + { + // Cost + const float curCost = filter->getCost(bestNode->pos, neighbourNode->pos, + parentRef, parentTile, parentPoly, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly); + const float endCost = filter->getCost(neighbourNode->pos, endPos, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly, + 0, 0, 0); + + cost = bestNode->cost + curCost + endCost; + heuristic = 0; + } + else + { + // Cost + const float curCost = filter->getCost(bestNode->pos, neighbourNode->pos, + parentRef, parentTile, parentPoly, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly); + cost = bestNode->cost + curCost; + heuristic = dtVdist(neighbourNode->pos, endPos)*H_SCALE; + } + + const float total = cost + heuristic; + + // The node is already in open list and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total) + continue; + // The node is already visited and process, and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_CLOSED) && total >= neighbourNode->total) + continue; + + // Add or update the node. + neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode); + neighbourNode->id = neighbourRef; + neighbourNode->flags = (neighbourNode->flags & ~DT_NODE_CLOSED); + neighbourNode->cost = cost; + neighbourNode->total = total; + + if (neighbourNode->flags & DT_NODE_OPEN) + { + // Already in open, update node location. + m_openList->modify(neighbourNode); + } + else + { + // Put the node in open list. + neighbourNode->flags |= DT_NODE_OPEN; + m_openList->push(neighbourNode); + } + + // Update nearest node to target so far. + if (heuristic < lastBestNodeCost) + { + lastBestNodeCost = heuristic; + lastBestNode = neighbourNode; + } + } + } + + dtStatus status = getPathToNode(lastBestNode, path, pathCount, maxPath); + + if (lastBestNode->id != endRef) + status |= DT_PARTIAL_RESULT; + + if (outOfNodes) + status |= DT_OUT_OF_NODES; + + return status; +} + +dtStatus dtNavMeshQuery::getPathToNode(dtNode* endNode, dtPolyRef* path, int* pathCount, int maxPath) const +{ + // Find the length of the entire path. + dtNode* curNode = endNode; + int length = 0; + do + { + length++; + curNode = m_nodePool->getNodeAtIdx(curNode->pidx); + } while (curNode); + + // If the path cannot be fully stored then advance to the last node we will be able to store. + curNode = endNode; + int writeCount; + for (writeCount = length; writeCount > maxPath; writeCount--) + { + dtAssert(curNode); + + curNode = m_nodePool->getNodeAtIdx(curNode->pidx); + } + + // Write path + for (int i = writeCount - 1; i >= 0; i--) + { + dtAssert(curNode); + + path[i] = curNode->id; + curNode = m_nodePool->getNodeAtIdx(curNode->pidx); + } + + dtAssert(!curNode); + + *pathCount = dtMin(length, maxPath); + + if (length > maxPath) + return DT_SUCCESS | DT_BUFFER_TOO_SMALL; + + return DT_SUCCESS; +} + + +/// @par +/// +/// @warning Calling any non-slice methods before calling finalizeSlicedFindPath() +/// or finalizeSlicedFindPathPartial() may result in corrupted data! +/// +/// The @p filter pointer is stored and used for the duration of the sliced +/// path query. +/// +dtStatus dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, + const float* startPos, const float* endPos, + const dtQueryFilter* filter, const unsigned int options) +{ + dtAssert(m_nav); + dtAssert(m_nodePool); + dtAssert(m_openList); + + // Init path state. + memset(&m_query, 0, sizeof(dtQueryData)); + m_query.status = DT_FAILURE; + m_query.startRef = startRef; + m_query.endRef = endRef; + dtVcopy(m_query.startPos, startPos); + dtVcopy(m_query.endPos, endPos); + m_query.filter = filter; + m_query.options = options; + m_query.raycastLimitSqr = FLT_MAX; + + if (!startRef || !endRef) + return DT_FAILURE | DT_INVALID_PARAM; + + // Validate input + if (!m_nav->isValidPolyRef(startRef) || !m_nav->isValidPolyRef(endRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + // trade quality with performance? + if (options & DT_FINDPATH_ANY_ANGLE) + { + // limiting to several times the character radius yields nice results. It is not sensitive + // so it is enough to compute it from the first tile. + const dtMeshTile* tile = m_nav->getTileByRef(startRef); + float agentRadius = tile->header->walkableRadius; + m_query.raycastLimitSqr = dtSqr(agentRadius * DT_RAY_CAST_LIMIT_PROPORTIONS); + } + + if (startRef == endRef) + { + m_query.status = DT_SUCCESS; + return DT_SUCCESS; + } + + m_nodePool->clear(); + m_openList->clear(); + + dtNode* startNode = m_nodePool->getNode(startRef); + dtVcopy(startNode->pos, startPos); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = dtVdist(startPos, endPos) * H_SCALE; + startNode->id = startRef; + startNode->flags = DT_NODE_OPEN; + m_openList->push(startNode); + + m_query.status = DT_IN_PROGRESS; + m_query.lastBestNode = startNode; + m_query.lastBestNodeCost = startNode->total; + + return m_query.status; +} + +dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) +{ + if (!dtStatusInProgress(m_query.status)) + return m_query.status; + + // Make sure the request is still valid. + if (!m_nav->isValidPolyRef(m_query.startRef) || !m_nav->isValidPolyRef(m_query.endRef)) + { + m_query.status = DT_FAILURE; + return DT_FAILURE; + } + + dtRaycastHit rayHit; + rayHit.maxPath = 0; + + int iter = 0; + while (iter < maxIter && !m_openList->empty()) + { + iter++; + + // Remove node from open list and put it in closed list. + dtNode* bestNode = m_openList->pop(); + bestNode->flags &= ~DT_NODE_OPEN; + bestNode->flags |= DT_NODE_CLOSED; + + // Reached the goal, stop searching. + if (bestNode->id == m_query.endRef) + { + m_query.lastBestNode = bestNode; + const dtStatus details = m_query.status & DT_STATUS_DETAIL_MASK; + m_query.status = DT_SUCCESS | details; + if (doneIters) + *doneIters = iter; + return m_query.status; + } + + // Get current poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef bestRef = bestNode->id; + const dtMeshTile* bestTile = 0; + const dtPoly* bestPoly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(bestRef, &bestTile, &bestPoly))) + { + // The polygon has disappeared during the sliced query, fail. + m_query.status = DT_FAILURE; + if (doneIters) + *doneIters = iter; + return m_query.status; + } + + // Get parent and grand parent poly and tile. + dtPolyRef parentRef = 0, grandpaRef = 0; + const dtMeshTile* parentTile = 0; + const dtPoly* parentPoly = 0; + dtNode* parentNode = 0; + if (bestNode->pidx) + { + parentNode = m_nodePool->getNodeAtIdx(bestNode->pidx); + parentRef = parentNode->id; + if (parentNode->pidx) + grandpaRef = m_nodePool->getNodeAtIdx(parentNode->pidx)->id; + } + if (parentRef) + { + bool invalidParent = dtStatusFailed(m_nav->getTileAndPolyByRef(parentRef, &parentTile, &parentPoly)); + if (invalidParent || (grandpaRef && !m_nav->isValidPolyRef(grandpaRef)) ) + { + // The polygon has disappeared during the sliced query, fail. + m_query.status = DT_FAILURE; + if (doneIters) + *doneIters = iter; + return m_query.status; + } + } + + // decide whether to test raycast to previous nodes + bool tryLOS = false; + if (m_query.options & DT_FINDPATH_ANY_ANGLE) + { + if ((parentRef != 0) && (dtVdistSqr(parentNode->pos, bestNode->pos) < m_query.raycastLimitSqr)) + tryLOS = true; + } + + for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next) + { + dtPolyRef neighbourRef = bestTile->links[i].ref; + + // Skip invalid ids and do not expand back to where we came from. + if (!neighbourRef || neighbourRef == parentRef) + continue; + + // Get neighbour poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); + + if (!m_query.filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + // get the neighbor node + dtNode* neighbourNode = m_nodePool->getNode(neighbourRef, 0); + if (!neighbourNode) + { + m_query.status |= DT_OUT_OF_NODES; + continue; + } + + // do not expand to nodes that were already visited from the same parent + if (neighbourNode->pidx != 0 && neighbourNode->pidx == bestNode->pidx) + continue; + + // If the node is visited the first time, calculate node position. + if (neighbourNode->flags == 0) + { + getEdgeMidPoint(bestRef, bestPoly, bestTile, + neighbourRef, neighbourPoly, neighbourTile, + neighbourNode->pos); + } + + // Calculate cost and heuristic. + float cost = 0; + float heuristic = 0; + + // raycast parent + bool foundShortCut = false; + rayHit.pathCost = rayHit.t = 0; + if (tryLOS) + { + raycast(parentRef, parentNode->pos, neighbourNode->pos, m_query.filter, DT_RAYCAST_USE_COSTS, &rayHit, grandpaRef); + foundShortCut = rayHit.t >= 1.0f; + } + + // update move cost + if (foundShortCut) + { + // shortcut found using raycast. Using shorter cost instead + cost = parentNode->cost + rayHit.pathCost; + } + else + { + // No shortcut found. + const float curCost = m_query.filter->getCost(bestNode->pos, neighbourNode->pos, + parentRef, parentTile, parentPoly, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly); + cost = bestNode->cost + curCost; + } + + // Special case for last node. + if (neighbourRef == m_query.endRef) + { + const float endCost = m_query.filter->getCost(neighbourNode->pos, m_query.endPos, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly, + 0, 0, 0); + + cost = cost + endCost; + heuristic = 0; + } + else + { + heuristic = dtVdist(neighbourNode->pos, m_query.endPos)*H_SCALE; + } + + const float total = cost + heuristic; + + // The node is already in open list and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total) + continue; + // The node is already visited and process, and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_CLOSED) && total >= neighbourNode->total) + continue; + + // Add or update the node. + neighbourNode->pidx = foundShortCut ? bestNode->pidx : m_nodePool->getNodeIdx(bestNode); + neighbourNode->id = neighbourRef; + neighbourNode->flags = (neighbourNode->flags & ~(DT_NODE_CLOSED | DT_NODE_PARENT_DETACHED)); + neighbourNode->cost = cost; + neighbourNode->total = total; + if (foundShortCut) + neighbourNode->flags = (neighbourNode->flags | DT_NODE_PARENT_DETACHED); + + if (neighbourNode->flags & DT_NODE_OPEN) + { + // Already in open, update node location. + m_openList->modify(neighbourNode); + } + else + { + // Put the node in open list. + neighbourNode->flags |= DT_NODE_OPEN; + m_openList->push(neighbourNode); + } + + // Update nearest node to target so far. + if (heuristic < m_query.lastBestNodeCost) + { + m_query.lastBestNodeCost = heuristic; + m_query.lastBestNode = neighbourNode; + } + } + } + + // Exhausted all nodes, but could not find path. + if (m_openList->empty()) + { + const dtStatus details = m_query.status & DT_STATUS_DETAIL_MASK; + m_query.status = DT_SUCCESS | details; + } + + if (doneIters) + *doneIters = iter; + + return m_query.status; +} + +dtStatus dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath) +{ + *pathCount = 0; + + if (dtStatusFailed(m_query.status)) + { + // Reset query. + memset(&m_query, 0, sizeof(dtQueryData)); + return DT_FAILURE; + } + + int n = 0; + + if (m_query.startRef == m_query.endRef) + { + // Special case: the search starts and ends at same poly. + path[n++] = m_query.startRef; + } + else + { + // Reverse the path. + dtAssert(m_query.lastBestNode); + + if (m_query.lastBestNode->id != m_query.endRef) + m_query.status |= DT_PARTIAL_RESULT; + + dtNode* prev = 0; + dtNode* node = m_query.lastBestNode; + int prevRay = 0; + do + { + dtNode* next = m_nodePool->getNodeAtIdx(node->pidx); + node->pidx = m_nodePool->getNodeIdx(prev); + prev = node; + int nextRay = node->flags & DT_NODE_PARENT_DETACHED; // keep track of whether parent is not adjacent (i.e. due to raycast shortcut) + node->flags = (node->flags & ~DT_NODE_PARENT_DETACHED) | prevRay; // and store it in the reversed path's node + prevRay = nextRay; + node = next; + } + while (node); + + // Store path + node = prev; + do + { + dtNode* next = m_nodePool->getNodeAtIdx(node->pidx); + dtStatus status = 0; + if (node->flags & DT_NODE_PARENT_DETACHED) + { + float t, normal[3]; + int m; + status = raycast(node->id, node->pos, next->pos, m_query.filter, &t, normal, path+n, &m, maxPath-n); + n += m; + // raycast ends on poly boundary and the path might include the next poly boundary. + if (path[n-1] == next->id) + n--; // remove to avoid duplicates + } + else + { + path[n++] = node->id; + if (n >= maxPath) + status = DT_BUFFER_TOO_SMALL; + } + + if (status & DT_STATUS_DETAIL_MASK) + { + m_query.status |= status & DT_STATUS_DETAIL_MASK; + break; + } + node = next; + } + while (node); + } + + const dtStatus details = m_query.status & DT_STATUS_DETAIL_MASK; + + // Reset query. + memset(&m_query, 0, sizeof(dtQueryData)); + + *pathCount = n; + + return DT_SUCCESS | details; +} + +dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize, + dtPolyRef* path, int* pathCount, const int maxPath) +{ + *pathCount = 0; + + if (existingSize == 0) + { + return DT_FAILURE; + } + + if (dtStatusFailed(m_query.status)) + { + // Reset query. + memset(&m_query, 0, sizeof(dtQueryData)); + return DT_FAILURE; + } + + int n = 0; + + if (m_query.startRef == m_query.endRef) + { + // Special case: the search starts and ends at same poly. + path[n++] = m_query.startRef; + } + else + { + // Find furthest existing node that was visited. + dtNode* prev = 0; + dtNode* node = 0; + for (int i = existingSize-1; i >= 0; --i) + { + m_nodePool->findNodes(existing[i], &node, 1); + if (node) + break; + } + + if (!node) + { + m_query.status |= DT_PARTIAL_RESULT; + dtAssert(m_query.lastBestNode); + node = m_query.lastBestNode; + } + + // Reverse the path. + int prevRay = 0; + do + { + dtNode* next = m_nodePool->getNodeAtIdx(node->pidx); + node->pidx = m_nodePool->getNodeIdx(prev); + prev = node; + int nextRay = node->flags & DT_NODE_PARENT_DETACHED; // keep track of whether parent is not adjacent (i.e. due to raycast shortcut) + node->flags = (node->flags & ~DT_NODE_PARENT_DETACHED) | prevRay; // and store it in the reversed path's node + prevRay = nextRay; + node = next; + } + while (node); + + // Store path + node = prev; + do + { + dtNode* next = m_nodePool->getNodeAtIdx(node->pidx); + dtStatus status = 0; + if (node->flags & DT_NODE_PARENT_DETACHED) + { + float t, normal[3]; + int m; + status = raycast(node->id, node->pos, next->pos, m_query.filter, &t, normal, path+n, &m, maxPath-n); + n += m; + // raycast ends on poly boundary and the path might include the next poly boundary. + if (path[n-1] == next->id) + n--; // remove to avoid duplicates + } + else + { + path[n++] = node->id; + if (n >= maxPath) + status = DT_BUFFER_TOO_SMALL; + } + + if (status & DT_STATUS_DETAIL_MASK) + { + m_query.status |= status & DT_STATUS_DETAIL_MASK; + break; + } + node = next; + } + while (node); + } + + const dtStatus details = m_query.status & DT_STATUS_DETAIL_MASK; + + // Reset query. + memset(&m_query, 0, sizeof(dtQueryData)); + + *pathCount = n; + + return DT_SUCCESS | details; +} + + +dtStatus dtNavMeshQuery::appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref, + float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, + int* straightPathCount, const int maxStraightPath) const +{ + if ((*straightPathCount) > 0 && dtVequal(&straightPath[((*straightPathCount)-1)*3], pos)) + { + // The vertices are equal, update flags and poly. + if (straightPathFlags) + straightPathFlags[(*straightPathCount)-1] = flags; + if (straightPathRefs) + straightPathRefs[(*straightPathCount)-1] = ref; + } + else + { + // Append new vertex. + dtVcopy(&straightPath[(*straightPathCount)*3], pos); + if (straightPathFlags) + straightPathFlags[(*straightPathCount)] = flags; + if (straightPathRefs) + straightPathRefs[(*straightPathCount)] = ref; + (*straightPathCount)++; + + // If there is no space to append more vertices, return. + if ((*straightPathCount) >= maxStraightPath) + { + return DT_SUCCESS | DT_BUFFER_TOO_SMALL; + } + + // If reached end of path, return. + if (flags == DT_STRAIGHTPATH_END) + { + return DT_SUCCESS; + } + } + return DT_IN_PROGRESS; +} + +dtStatus dtNavMeshQuery::appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path, + float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, + int* straightPathCount, const int maxStraightPath, const int options) const +{ + const float* startPos = &straightPath[(*straightPathCount-1)*3]; + // Append or update last vertex + dtStatus stat = 0; + for (int i = startIdx; i < endIdx; i++) + { + // Calculate portal + const dtPolyRef from = path[i]; + const dtMeshTile* fromTile = 0; + const dtPoly* fromPoly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(from, &fromTile, &fromPoly))) + return DT_FAILURE | DT_INVALID_PARAM; + + const dtPolyRef to = path[i+1]; + const dtMeshTile* toTile = 0; + const dtPoly* toPoly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(to, &toTile, &toPoly))) + return DT_FAILURE | DT_INVALID_PARAM; + + float left[3], right[3]; + if (dtStatusFailed(getPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, left, right))) + break; + + if (options & DT_STRAIGHTPATH_AREA_CROSSINGS) + { + // Skip intersection if only area crossings are requested. + if (fromPoly->getArea() == toPoly->getArea()) + continue; + } + + // Append intersection + float s,t; + if (dtIntersectSegSeg2D(startPos, endPos, left, right, s, t)) + { + float pt[3]; + dtVlerp(pt, left,right, t); + + stat = appendVertex(pt, 0, path[i+1], + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath); + if (stat != DT_IN_PROGRESS) + return stat; + } + } + return DT_IN_PROGRESS; +} + +/// @par +/// +/// This method peforms what is often called 'string pulling'. +/// +/// The start position is clamped to the first polygon in the path, and the +/// end position is clamped to the last. So the start and end positions should +/// normally be within or very near the first and last polygons respectively. +/// +/// The returned polygon references represent the reference id of the polygon +/// that is entered at the associated path position. The reference id associated +/// with the end point will always be zero. This allows, for example, matching +/// off-mesh link points to their representative polygons. +/// +/// If the provided result buffers are too small for the entire result set, +/// they will be filled as far as possible from the start toward the end +/// position. +/// +dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos, + const dtPolyRef* path, const int pathSize, + float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, + int* straightPathCount, const int maxStraightPath, const int options) const +{ + dtAssert(m_nav); + + *straightPathCount = 0; + + if (!maxStraightPath) + return DT_FAILURE | DT_INVALID_PARAM; + + if (!path[0]) + return DT_FAILURE | DT_INVALID_PARAM; + + dtStatus stat = 0; + + // TODO: Should this be callers responsibility? + float closestStartPos[3]; + if (dtStatusFailed(closestPointOnPolyBoundary(path[0], startPos, closestStartPos))) + return DT_FAILURE | DT_INVALID_PARAM; + + float closestEndPos[3]; + if (dtStatusFailed(closestPointOnPolyBoundary(path[pathSize-1], endPos, closestEndPos))) + return DT_FAILURE | DT_INVALID_PARAM; + + // Add start point. + stat = appendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0], + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath); + if (stat != DT_IN_PROGRESS) + return stat; + + if (pathSize > 1) + { + float portalApex[3], portalLeft[3], portalRight[3]; + dtVcopy(portalApex, closestStartPos); + dtVcopy(portalLeft, portalApex); + dtVcopy(portalRight, portalApex); + int apexIndex = 0; + int leftIndex = 0; + int rightIndex = 0; + + unsigned char leftPolyType = 0; + unsigned char rightPolyType = 0; + + dtPolyRef leftPolyRef = path[0]; + dtPolyRef rightPolyRef = path[0]; + + for (int i = 0; i < pathSize; ++i) + { + float left[3], right[3]; + unsigned char toType; + + if (i+1 < pathSize) + { + unsigned char fromType; // fromType is ignored. + + // Next portal. + if (dtStatusFailed(getPortalPoints(path[i], path[i+1], left, right, fromType, toType))) + { + // Failed to get portal points, in practice this means that path[i+1] is invalid polygon. + // Clamp the end point to path[i], and return the path so far. + + if (dtStatusFailed(closestPointOnPolyBoundary(path[i], endPos, closestEndPos))) + { + // This should only happen when the first polygon is invalid. + return DT_FAILURE | DT_INVALID_PARAM; + } + + // Apeend portals along the current straight path segment. + if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS)) + { + // Ignore status return value as we're just about to return anyway. + appendPortals(apexIndex, i, closestEndPos, path, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath, options); + } + + // Ignore status return value as we're just about to return anyway. + appendVertex(closestEndPos, 0, path[i], + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath); + + return DT_SUCCESS | DT_PARTIAL_RESULT | ((*straightPathCount >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0); + } + + // If starting really close the portal, advance. + if (i == 0) + { + float t; + if (dtDistancePtSegSqr2D(portalApex, left, right, t) < dtSqr(0.001f)) + continue; + } + } + else + { + // End of the path. + dtVcopy(left, closestEndPos); + dtVcopy(right, closestEndPos); + + toType = DT_POLYTYPE_GROUND; + } + + // Right vertex. + if (dtTriArea2D(portalApex, portalRight, right) <= 0.0f) + { + if (dtVequal(portalApex, portalRight) || dtTriArea2D(portalApex, portalLeft, right) > 0.0f) + { + dtVcopy(portalRight, right); + rightPolyRef = (i+1 < pathSize) ? path[i+1] : 0; + rightPolyType = toType; + rightIndex = i; + } + else + { + // Append portals along the current straight path segment. + if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS)) + { + stat = appendPortals(apexIndex, leftIndex, portalLeft, path, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath, options); + if (stat != DT_IN_PROGRESS) + return stat; + } + + dtVcopy(portalApex, portalLeft); + apexIndex = leftIndex; + + unsigned char flags = 0; + if (!leftPolyRef) + flags = DT_STRAIGHTPATH_END; + else if (leftPolyType == DT_POLYTYPE_OFFMESH_CONNECTION) + flags = DT_STRAIGHTPATH_OFFMESH_CONNECTION; + dtPolyRef ref = leftPolyRef; + + // Append or update vertex + stat = appendVertex(portalApex, flags, ref, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath); + if (stat != DT_IN_PROGRESS) + return stat; + + dtVcopy(portalLeft, portalApex); + dtVcopy(portalRight, portalApex); + leftIndex = apexIndex; + rightIndex = apexIndex; + + // Restart + i = apexIndex; + + continue; + } + } + + // Left vertex. + if (dtTriArea2D(portalApex, portalLeft, left) >= 0.0f) + { + if (dtVequal(portalApex, portalLeft) || dtTriArea2D(portalApex, portalRight, left) < 0.0f) + { + dtVcopy(portalLeft, left); + leftPolyRef = (i+1 < pathSize) ? path[i+1] : 0; + leftPolyType = toType; + leftIndex = i; + } + else + { + // Append portals along the current straight path segment. + if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS)) + { + stat = appendPortals(apexIndex, rightIndex, portalRight, path, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath, options); + if (stat != DT_IN_PROGRESS) + return stat; + } + + dtVcopy(portalApex, portalRight); + apexIndex = rightIndex; + + unsigned char flags = 0; + if (!rightPolyRef) + flags = DT_STRAIGHTPATH_END; + else if (rightPolyType == DT_POLYTYPE_OFFMESH_CONNECTION) + flags = DT_STRAIGHTPATH_OFFMESH_CONNECTION; + dtPolyRef ref = rightPolyRef; + + // Append or update vertex + stat = appendVertex(portalApex, flags, ref, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath); + if (stat != DT_IN_PROGRESS) + return stat; + + dtVcopy(portalLeft, portalApex); + dtVcopy(portalRight, portalApex); + leftIndex = apexIndex; + rightIndex = apexIndex; + + // Restart + i = apexIndex; + + continue; + } + } + } + + // Append portals along the current straight path segment. + if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS)) + { + stat = appendPortals(apexIndex, pathSize-1, closestEndPos, path, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath, options); + if (stat != DT_IN_PROGRESS) + return stat; + } + } + + // Ignore status return value as we're just about to return anyway. + appendVertex(closestEndPos, DT_STRAIGHTPATH_END, 0, + straightPath, straightPathFlags, straightPathRefs, + straightPathCount, maxStraightPath); + + return DT_SUCCESS | ((*straightPathCount >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0); +} + +/// @par +/// +/// This method is optimized for small delta movement and a small number of +/// polygons. If used for too great a distance, the result set will form an +/// incomplete path. +/// +/// @p resultPos will equal the @p endPos if the end is reached. +/// Otherwise the closest reachable position will be returned. +/// +/// @p resultPos is not projected onto the surface of the navigation +/// mesh. Use #getPolyHeight if this is needed. +/// +/// This method treats the end position in the same manner as +/// the #raycast method. (As a 2D point.) See that method's documentation +/// for details. +/// +/// If the @p visited array is too small to hold the entire result set, it will +/// be filled as far as possible from the start position toward the end +/// position. +/// +dtStatus dtNavMeshQuery::moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, + float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const +{ + dtAssert(m_nav); + dtAssert(m_tinyNodePool); + + *visitedCount = 0; + + // Validate input + if (!startRef) + return DT_FAILURE | DT_INVALID_PARAM; + if (!m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + dtStatus status = DT_SUCCESS; + + static const int MAX_STACK = 48; + dtNode* stack[MAX_STACK]; + int nstack = 0; + + m_tinyNodePool->clear(); + + dtNode* startNode = m_tinyNodePool->getNode(startRef); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = 0; + startNode->id = startRef; + startNode->flags = DT_NODE_CLOSED; + stack[nstack++] = startNode; + + float bestPos[3]; + float bestDist = FLT_MAX; + dtNode* bestNode = 0; + dtVcopy(bestPos, startPos); + + // Search constraints + float searchPos[3], searchRadSqr; + dtVlerp(searchPos, startPos, endPos, 0.5f); + searchRadSqr = dtSqr(dtVdist(startPos, endPos)/2.0f + 0.001f); + + float verts[DT_VERTS_PER_POLYGON*3]; + + while (nstack) + { + // Pop front. + dtNode* curNode = stack[0]; + for (int i = 0; i < nstack-1; ++i) + stack[i] = stack[i+1]; + nstack--; + + // Get poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef curRef = curNode->id; + const dtMeshTile* curTile = 0; + const dtPoly* curPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(curRef, &curTile, &curPoly); + + // Collect vertices. + const int nverts = curPoly->vertCount; + for (int i = 0; i < nverts; ++i) + dtVcopy(&verts[i*3], &curTile->verts[curPoly->verts[i]*3]); + + // If target is inside the poly, stop search. + if (dtPointInPolygon(endPos, verts, nverts)) + { + bestNode = curNode; + dtVcopy(bestPos, endPos); + break; + } + + // Find wall edges and find nearest point inside the walls. + for (int i = 0, j = (int)curPoly->vertCount-1; i < (int)curPoly->vertCount; j = i++) + { + // Find links to neighbours. + static const int MAX_NEIS = 8; + int nneis = 0; + dtPolyRef neis[MAX_NEIS]; + + if (curPoly->neis[j] & DT_EXT_LINK) + { + // Tile border. + for (unsigned int k = curPoly->firstLink; k != DT_NULL_LINK; k = curTile->links[k].next) + { + const dtLink* link = &curTile->links[k]; + if (link->edge == j) + { + if (link->ref != 0) + { + const dtMeshTile* neiTile = 0; + const dtPoly* neiPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly); + if (filter->passFilter(link->ref, neiTile, neiPoly)) + { + if (nneis < MAX_NEIS) + neis[nneis++] = link->ref; + } + } + } + } + } + else if (curPoly->neis[j]) + { + const unsigned int idx = (unsigned int)(curPoly->neis[j]-1); + const dtPolyRef ref = m_nav->getPolyRefBase(curTile) | idx; + if (filter->passFilter(ref, curTile, &curTile->polys[idx])) + { + // Internal edge, encode id. + neis[nneis++] = ref; + } + } + + if (!nneis) + { + // Wall edge, calc distance. + const float* vj = &verts[j*3]; + const float* vi = &verts[i*3]; + float tseg; + const float distSqr = dtDistancePtSegSqr2D(endPos, vj, vi, tseg); + if (distSqr < bestDist) + { + // Update nearest distance. + dtVlerp(bestPos, vj,vi, tseg); + bestDist = distSqr; + bestNode = curNode; + } + } + else + { + for (int k = 0; k < nneis; ++k) + { + // Skip if no node can be allocated. + dtNode* neighbourNode = m_tinyNodePool->getNode(neis[k]); + if (!neighbourNode) + continue; + // Skip if already visited. + if (neighbourNode->flags & DT_NODE_CLOSED) + continue; + + // Skip the link if it is too far from search constraint. + // TODO: Maybe should use getPortalPoints(), but this one is way faster. + const float* vj = &verts[j*3]; + const float* vi = &verts[i*3]; + float tseg; + float distSqr = dtDistancePtSegSqr2D(searchPos, vj, vi, tseg); + if (distSqr > searchRadSqr) + continue; + + // Mark as the node as visited and push to queue. + if (nstack < MAX_STACK) + { + neighbourNode->pidx = m_tinyNodePool->getNodeIdx(curNode); + neighbourNode->flags |= DT_NODE_CLOSED; + stack[nstack++] = neighbourNode; + } + } + } + } + } + + int n = 0; + if (bestNode) + { + // Reverse the path. + dtNode* prev = 0; + dtNode* node = bestNode; + do + { + dtNode* next = m_tinyNodePool->getNodeAtIdx(node->pidx); + node->pidx = m_tinyNodePool->getNodeIdx(prev); + prev = node; + node = next; + } + while (node); + + // Store result + node = prev; + do + { + visited[n++] = node->id; + if (n >= maxVisitedSize) + { + status |= DT_BUFFER_TOO_SMALL; + break; + } + node = m_tinyNodePool->getNodeAtIdx(node->pidx); + } + while (node); + } + + dtVcopy(resultPos, bestPos); + + *visitedCount = n; + + return status; +} + + +dtStatus dtNavMeshQuery::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right, + unsigned char& fromType, unsigned char& toType) const +{ + dtAssert(m_nav); + + const dtMeshTile* fromTile = 0; + const dtPoly* fromPoly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(from, &fromTile, &fromPoly))) + return DT_FAILURE | DT_INVALID_PARAM; + fromType = fromPoly->getType(); + + const dtMeshTile* toTile = 0; + const dtPoly* toPoly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(to, &toTile, &toPoly))) + return DT_FAILURE | DT_INVALID_PARAM; + toType = toPoly->getType(); + + return getPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, left, right); +} + +// Returns portal points between two polygons. +dtStatus dtNavMeshQuery::getPortalPoints(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile, + dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile, + float* left, float* right) const +{ + // Find the link that points to the 'to' polygon. + const dtLink* link = 0; + for (unsigned int i = fromPoly->firstLink; i != DT_NULL_LINK; i = fromTile->links[i].next) + { + if (fromTile->links[i].ref == to) + { + link = &fromTile->links[i]; + break; + } + } + if (!link) + return DT_FAILURE | DT_INVALID_PARAM; + + // Handle off-mesh connections. + if (fromPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + // Find link that points to first vertex. + for (unsigned int i = fromPoly->firstLink; i != DT_NULL_LINK; i = fromTile->links[i].next) + { + if (fromTile->links[i].ref == to) + { + const int v = fromTile->links[i].edge; + dtVcopy(left, &fromTile->verts[fromPoly->verts[v]*3]); + dtVcopy(right, &fromTile->verts[fromPoly->verts[v]*3]); + return DT_SUCCESS; + } + } + return DT_FAILURE | DT_INVALID_PARAM; + } + + if (toPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + for (unsigned int i = toPoly->firstLink; i != DT_NULL_LINK; i = toTile->links[i].next) + { + if (toTile->links[i].ref == from) + { + const int v = toTile->links[i].edge; + dtVcopy(left, &toTile->verts[toPoly->verts[v]*3]); + dtVcopy(right, &toTile->verts[toPoly->verts[v]*3]); + return DT_SUCCESS; + } + } + return DT_FAILURE | DT_INVALID_PARAM; + } + + // Find portal vertices. + const int v0 = fromPoly->verts[link->edge]; + const int v1 = fromPoly->verts[(link->edge+1) % (int)fromPoly->vertCount]; + dtVcopy(left, &fromTile->verts[v0*3]); + dtVcopy(right, &fromTile->verts[v1*3]); + + // If the link is at tile boundary, dtClamp the vertices to + // the link width. + if (link->side != 0xff) + { + // Unpack portal limits. + if (link->bmin != 0 || link->bmax != 255) + { + const float s = 1.0f/255.0f; + const float tmin = link->bmin*s; + const float tmax = link->bmax*s; + dtVlerp(left, &fromTile->verts[v0*3], &fromTile->verts[v1*3], tmin); + dtVlerp(right, &fromTile->verts[v0*3], &fromTile->verts[v1*3], tmax); + } + } + + return DT_SUCCESS; +} + +// Returns edge mid point between two polygons. +dtStatus dtNavMeshQuery::getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const +{ + float left[3], right[3]; + unsigned char fromType, toType; + if (dtStatusFailed(getPortalPoints(from, to, left,right, fromType, toType))) + return DT_FAILURE | DT_INVALID_PARAM; + mid[0] = (left[0]+right[0])*0.5f; + mid[1] = (left[1]+right[1])*0.5f; + mid[2] = (left[2]+right[2])*0.5f; + return DT_SUCCESS; +} + +dtStatus dtNavMeshQuery::getEdgeMidPoint(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile, + dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile, + float* mid) const +{ + float left[3], right[3]; + if (dtStatusFailed(getPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, left, right))) + return DT_FAILURE | DT_INVALID_PARAM; + mid[0] = (left[0]+right[0])*0.5f; + mid[1] = (left[1]+right[1])*0.5f; + mid[2] = (left[2]+right[2])*0.5f; + return DT_SUCCESS; +} + + + +/// @par +/// +/// This method is meant to be used for quick, short distance checks. +/// +/// If the path array is too small to hold the result, it will be filled as +/// far as possible from the start postion toward the end position. +/// +/// Using the Hit Parameter (t) +/// +/// If the hit parameter is a very high value (FLT_MAX), then the ray has hit +/// the end position. In this case the path represents a valid corridor to the +/// end position and the value of @p hitNormal is undefined. +/// +/// If the hit parameter is zero, then the start position is on the wall that +/// was hit and the value of @p hitNormal is undefined. +/// +/// If 0 < t < 1.0 then the following applies: +/// +/// @code +/// distanceToHitBorder = distanceToEndPosition * t +/// hitPoint = startPos + (endPos - startPos) * t +/// @endcode +/// +/// Use Case Restriction +/// +/// The raycast ignores the y-value of the end position. (2D check.) This +/// places significant limits on how it can be used. For example: +/// +/// Consider a scene where there is a main floor with a second floor balcony +/// that hangs over the main floor. So the first floor mesh extends below the +/// balcony mesh. The start position is somewhere on the first floor. The end +/// position is on the balcony. +/// +/// The raycast will search toward the end position along the first floor mesh. +/// If it reaches the end position's xz-coordinates it will indicate FLT_MAX +/// (no wall hit), meaning it reached the end position. This is one example of why +/// this method is meant for short distance checks. +/// +dtStatus dtNavMeshQuery::raycast(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, + float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const +{ + dtRaycastHit hit; + hit.path = path; + hit.maxPath = maxPath; + + dtStatus status = raycast(startRef, startPos, endPos, filter, 0, &hit); + + *t = hit.t; + if (hitNormal) + dtVcopy(hitNormal, hit.hitNormal); + if (pathCount) + *pathCount = hit.pathCount; + + return status; +} + + +/// @par +/// +/// This method is meant to be used for quick, short distance checks. +/// +/// If the path array is too small to hold the result, it will be filled as +/// far as possible from the start postion toward the end position. +/// +/// Using the Hit Parameter t of RaycastHit +/// +/// If the hit parameter is a very high value (FLT_MAX), then the ray has hit +/// the end position. In this case the path represents a valid corridor to the +/// end position and the value of @p hitNormal is undefined. +/// +/// If the hit parameter is zero, then the start position is on the wall that +/// was hit and the value of @p hitNormal is undefined. +/// +/// If 0 < t < 1.0 then the following applies: +/// +/// @code +/// distanceToHitBorder = distanceToEndPosition * t +/// hitPoint = startPos + (endPos - startPos) * t +/// @endcode +/// +/// Use Case Restriction +/// +/// The raycast ignores the y-value of the end position. (2D check.) This +/// places significant limits on how it can be used. For example: +/// +/// Consider a scene where there is a main floor with a second floor balcony +/// that hangs over the main floor. So the first floor mesh extends below the +/// balcony mesh. The start position is somewhere on the first floor. The end +/// position is on the balcony. +/// +/// The raycast will search toward the end position along the first floor mesh. +/// If it reaches the end position's xz-coordinates it will indicate FLT_MAX +/// (no wall hit), meaning it reached the end position. This is one example of why +/// this method is meant for short distance checks. +/// +dtStatus dtNavMeshQuery::raycast(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, const unsigned int options, + dtRaycastHit* hit, dtPolyRef prevRef) const +{ + dtAssert(m_nav); + + hit->t = 0; + hit->pathCount = 0; + hit->pathCost = 0; + + // Validate input + if (!startRef || !m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + if (prevRef && !m_nav->isValidPolyRef(prevRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + float dir[3], curPos[3], lastPos[3]; + float verts[DT_VERTS_PER_POLYGON*3+3]; + int n = 0; + + dtVcopy(curPos, startPos); + dtVsub(dir, endPos, startPos); + dtVset(hit->hitNormal, 0, 0, 0); + + dtStatus status = DT_SUCCESS; + + const dtMeshTile* prevTile, *tile, *nextTile; + const dtPoly* prevPoly, *poly, *nextPoly; + dtPolyRef curRef; + + // The API input has been checked already, skip checking internal data. + curRef = startRef; + tile = 0; + poly = 0; + m_nav->getTileAndPolyByRefUnsafe(curRef, &tile, &poly); + nextTile = prevTile = tile; + nextPoly = prevPoly = poly; + if (prevRef) + m_nav->getTileAndPolyByRefUnsafe(prevRef, &prevTile, &prevPoly); + + while (curRef) + { + // Cast ray against current polygon. + + // Collect vertices. + int nv = 0; + for (int i = 0; i < (int)poly->vertCount; ++i) + { + dtVcopy(&verts[nv*3], &tile->verts[poly->verts[i]*3]); + nv++; + } + + float tmin, tmax; + int segMin, segMax; + if (!dtIntersectSegmentPoly2D(startPos, endPos, verts, nv, tmin, tmax, segMin, segMax)) + { + // Could not hit the polygon, keep the old t and report hit. + hit->pathCount = n; + return status; + } + + hit->hitEdgeIndex = segMax; + + // Keep track of furthest t so far. + if (tmax > hit->t) + hit->t = tmax; + + // Store visited polygons. + if (n < hit->maxPath) + hit->path[n++] = curRef; + else + status |= DT_BUFFER_TOO_SMALL; + + // Ray end is completely inside the polygon. + if (segMax == -1) + { + hit->t = FLT_MAX; + hit->pathCount = n; + + // add the cost + if (options & DT_RAYCAST_USE_COSTS) + hit->pathCost += filter->getCost(curPos, endPos, prevRef, prevTile, prevPoly, curRef, tile, poly, curRef, tile, poly); + return status; + } + + // Follow neighbours. + dtPolyRef nextRef = 0; + + for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = tile->links[i].next) + { + const dtLink* link = &tile->links[i]; + + // Find link which contains this edge. + if ((int)link->edge != segMax) + continue; + + // Get pointer to the next polygon. + nextTile = 0; + nextPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(link->ref, &nextTile, &nextPoly); + + // Skip off-mesh connections. + if (nextPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + + // Skip links based on filter. + if (!filter->passFilter(link->ref, nextTile, nextPoly)) + continue; + + // If the link is internal, just return the ref. + if (link->side == 0xff) + { + nextRef = link->ref; + break; + } + + // If the link is at tile boundary, + + // Check if the link spans the whole edge, and accept. + if (link->bmin == 0 && link->bmax == 255) + { + nextRef = link->ref; + break; + } + + // Check for partial edge links. + const int v0 = poly->verts[link->edge]; + const int v1 = poly->verts[(link->edge+1) % poly->vertCount]; + const float* left = &tile->verts[v0*3]; + const float* right = &tile->verts[v1*3]; + + // Check that the intersection lies inside the link portal. + if (link->side == 0 || link->side == 4) + { + // Calculate link size. + const float s = 1.0f/255.0f; + float lmin = left[2] + (right[2] - left[2])*(link->bmin*s); + float lmax = left[2] + (right[2] - left[2])*(link->bmax*s); + if (lmin > lmax) dtSwap(lmin, lmax); + + // Find Z intersection. + float z = startPos[2] + (endPos[2]-startPos[2])*tmax; + if (z >= lmin && z <= lmax) + { + nextRef = link->ref; + break; + } + } + else if (link->side == 2 || link->side == 6) + { + // Calculate link size. + const float s = 1.0f/255.0f; + float lmin = left[0] + (right[0] - left[0])*(link->bmin*s); + float lmax = left[0] + (right[0] - left[0])*(link->bmax*s); + if (lmin > lmax) dtSwap(lmin, lmax); + + // Find X intersection. + float x = startPos[0] + (endPos[0]-startPos[0])*tmax; + if (x >= lmin && x <= lmax) + { + nextRef = link->ref; + break; + } + } + } + + // add the cost + if (options & DT_RAYCAST_USE_COSTS) + { + // compute the intersection point at the furthest end of the polygon + // and correct the height (since the raycast moves in 2d) + dtVcopy(lastPos, curPos); + dtVmad(curPos, startPos, dir, hit->t); + float* e1 = &verts[segMax*3]; + float* e2 = &verts[((segMax+1)%nv)*3]; + float eDir[3], diff[3]; + dtVsub(eDir, e2, e1); + dtVsub(diff, curPos, e1); + float s = dtSqr(eDir[0]) > dtSqr(eDir[2]) ? diff[0] / eDir[0] : diff[2] / eDir[2]; + curPos[1] = e1[1] + eDir[1] * s; + + hit->pathCost += filter->getCost(lastPos, curPos, prevRef, prevTile, prevPoly, curRef, tile, poly, nextRef, nextTile, nextPoly); + } + + if (!nextRef) + { + // No neighbour, we hit a wall. + + // Calculate hit normal. + const int a = segMax; + const int b = segMax+1 < nv ? segMax+1 : 0; + const float* va = &verts[a*3]; + const float* vb = &verts[b*3]; + const float dx = vb[0] - va[0]; + const float dz = vb[2] - va[2]; + hit->hitNormal[0] = dz; + hit->hitNormal[1] = 0; + hit->hitNormal[2] = -dx; + dtVnormalize(hit->hitNormal); + + hit->pathCount = n; + return status; + } + + // No hit, advance to neighbour polygon. + prevRef = curRef; + curRef = nextRef; + prevTile = tile; + tile = nextTile; + prevPoly = poly; + poly = nextPoly; + } + + hit->pathCount = n; + + return status; +} + +/// @par +/// +/// At least one result array must be provided. +/// +/// The order of the result set is from least to highest cost to reach the polygon. +/// +/// A common use case for this method is to perform Dijkstra searches. +/// Candidate polygons are found by searching the graph beginning at the start polygon. +/// +/// If a polygon is not found via the graph search, even if it intersects the +/// search circle, it will not be included in the result set. For example: +/// +/// polyA is the start polygon. +/// polyB shares an edge with polyA. (Is adjacent.) +/// polyC shares an edge with polyB, but not with polyA +/// Even if the search circle overlaps polyC, it will not be included in the +/// result set unless polyB is also in the set. +/// +/// The value of the center point is used as the start position for cost +/// calculations. It is not projected onto the surface of the mesh, so its +/// y-value will effect the costs. +/// +/// Intersection tests occur in 2D. All polygons and the search circle are +/// projected onto the xz-plane. So the y-value of the center point does not +/// effect intersection tests. +/// +/// If the result arrays are to small to hold the entire result set, they will be +/// filled to capacity. +/// +dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius, + const dtQueryFilter* filter, + dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, + int* resultCount, const int maxResult) const +{ + dtAssert(m_nav); + dtAssert(m_nodePool); + dtAssert(m_openList); + + *resultCount = 0; + + // Validate input + if (!startRef || !m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + m_nodePool->clear(); + m_openList->clear(); + + dtNode* startNode = m_nodePool->getNode(startRef); + dtVcopy(startNode->pos, centerPos); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = 0; + startNode->id = startRef; + startNode->flags = DT_NODE_OPEN; + m_openList->push(startNode); + + dtStatus status = DT_SUCCESS; + + int n = 0; + + const float radiusSqr = dtSqr(radius); + + while (!m_openList->empty()) + { + dtNode* bestNode = m_openList->pop(); + bestNode->flags &= ~DT_NODE_OPEN; + bestNode->flags |= DT_NODE_CLOSED; + + // Get poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef bestRef = bestNode->id; + const dtMeshTile* bestTile = 0; + const dtPoly* bestPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(bestRef, &bestTile, &bestPoly); + + // Get parent poly and tile. + dtPolyRef parentRef = 0; + const dtMeshTile* parentTile = 0; + const dtPoly* parentPoly = 0; + if (bestNode->pidx) + parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id; + if (parentRef) + m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly); + + if (n < maxResult) + { + if (resultRef) + resultRef[n] = bestRef; + if (resultParent) + resultParent[n] = parentRef; + if (resultCost) + resultCost[n] = bestNode->total; + ++n; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + + for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next) + { + const dtLink* link = &bestTile->links[i]; + dtPolyRef neighbourRef = link->ref; + // Skip invalid neighbours and do not follow back to parent. + if (!neighbourRef || neighbourRef == parentRef) + continue; + + // Expand to neighbour + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); + + // Do not advance if the polygon is excluded by the filter. + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + // Find edge and calc distance to the edge. + float va[3], vb[3]; + if (!getPortalPoints(bestRef, bestPoly, bestTile, neighbourRef, neighbourPoly, neighbourTile, va, vb)) + continue; + + // If the circle is not touching the next polygon, skip it. + float tseg; + float distSqr = dtDistancePtSegSqr2D(centerPos, va, vb, tseg); + if (distSqr > radiusSqr) + continue; + + dtNode* neighbourNode = m_nodePool->getNode(neighbourRef); + if (!neighbourNode) + { + status |= DT_OUT_OF_NODES; + continue; + } + + if (neighbourNode->flags & DT_NODE_CLOSED) + continue; + + // Cost + if (neighbourNode->flags == 0) + dtVlerp(neighbourNode->pos, va, vb, 0.5f); + + float cost = filter->getCost( + bestNode->pos, neighbourNode->pos, + parentRef, parentTile, parentPoly, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly); + + const float total = bestNode->total + cost; + + // The node is already in open list and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total) + continue; + + neighbourNode->id = neighbourRef; + neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode); + neighbourNode->total = total; + + if (neighbourNode->flags & DT_NODE_OPEN) + { + m_openList->modify(neighbourNode); + } + else + { + neighbourNode->flags = DT_NODE_OPEN; + m_openList->push(neighbourNode); + } + } + } + + *resultCount = n; + + return status; +} + +/// @par +/// +/// The order of the result set is from least to highest cost. +/// +/// At least one result array must be provided. +/// +/// A common use case for this method is to perform Dijkstra searches. +/// Candidate polygons are found by searching the graph beginning at the start +/// polygon. +/// +/// The same intersection test restrictions that apply to findPolysAroundCircle() +/// method apply to this method. +/// +/// The 3D centroid of the search polygon is used as the start position for cost +/// calculations. +/// +/// Intersection tests occur in 2D. All polygons are projected onto the +/// xz-plane. So the y-values of the vertices do not effect intersection tests. +/// +/// If the result arrays are is too small to hold the entire result set, they will +/// be filled to capacity. +/// +dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts, + const dtQueryFilter* filter, + dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, + int* resultCount, const int maxResult) const +{ + dtAssert(m_nav); + dtAssert(m_nodePool); + dtAssert(m_openList); + + *resultCount = 0; + + // Validate input + if (!startRef || !m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + m_nodePool->clear(); + m_openList->clear(); + + float centerPos[3] = {0,0,0}; + for (int i = 0; i < nverts; ++i) + dtVadd(centerPos,centerPos,&verts[i*3]); + dtVscale(centerPos,centerPos,1.0f/nverts); + + dtNode* startNode = m_nodePool->getNode(startRef); + dtVcopy(startNode->pos, centerPos); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = 0; + startNode->id = startRef; + startNode->flags = DT_NODE_OPEN; + m_openList->push(startNode); + + dtStatus status = DT_SUCCESS; + + int n = 0; + + while (!m_openList->empty()) + { + dtNode* bestNode = m_openList->pop(); + bestNode->flags &= ~DT_NODE_OPEN; + bestNode->flags |= DT_NODE_CLOSED; + + // Get poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef bestRef = bestNode->id; + const dtMeshTile* bestTile = 0; + const dtPoly* bestPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(bestRef, &bestTile, &bestPoly); + + // Get parent poly and tile. + dtPolyRef parentRef = 0; + const dtMeshTile* parentTile = 0; + const dtPoly* parentPoly = 0; + if (bestNode->pidx) + parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id; + if (parentRef) + m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly); + + if (n < maxResult) + { + if (resultRef) + resultRef[n] = bestRef; + if (resultParent) + resultParent[n] = parentRef; + if (resultCost) + resultCost[n] = bestNode->total; + + ++n; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + + for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next) + { + const dtLink* link = &bestTile->links[i]; + dtPolyRef neighbourRef = link->ref; + // Skip invalid neighbours and do not follow back to parent. + if (!neighbourRef || neighbourRef == parentRef) + continue; + + // Expand to neighbour + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); + + // Do not advance if the polygon is excluded by the filter. + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + // Find edge and calc distance to the edge. + float va[3], vb[3]; + if (!getPortalPoints(bestRef, bestPoly, bestTile, neighbourRef, neighbourPoly, neighbourTile, va, vb)) + continue; + + // If the poly is not touching the edge to the next polygon, skip the connection it. + float tmin, tmax; + int segMin, segMax; + if (!dtIntersectSegmentPoly2D(va, vb, verts, nverts, tmin, tmax, segMin, segMax)) + continue; + if (tmin > 1.0f || tmax < 0.0f) + continue; + + dtNode* neighbourNode = m_nodePool->getNode(neighbourRef); + if (!neighbourNode) + { + status |= DT_OUT_OF_NODES; + continue; + } + + if (neighbourNode->flags & DT_NODE_CLOSED) + continue; + + // Cost + if (neighbourNode->flags == 0) + dtVlerp(neighbourNode->pos, va, vb, 0.5f); + + float cost = filter->getCost( + bestNode->pos, neighbourNode->pos, + parentRef, parentTile, parentPoly, + bestRef, bestTile, bestPoly, + neighbourRef, neighbourTile, neighbourPoly); + + const float total = bestNode->total + cost; + + // The node is already in open list and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total) + continue; + + neighbourNode->id = neighbourRef; + neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode); + neighbourNode->total = total; + + if (neighbourNode->flags & DT_NODE_OPEN) + { + m_openList->modify(neighbourNode); + } + else + { + neighbourNode->flags = DT_NODE_OPEN; + m_openList->push(neighbourNode); + } + } + } + + *resultCount = n; + + return status; +} + +dtStatus dtNavMeshQuery::getPathFromDijkstraSearch(dtPolyRef endRef, dtPolyRef* path, int* pathCount, int maxPath) const +{ + if (!m_nav->isValidPolyRef(endRef) || !path || !pathCount || maxPath < 0) + return DT_FAILURE | DT_INVALID_PARAM; + + *pathCount = 0; + + dtNode* endNode; + if (m_nodePool->findNodes(endRef, &endNode, 1) != 1 || + (endNode->flags & DT_NODE_CLOSED) == 0) + return DT_FAILURE | DT_INVALID_PARAM; + + return getPathToNode(endNode, path, pathCount, maxPath); +} + +/// @par +/// +/// This method is optimized for a small search radius and small number of result +/// polygons. +/// +/// Candidate polygons are found by searching the navigation graph beginning at +/// the start polygon. +/// +/// The same intersection test restrictions that apply to the findPolysAroundCircle +/// mehtod applies to this method. +/// +/// The value of the center point is used as the start point for cost calculations. +/// It is not projected onto the surface of the mesh, so its y-value will effect +/// the costs. +/// +/// Intersection tests occur in 2D. All polygons and the search circle are +/// projected onto the xz-plane. So the y-value of the center point does not +/// effect intersection tests. +/// +/// If the result arrays are is too small to hold the entire result set, they will +/// be filled to capacity. +/// +dtStatus dtNavMeshQuery::findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius, + const dtQueryFilter* filter, + dtPolyRef* resultRef, dtPolyRef* resultParent, + int* resultCount, const int maxResult) const +{ + dtAssert(m_nav); + dtAssert(m_tinyNodePool); + + *resultCount = 0; + + // Validate input + if (!startRef || !m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + static const int MAX_STACK = 48; + dtNode* stack[MAX_STACK]; + int nstack = 0; + + m_tinyNodePool->clear(); + + dtNode* startNode = m_tinyNodePool->getNode(startRef); + startNode->pidx = 0; + startNode->id = startRef; + startNode->flags = DT_NODE_CLOSED; + stack[nstack++] = startNode; + + const float radiusSqr = dtSqr(radius); + + float pa[DT_VERTS_PER_POLYGON*3]; + float pb[DT_VERTS_PER_POLYGON*3]; + + dtStatus status = DT_SUCCESS; + + int n = 0; + if (n < maxResult) + { + resultRef[n] = startNode->id; + if (resultParent) + resultParent[n] = 0; + ++n; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + + while (nstack) + { + // Pop front. + dtNode* curNode = stack[0]; + for (int i = 0; i < nstack-1; ++i) + stack[i] = stack[i+1]; + nstack--; + + // Get poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef curRef = curNode->id; + const dtMeshTile* curTile = 0; + const dtPoly* curPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(curRef, &curTile, &curPoly); + + for (unsigned int i = curPoly->firstLink; i != DT_NULL_LINK; i = curTile->links[i].next) + { + const dtLink* link = &curTile->links[i]; + dtPolyRef neighbourRef = link->ref; + // Skip invalid neighbours. + if (!neighbourRef) + continue; + + // Skip if cannot alloca more nodes. + dtNode* neighbourNode = m_tinyNodePool->getNode(neighbourRef); + if (!neighbourNode) + continue; + // Skip visited. + if (neighbourNode->flags & DT_NODE_CLOSED) + continue; + + // Expand to neighbour + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); + + // Skip off-mesh connections. + if (neighbourPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + + // Do not advance if the polygon is excluded by the filter. + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + // Find edge and calc distance to the edge. + float va[3], vb[3]; + if (!getPortalPoints(curRef, curPoly, curTile, neighbourRef, neighbourPoly, neighbourTile, va, vb)) + continue; + + // If the circle is not touching the next polygon, skip it. + float tseg; + float distSqr = dtDistancePtSegSqr2D(centerPos, va, vb, tseg); + if (distSqr > radiusSqr) + continue; + + // Mark node visited, this is done before the overlap test so that + // we will not visit the poly again if the test fails. + neighbourNode->flags |= DT_NODE_CLOSED; + neighbourNode->pidx = m_tinyNodePool->getNodeIdx(curNode); + + // Check that the polygon does not collide with existing polygons. + + // Collect vertices of the neighbour poly. + const int npa = neighbourPoly->vertCount; + for (int k = 0; k < npa; ++k) + dtVcopy(&pa[k*3], &neighbourTile->verts[neighbourPoly->verts[k]*3]); + + bool overlap = false; + for (int j = 0; j < n; ++j) + { + dtPolyRef pastRef = resultRef[j]; + + // Connected polys do not overlap. + bool connected = false; + for (unsigned int k = curPoly->firstLink; k != DT_NULL_LINK; k = curTile->links[k].next) + { + if (curTile->links[k].ref == pastRef) + { + connected = true; + break; + } + } + if (connected) + continue; + + // Potentially overlapping. + const dtMeshTile* pastTile = 0; + const dtPoly* pastPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(pastRef, &pastTile, &pastPoly); + + // Get vertices and test overlap + const int npb = pastPoly->vertCount; + for (int k = 0; k < npb; ++k) + dtVcopy(&pb[k*3], &pastTile->verts[pastPoly->verts[k]*3]); + + if (dtOverlapPolyPoly2D(pa,npa, pb,npb)) + { + overlap = true; + break; + } + } + if (overlap) + continue; + + // This poly is fine, store and advance to the poly. + if (n < maxResult) + { + resultRef[n] = neighbourRef; + if (resultParent) + resultParent[n] = curRef; + ++n; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + + if (nstack < MAX_STACK) + { + stack[nstack++] = neighbourNode; + } + } + } + + *resultCount = n; + + return status; +} + + +struct dtSegInterval +{ + dtPolyRef ref; + short tmin, tmax; +}; + +static void insertInterval(dtSegInterval* ints, int& nints, const int maxInts, + const short tmin, const short tmax, const dtPolyRef ref) +{ + if (nints+1 > maxInts) return; + // Find insertion point. + int idx = 0; + while (idx < nints) + { + if (tmax <= ints[idx].tmin) + break; + idx++; + } + // Move current results. + if (nints-idx) + memmove(ints+idx+1, ints+idx, sizeof(dtSegInterval)*(nints-idx)); + // Store + ints[idx].ref = ref; + ints[idx].tmin = tmin; + ints[idx].tmax = tmax; + nints++; +} + +/// @par +/// +/// If the @p segmentRefs parameter is provided, then all polygon segments will be returned. +/// Otherwise only the wall segments are returned. +/// +/// A segment that is normally a portal will be included in the result set as a +/// wall if the @p filter results in the neighbor polygon becoomming impassable. +/// +/// The @p segmentVerts and @p segmentRefs buffers should normally be sized for the +/// maximum segments per polygon of the source navigation mesh. +/// +dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, + float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount, + const int maxSegments) const +{ + dtAssert(m_nav); + + *segmentCount = 0; + + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + if (dtStatusFailed(m_nav->getTileAndPolyByRef(ref, &tile, &poly))) + return DT_FAILURE | DT_INVALID_PARAM; + + int n = 0; + static const int MAX_INTERVAL = 16; + dtSegInterval ints[MAX_INTERVAL]; + int nints; + + const bool storePortals = segmentRefs != 0; + + dtStatus status = DT_SUCCESS; + + for (int i = 0, j = (int)poly->vertCount-1; i < (int)poly->vertCount; j = i++) + { + // Skip non-solid edges. + nints = 0; + if (poly->neis[j] & DT_EXT_LINK) + { + // Tile border. + for (unsigned int k = poly->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) + { + const dtLink* link = &tile->links[k]; + if (link->edge == j) + { + if (link->ref != 0) + { + const dtMeshTile* neiTile = 0; + const dtPoly* neiPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly); + if (filter->passFilter(link->ref, neiTile, neiPoly)) + { + insertInterval(ints, nints, MAX_INTERVAL, link->bmin, link->bmax, link->ref); + } + } + } + } + } + else + { + // Internal edge + dtPolyRef neiRef = 0; + if (poly->neis[j]) + { + const unsigned int idx = (unsigned int)(poly->neis[j]-1); + neiRef = m_nav->getPolyRefBase(tile) | idx; + if (!filter->passFilter(neiRef, tile, &tile->polys[idx])) + neiRef = 0; + } + + // If the edge leads to another polygon and portals are not stored, skip. + if (neiRef != 0 && !storePortals) + continue; + + if (n < maxSegments) + { + const float* vj = &tile->verts[poly->verts[j]*3]; + const float* vi = &tile->verts[poly->verts[i]*3]; + float* seg = &segmentVerts[n*6]; + dtVcopy(seg+0, vj); + dtVcopy(seg+3, vi); + if (segmentRefs) + segmentRefs[n] = neiRef; + n++; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + + continue; + } + + // Add sentinels + insertInterval(ints, nints, MAX_INTERVAL, -1, 0, 0); + insertInterval(ints, nints, MAX_INTERVAL, 255, 256, 0); + + // Store segments. + const float* vj = &tile->verts[poly->verts[j]*3]; + const float* vi = &tile->verts[poly->verts[i]*3]; + for (int k = 1; k < nints; ++k) + { + // Portal segment. + if (storePortals && ints[k].ref) + { + const float tmin = ints[k].tmin/255.0f; + const float tmax = ints[k].tmax/255.0f; + if (n < maxSegments) + { + float* seg = &segmentVerts[n*6]; + dtVlerp(seg+0, vj,vi, tmin); + dtVlerp(seg+3, vj,vi, tmax); + if (segmentRefs) + segmentRefs[n] = ints[k].ref; + n++; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + } + + // Wall segment. + const int imin = ints[k-1].tmax; + const int imax = ints[k].tmin; + if (imin != imax) + { + const float tmin = imin/255.0f; + const float tmax = imax/255.0f; + if (n < maxSegments) + { + float* seg = &segmentVerts[n*6]; + dtVlerp(seg+0, vj,vi, tmin); + dtVlerp(seg+3, vj,vi, tmax); + if (segmentRefs) + segmentRefs[n] = 0; + n++; + } + else + { + status |= DT_BUFFER_TOO_SMALL; + } + } + } + } + + *segmentCount = n; + + return status; +} + +/// @par +/// +/// @p hitPos is not adjusted using the height detail data. +/// +/// @p hitDist will equal the search radius if there is no wall within the +/// radius. In this case the values of @p hitPos and @p hitNormal are +/// undefined. +/// +/// The normal will become unpredicable if @p hitDist is a very small number. +/// +dtStatus dtNavMeshQuery::findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius, + const dtQueryFilter* filter, + float* hitDist, float* hitPos, float* hitNormal) const +{ + dtAssert(m_nav); + dtAssert(m_nodePool); + dtAssert(m_openList); + + // Validate input + if (!startRef || !m_nav->isValidPolyRef(startRef)) + return DT_FAILURE | DT_INVALID_PARAM; + + m_nodePool->clear(); + m_openList->clear(); + + dtNode* startNode = m_nodePool->getNode(startRef); + dtVcopy(startNode->pos, centerPos); + startNode->pidx = 0; + startNode->cost = 0; + startNode->total = 0; + startNode->id = startRef; + startNode->flags = DT_NODE_OPEN; + m_openList->push(startNode); + + float radiusSqr = dtSqr(maxRadius); + + dtStatus status = DT_SUCCESS; + + while (!m_openList->empty()) + { + dtNode* bestNode = m_openList->pop(); + bestNode->flags &= ~DT_NODE_OPEN; + bestNode->flags |= DT_NODE_CLOSED; + + // Get poly and tile. + // The API input has been cheked already, skip checking internal data. + const dtPolyRef bestRef = bestNode->id; + const dtMeshTile* bestTile = 0; + const dtPoly* bestPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(bestRef, &bestTile, &bestPoly); + + // Get parent poly and tile. + dtPolyRef parentRef = 0; + const dtMeshTile* parentTile = 0; + const dtPoly* parentPoly = 0; + if (bestNode->pidx) + parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id; + if (parentRef) + m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly); + + // Hit test walls. + for (int i = 0, j = (int)bestPoly->vertCount-1; i < (int)bestPoly->vertCount; j = i++) + { + // Skip non-solid edges. + if (bestPoly->neis[j] & DT_EXT_LINK) + { + // Tile border. + bool solid = true; + for (unsigned int k = bestPoly->firstLink; k != DT_NULL_LINK; k = bestTile->links[k].next) + { + const dtLink* link = &bestTile->links[k]; + if (link->edge == j) + { + if (link->ref != 0) + { + const dtMeshTile* neiTile = 0; + const dtPoly* neiPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly); + if (filter->passFilter(link->ref, neiTile, neiPoly)) + solid = false; + } + break; + } + } + if (!solid) continue; + } + else if (bestPoly->neis[j]) + { + // Internal edge + const unsigned int idx = (unsigned int)(bestPoly->neis[j]-1); + const dtPolyRef ref = m_nav->getPolyRefBase(bestTile) | idx; + if (filter->passFilter(ref, bestTile, &bestTile->polys[idx])) + continue; + } + + // Calc distance to the edge. + const float* vj = &bestTile->verts[bestPoly->verts[j]*3]; + const float* vi = &bestTile->verts[bestPoly->verts[i]*3]; + float tseg; + float distSqr = dtDistancePtSegSqr2D(centerPos, vj, vi, tseg); + + // Edge is too far, skip. + if (distSqr > radiusSqr) + continue; + + // Hit wall, update radius. + radiusSqr = distSqr; + // Calculate hit pos. + hitPos[0] = vj[0] + (vi[0] - vj[0])*tseg; + hitPos[1] = vj[1] + (vi[1] - vj[1])*tseg; + hitPos[2] = vj[2] + (vi[2] - vj[2])*tseg; + } + + for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next) + { + const dtLink* link = &bestTile->links[i]; + dtPolyRef neighbourRef = link->ref; + // Skip invalid neighbours and do not follow back to parent. + if (!neighbourRef || neighbourRef == parentRef) + continue; + + // Expand to neighbour. + const dtMeshTile* neighbourTile = 0; + const dtPoly* neighbourPoly = 0; + m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); + + // Skip off-mesh connections. + if (neighbourPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + + // Calc distance to the edge. + const float* va = &bestTile->verts[bestPoly->verts[link->edge]*3]; + const float* vb = &bestTile->verts[bestPoly->verts[(link->edge+1) % bestPoly->vertCount]*3]; + float tseg; + float distSqr = dtDistancePtSegSqr2D(centerPos, va, vb, tseg); + + // If the circle is not touching the next polygon, skip it. + if (distSqr > radiusSqr) + continue; + + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + continue; + + dtNode* neighbourNode = m_nodePool->getNode(neighbourRef); + if (!neighbourNode) + { + status |= DT_OUT_OF_NODES; + continue; + } + + if (neighbourNode->flags & DT_NODE_CLOSED) + continue; + + // Cost + if (neighbourNode->flags == 0) + { + getEdgeMidPoint(bestRef, bestPoly, bestTile, + neighbourRef, neighbourPoly, neighbourTile, neighbourNode->pos); + } + + const float total = bestNode->total + dtVdist(bestNode->pos, neighbourNode->pos); + + // The node is already in open list and the new result is worse, skip. + if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total) + continue; + + neighbourNode->id = neighbourRef; + neighbourNode->flags = (neighbourNode->flags & ~DT_NODE_CLOSED); + neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode); + neighbourNode->total = total; + + if (neighbourNode->flags & DT_NODE_OPEN) + { + m_openList->modify(neighbourNode); + } + else + { + neighbourNode->flags |= DT_NODE_OPEN; + m_openList->push(neighbourNode); + } + } + } + + // Calc hit normal. + dtVsub(hitNormal, centerPos, hitPos); + dtVnormalize(hitNormal); + + *hitDist = dtMathSqrtf(radiusSqr); + + return status; +} + +bool dtNavMeshQuery::isValidPolyRef(dtPolyRef ref, const dtQueryFilter* filter) const +{ + const dtMeshTile* tile = 0; + const dtPoly* poly = 0; + dtStatus status = m_nav->getTileAndPolyByRef(ref, &tile, &poly); + // If cannot get polygon, assume it does not exists and boundary is invalid. + if (dtStatusFailed(status)) + return false; + // If cannot pass filter, assume flags has changed and boundary is invalid. + if (!filter->passFilter(ref, tile, poly)) + return false; + return true; +} + +/// @par +/// +/// The closed list is the list of polygons that were fully evaluated during +/// the last navigation graph search. (A* or Dijkstra) +/// +bool dtNavMeshQuery::isInClosedList(dtPolyRef ref) const +{ + if (!m_nodePool) return false; + + dtNode* nodes[DT_MAX_STATES_PER_NODE]; + int n= m_nodePool->findNodes(ref, nodes, DT_MAX_STATES_PER_NODE); + + for (int i=0; iflags & DT_NODE_CLOSED) + return true; + } + + return false; +} diff --git a/libs/recast/detour/src/DetourNode.cpp b/libs/recast/detour/src/DetourNode.cpp new file mode 100644 index 000000000..48abbba6b --- /dev/null +++ b/libs/recast/detour/src/DetourNode.cpp @@ -0,0 +1,200 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include "DetourNode.h" +#include "DetourAlloc.h" +#include "DetourAssert.h" +#include "DetourCommon.h" +#include + +#ifdef DT_POLYREF64 +// From Thomas Wang, https://gist.github.com/badboy/6267743 +inline unsigned int dtHashRef(dtPolyRef a) +{ + a = (~a) + (a << 18); // a = (a << 18) - a - 1; + a = a ^ (a >> 31); + a = a * 21; // a = (a + (a << 2)) + (a << 4); + a = a ^ (a >> 11); + a = a + (a << 6); + a = a ^ (a >> 22); + return (unsigned int)a; +} +#else +inline unsigned int dtHashRef(dtPolyRef a) +{ + a += ~(a<<15); + a ^= (a>>10); + a += (a<<3); + a ^= (a>>6); + a += ~(a<<11); + a ^= (a>>16); + return (unsigned int)a; +} +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +dtNodePool::dtNodePool(int maxNodes, int hashSize) : + m_nodes(0), + m_first(0), + m_next(0), + m_maxNodes(maxNodes), + m_hashSize(hashSize), + m_nodeCount(0) +{ + dtAssert(dtNextPow2(m_hashSize) == (unsigned int)m_hashSize); + // pidx is special as 0 means "none" and 1 is the first node. For that reason + // we have 1 fewer nodes available than the number of values it can contain. + dtAssert(m_maxNodes > 0 && m_maxNodes <= DT_NULL_IDX && m_maxNodes <= (1 << DT_NODE_PARENT_BITS) - 1); + + m_nodes = (dtNode*)dtAlloc(sizeof(dtNode)*m_maxNodes, DT_ALLOC_PERM); + m_next = (dtNodeIndex*)dtAlloc(sizeof(dtNodeIndex)*m_maxNodes, DT_ALLOC_PERM); + m_first = (dtNodeIndex*)dtAlloc(sizeof(dtNodeIndex)*hashSize, DT_ALLOC_PERM); + + dtAssert(m_nodes); + dtAssert(m_next); + dtAssert(m_first); + + memset(m_first, 0xff, sizeof(dtNodeIndex)*m_hashSize); + memset(m_next, 0xff, sizeof(dtNodeIndex)*m_maxNodes); +} + +dtNodePool::~dtNodePool() +{ + dtFree(m_nodes); + dtFree(m_next); + dtFree(m_first); +} + +void dtNodePool::clear() +{ + memset(m_first, 0xff, sizeof(dtNodeIndex)*m_hashSize); + m_nodeCount = 0; +} + +unsigned int dtNodePool::findNodes(dtPolyRef id, dtNode** nodes, const int maxNodes) +{ + int n = 0; + unsigned int bucket = dtHashRef(id) & (m_hashSize-1); + dtNodeIndex i = m_first[bucket]; + while (i != DT_NULL_IDX) + { + if (m_nodes[i].id == id) + { + if (n >= maxNodes) + return n; + nodes[n++] = &m_nodes[i]; + } + i = m_next[i]; + } + + return n; +} + +dtNode* dtNodePool::findNode(dtPolyRef id, unsigned char state) +{ + unsigned int bucket = dtHashRef(id) & (m_hashSize-1); + dtNodeIndex i = m_first[bucket]; + while (i != DT_NULL_IDX) + { + if (m_nodes[i].id == id && m_nodes[i].state == state) + return &m_nodes[i]; + i = m_next[i]; + } + return 0; +} + +dtNode* dtNodePool::getNode(dtPolyRef id, unsigned char state) +{ + unsigned int bucket = dtHashRef(id) & (m_hashSize-1); + dtNodeIndex i = m_first[bucket]; + dtNode* node = 0; + while (i != DT_NULL_IDX) + { + if (m_nodes[i].id == id && m_nodes[i].state == state) + return &m_nodes[i]; + i = m_next[i]; + } + + if (m_nodeCount >= m_maxNodes) + return 0; + + i = (dtNodeIndex)m_nodeCount; + m_nodeCount++; + + // Init node + node = &m_nodes[i]; + node->pidx = 0; + node->cost = 0; + node->total = 0; + node->id = id; + node->state = state; + node->flags = 0; + + m_next[i] = m_first[bucket]; + m_first[bucket] = i; + + return node; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +dtNodeQueue::dtNodeQueue(int n) : + m_heap(0), + m_capacity(n), + m_size(0) +{ + dtAssert(m_capacity > 0); + + m_heap = (dtNode**)dtAlloc(sizeof(dtNode*)*(m_capacity+1), DT_ALLOC_PERM); + dtAssert(m_heap); +} + +dtNodeQueue::~dtNodeQueue() +{ + dtFree(m_heap); +} + +void dtNodeQueue::bubbleUp(int i, dtNode* node) +{ + int parent = (i-1)/2; + // note: (index > 0) means there is a parent + while ((i > 0) && (m_heap[parent]->total > node->total)) + { + m_heap[i] = m_heap[parent]; + i = parent; + parent = (i-1)/2; + } + m_heap[i] = node; +} + +void dtNodeQueue::trickleDown(int i, dtNode* node) +{ + int child = (i*2)+1; + while (child < m_size) + { + if (((child+1) < m_size) && + (m_heap[child]->total > m_heap[child+1]->total)) + { + child++; + } + m_heap[i] = m_heap[child]; + i = child; + child = (i*2)+1; + } + bubbleUp(i, node); +} diff --git a/libs/recast/detour_tile_cache/include/DetourTileCache.h b/libs/recast/detour_tile_cache/include/DetourTileCache.h new file mode 100644 index 000000000..c45910cd5 --- /dev/null +++ b/libs/recast/detour_tile_cache/include/DetourTileCache.h @@ -0,0 +1,247 @@ +#ifndef DETOURTILECACHE_H +#define DETOURTILECACHE_H + +#include "DetourStatus.h" + + + +typedef unsigned int dtObstacleRef; + +typedef unsigned int dtCompressedTileRef; + +/// Flags for addTile +enum dtCompressedTileFlags +{ + DT_COMPRESSEDTILE_FREE_DATA = 0x01, ///< Navmesh owns the tile memory and should free it. +}; + +struct dtCompressedTile +{ + unsigned int salt; ///< Counter describing modifications to the tile. + struct dtTileCacheLayerHeader* header; + unsigned char* compressed; + int compressedSize; + unsigned char* data; + int dataSize; + unsigned int flags; + dtCompressedTile* next; +}; + +enum ObstacleState +{ + DT_OBSTACLE_EMPTY, + DT_OBSTACLE_PROCESSING, + DT_OBSTACLE_PROCESSED, + DT_OBSTACLE_REMOVING, +}; + +enum ObstacleType +{ + DT_OBSTACLE_CYLINDER, + DT_OBSTACLE_BOX, +}; + +struct dtObstacleCylinder +{ + float pos[ 3 ]; + float radius; + float height; +}; + +struct dtObstacleBox +{ + float bmin[ 3 ]; + float bmax[ 3 ]; +}; + +static const int DT_MAX_TOUCHED_TILES = 8; +struct dtTileCacheObstacle +{ + union + { + dtObstacleCylinder cylinder; + dtObstacleBox box; + }; + + dtCompressedTileRef touched[DT_MAX_TOUCHED_TILES]; + dtCompressedTileRef pending[DT_MAX_TOUCHED_TILES]; + unsigned short salt; + unsigned char type; + unsigned char state; + unsigned char ntouched; + unsigned char npending; + dtTileCacheObstacle* next; +}; + +struct dtTileCacheParams +{ + float orig[3]; + float cs, ch; + int width, height; + float walkableHeight; + float walkableRadius; + float walkableClimb; + float maxSimplificationError; + int maxTiles; + int maxObstacles; +}; + +struct dtTileCacheMeshProcess +{ + virtual ~dtTileCacheMeshProcess() { } + + virtual void process(struct dtNavMeshCreateParams* params, + unsigned char* polyAreas, unsigned short* polyFlags) = 0; +}; + + +class dtTileCache +{ +public: + dtTileCache(); + ~dtTileCache(); + + struct dtTileCacheAlloc* getAlloc() { return m_talloc; } + struct dtTileCacheCompressor* getCompressor() { return m_tcomp; } + const dtTileCacheParams* getParams() const { return &m_params; } + + inline int getTileCount() const { return m_params.maxTiles; } + inline const dtCompressedTile* getTile(const int i) const { return &m_tiles[i]; } + + inline int getObstacleCount() const { return m_params.maxObstacles; } + inline const dtTileCacheObstacle* getObstacle(const int i) const { return &m_obstacles[i]; } + + const dtTileCacheObstacle* getObstacleByRef(dtObstacleRef ref); + + dtObstacleRef getObstacleRef(const dtTileCacheObstacle* obmin) const; + + dtStatus init(const dtTileCacheParams* params, + struct dtTileCacheAlloc* talloc, + struct dtTileCacheCompressor* tcomp, + struct dtTileCacheMeshProcess* tmproc); + + int getTilesAt(const int tx, const int ty, dtCompressedTileRef* tiles, const int maxTiles) const ; + + dtCompressedTile* getTileAt(const int tx, const int ty, const int tlayer); + dtCompressedTileRef getTileRef(const dtCompressedTile* tile) const; + const dtCompressedTile* getTileByRef(dtCompressedTileRef ref) const; + + dtStatus addTile(unsigned char* data, const int dataSize, unsigned char flags, dtCompressedTileRef* result); + + dtStatus removeTile(dtCompressedTileRef ref, unsigned char** data, int* dataSize); + + dtStatus addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result); + dtStatus addBoxObstacle(const float* bmin, const float* bmax, dtObstacleRef* result); + + dtStatus removeObstacle(const dtObstacleRef ref); + + dtStatus queryTiles(const float* bmin, const float* bmax, + dtCompressedTileRef* results, int* resultCount, const int maxResults) const; + + /// Updates the tile cache by rebuilding tiles touched by unfinished obstacle requests. + /// @param[in] dt The time step size. Currently not used. + /// @param[in] navmesh The mesh to affect when rebuilding tiles. + /// @param[out] upToDate Whether the tile cache is fully up to date with obstacle requests and tile rebuilds. + /// If the tile cache is up to date another (immediate) call to update will have no effect; + /// otherwise another call will continue processing obstacle requests and tile rebuilds. + dtStatus update(const float dt, class dtNavMesh* navmesh, bool* upToDate = 0); + + dtStatus buildNavMeshTilesAt(const int tx, const int ty, class dtNavMesh* navmesh); + + dtStatus buildNavMeshTile(const dtCompressedTileRef ref, class dtNavMesh* navmesh); + + void calcTightTileBounds(const struct dtTileCacheLayerHeader* header, float* bmin, float* bmax) const; + + void getObstacleBounds(const struct dtTileCacheObstacle* ob, float* bmin, float* bmax) const; + + + /// Encodes a tile id. + inline dtCompressedTileRef encodeTileId(unsigned int salt, unsigned int it) const + { + return ((dtCompressedTileRef)salt << m_tileBits) | (dtCompressedTileRef)it; + } + + /// Decodes a tile salt. + inline unsigned int decodeTileIdSalt(dtCompressedTileRef ref) const + { + const dtCompressedTileRef saltMask = ((dtCompressedTileRef)1<> m_tileBits) & saltMask); + } + + /// Decodes a tile id. + inline unsigned int decodeTileIdTile(dtCompressedTileRef ref) const + { + const dtCompressedTileRef tileMask = ((dtCompressedTileRef)1<> 16) & saltMask); + } + + /// Decodes an obstacle id. + inline unsigned int decodeObstacleIdObstacle(dtObstacleRef ref) const + { + const dtObstacleRef tileMask = ((dtObstacleRef)1<<16)-1; + return (unsigned int)(ref & tileMask); + } + + +private: + // Explicitly disabled copy constructor and copy assignment operator. + dtTileCache(const dtTileCache&); + dtTileCache& operator=(const dtTileCache&); + + enum ObstacleRequestAction + { + REQUEST_ADD, + REQUEST_REMOVE, + }; + + struct ObstacleRequest + { + int action; + dtObstacleRef ref; + }; + + int m_tileLutSize; ///< Tile hash lookup size (must be pot). + int m_tileLutMask; ///< Tile hash lookup mask. + + dtCompressedTile** m_posLookup; ///< Tile hash lookup. + dtCompressedTile* m_nextFreeTile; ///< Freelist of tiles. + dtCompressedTile* m_tiles; ///< List of tiles. + + unsigned int m_saltBits; ///< Number of salt bits in the tile ID. + unsigned int m_tileBits; ///< Number of tile bits in the tile ID. + + dtTileCacheParams m_params; + + dtTileCacheAlloc* m_talloc; + dtTileCacheCompressor* m_tcomp; + dtTileCacheMeshProcess* m_tmproc; + + dtTileCacheObstacle* m_obstacles; + dtTileCacheObstacle* m_nextFreeObstacle; + + static const int MAX_REQUESTS = 64; + ObstacleRequest m_reqs[MAX_REQUESTS]; + int m_nreqs; + + static const int MAX_UPDATE = 64; + dtCompressedTileRef m_update[MAX_UPDATE]; + int m_nupdate; +}; + +dtTileCache* dtAllocTileCache(); +void dtFreeTileCache(dtTileCache* tc); + +#endif diff --git a/libs/recast/detour_tile_cache/include/DetourTileCacheBuilder.h b/libs/recast/detour_tile_cache/include/DetourTileCacheBuilder.h new file mode 100644 index 000000000..d1ef80e1d --- /dev/null +++ b/libs/recast/detour_tile_cache/include/DetourTileCacheBuilder.h @@ -0,0 +1,153 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef DETOURTILECACHEBUILDER_H +#define DETOURTILECACHEBUILDER_H + +#include "DetourAlloc.h" +#include "DetourStatus.h" + +static const int DT_TILECACHE_MAGIC = 'D'<<24 | 'T'<<16 | 'L'<<8 | 'R'; ///< 'DTLR'; +static const int DT_TILECACHE_VERSION = 1; + +static const unsigned char DT_TILECACHE_NULL_AREA = 0; +static const unsigned char DT_TILECACHE_WALKABLE_AREA = 63; +static const unsigned short DT_TILECACHE_NULL_IDX = 0xffff; + +struct dtTileCacheLayerHeader +{ + int magic; ///< Data magic + int version; ///< Data version + int tx,ty,tlayer; + float bmin[3], bmax[3]; + unsigned short hmin, hmax; ///< Height min/max range + unsigned char width, height; ///< Dimension of the layer. + unsigned char minx, maxx, miny, maxy; ///< Usable sub-region. +}; + +struct dtTileCacheLayer +{ + dtTileCacheLayerHeader* header; + unsigned char regCount; ///< Region count. + unsigned char* heights; + unsigned char* areas; + unsigned char* cons; + unsigned char* regs; +}; + +struct dtTileCacheContour +{ + int nverts; + unsigned char* verts; + unsigned char reg; + unsigned char area; +}; + +struct dtTileCacheContourSet +{ + int nconts; + dtTileCacheContour* conts; +}; + +struct dtTileCachePolyMesh +{ + int nvp; + int nverts; ///< Number of vertices. + int npolys; ///< Number of polygons. + unsigned short* verts; ///< Vertices of the mesh, 3 elements per vertex. + unsigned short* polys; ///< Polygons of the mesh, nvp*2 elements per polygon. + unsigned short* flags; ///< Per polygon flags. + unsigned char* areas; ///< Area ID of polygons. +}; + + +struct dtTileCacheAlloc +{ + virtual ~dtTileCacheAlloc() {} + + virtual void reset() {} + + virtual void* alloc(const size_t size) + { + return dtAlloc(size, DT_ALLOC_TEMP); + } + + virtual void free(void* ptr) + { + dtFree(ptr); + } +}; + +struct dtTileCacheCompressor +{ + virtual ~dtTileCacheCompressor() { } + + virtual int maxCompressedSize(const int bufferSize) = 0; + virtual dtStatus compress(const unsigned char* buffer, const int bufferSize, + unsigned char* compressed, const int maxCompressedSize, int* compressedSize) = 0; + virtual dtStatus decompress(const unsigned char* compressed, const int compressedSize, + unsigned char* buffer, const int maxBufferSize, int* bufferSize) = 0; +}; + + +dtStatus dtBuildTileCacheLayer(dtTileCacheCompressor* comp, + dtTileCacheLayerHeader* header, + const unsigned char* heights, + const unsigned char* areas, + const unsigned char* cons, + unsigned char** outData, int* outDataSize); + +void dtFreeTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheLayer* layer); + +dtStatus dtDecompressTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheCompressor* comp, + unsigned char* compressed, const int compressedSize, + dtTileCacheLayer** layerOut); + +dtTileCacheContourSet* dtAllocTileCacheContourSet(dtTileCacheAlloc* alloc); +void dtFreeTileCacheContourSet(dtTileCacheAlloc* alloc, dtTileCacheContourSet* cset); + +dtTileCachePolyMesh* dtAllocTileCachePolyMesh(dtTileCacheAlloc* alloc); +void dtFreeTileCachePolyMesh(dtTileCacheAlloc* alloc, dtTileCachePolyMesh* lmesh); + +dtStatus dtMarkCylinderArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch, + const float* pos, const float radius, const float height, const unsigned char areaId); + +dtStatus dtMarkBoxArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch, + const float* bmin, const float* bmax, const unsigned char areaId); + +dtStatus dtBuildTileCacheRegions(dtTileCacheAlloc* alloc, + dtTileCacheLayer& layer, + const int walkableClimb); + +dtStatus dtBuildTileCacheContours(dtTileCacheAlloc* alloc, + dtTileCacheLayer& layer, + const int walkableClimb, const float maxError, + dtTileCacheContourSet& lcset); + +dtStatus dtBuildTileCachePolyMesh(dtTileCacheAlloc* alloc, + dtTileCacheContourSet& lcset, + dtTileCachePolyMesh& mesh); + +/// Swaps the endianess of the compressed tile data's header (#dtTileCacheLayerHeader). +/// Tile layer data does not need endian swapping as it consits only of bytes. +/// @param[in,out] data The tile data array. +/// @param[in] dataSize The size of the data array. +bool dtTileCacheHeaderSwapEndian(unsigned char* data, const int dataSize); + + +#endif // DETOURTILECACHEBUILDER_H diff --git a/libs/recast/detour_tile_cache/src/DetourTileCache.cpp b/libs/recast/detour_tile_cache/src/DetourTileCache.cpp new file mode 100644 index 000000000..cf575046c --- /dev/null +++ b/libs/recast/detour_tile_cache/src/DetourTileCache.cpp @@ -0,0 +1,764 @@ +#include "DetourTileCache.h" +#include "DetourTileCacheBuilder.h" +#include "DetourNavMeshBuilder.h" +#include "DetourNavMesh.h" +#include "DetourCommon.h" +#include "DetourMath.h" +#include "DetourAlloc.h" +#include "DetourAssert.h" +#include +#include + +dtTileCache* dtAllocTileCache() +{ + void* mem = dtAlloc(sizeof(dtTileCache), DT_ALLOC_PERM); + if (!mem) return 0; + return new(mem) dtTileCache; +} + +void dtFreeTileCache(dtTileCache* tc) +{ + if (!tc) return; + tc->~dtTileCache(); + dtFree(tc); +} + +static bool contains(const dtCompressedTileRef* a, const int n, const dtCompressedTileRef v) +{ + for (int i = 0; i < n; ++i) + if (a[i] == v) + return true; + return false; +} + +inline int computeTileHash(int x, int y, const int mask) +{ + const unsigned int h1 = 0x8da6b343; // Large multiplicative constants; + const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes + unsigned int n = h1 * x + h2 * y; + return (int)(n & mask); +} + + +struct NavMeshTileBuildContext +{ + inline NavMeshTileBuildContext(struct dtTileCacheAlloc* a) : layer(0), lcset(0), lmesh(0), alloc(a) {} + inline ~NavMeshTileBuildContext() { purge(); } + void purge() + { + dtFreeTileCacheLayer(alloc, layer); + layer = 0; + dtFreeTileCacheContourSet(alloc, lcset); + lcset = 0; + dtFreeTileCachePolyMesh(alloc, lmesh); + lmesh = 0; + } + struct dtTileCacheLayer* layer; + struct dtTileCacheContourSet* lcset; + struct dtTileCachePolyMesh* lmesh; + struct dtTileCacheAlloc* alloc; +}; + + +dtTileCache::dtTileCache() : + m_tileLutSize(0), + m_tileLutMask(0), + m_posLookup(0), + m_nextFreeTile(0), + m_tiles(0), + m_saltBits(0), + m_tileBits(0), + m_talloc(0), + m_tcomp(0), + m_tmproc(0), + m_obstacles(0), + m_nextFreeObstacle(0), + m_nreqs(0), + m_nupdate(0) +{ + memset(&m_params, 0, sizeof(m_params)); + memset(m_reqs, 0, sizeof(ObstacleRequest) * MAX_REQUESTS); +} + +dtTileCache::~dtTileCache() +{ + for (int i = 0; i < m_params.maxTiles; ++i) + { + if (m_tiles[i].flags & DT_COMPRESSEDTILE_FREE_DATA) + { + dtFree(m_tiles[i].data); + m_tiles[i].data = 0; + } + } + dtFree(m_obstacles); + m_obstacles = 0; + dtFree(m_posLookup); + m_posLookup = 0; + dtFree(m_tiles); + m_tiles = 0; + m_nreqs = 0; + m_nupdate = 0; +} + +const dtCompressedTile* dtTileCache::getTileByRef(dtCompressedTileRef ref) const +{ + if (!ref) + return 0; + unsigned int tileIndex = decodeTileIdTile(ref); + unsigned int tileSalt = decodeTileIdSalt(ref); + if ((int)tileIndex >= m_params.maxTiles) + return 0; + const dtCompressedTile* tile = &m_tiles[tileIndex]; + if (tile->salt != tileSalt) + return 0; + return tile; +} + + +dtStatus dtTileCache::init(const dtTileCacheParams* params, + dtTileCacheAlloc* talloc, + dtTileCacheCompressor* tcomp, + dtTileCacheMeshProcess* tmproc) +{ + m_talloc = talloc; + m_tcomp = tcomp; + m_tmproc = tmproc; + m_nreqs = 0; + memcpy(&m_params, params, sizeof(m_params)); + + // Alloc space for obstacles. + m_obstacles = (dtTileCacheObstacle*)dtAlloc(sizeof(dtTileCacheObstacle)*m_params.maxObstacles, DT_ALLOC_PERM); + if (!m_obstacles) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(m_obstacles, 0, sizeof(dtTileCacheObstacle)*m_params.maxObstacles); + m_nextFreeObstacle = 0; + for (int i = m_params.maxObstacles-1; i >= 0; --i) + { + m_obstacles[i].salt = 1; + m_obstacles[i].next = m_nextFreeObstacle; + m_nextFreeObstacle = &m_obstacles[i]; + } + + // Init tiles + m_tileLutSize = dtNextPow2(m_params.maxTiles/4); + if (!m_tileLutSize) m_tileLutSize = 1; + m_tileLutMask = m_tileLutSize-1; + + m_tiles = (dtCompressedTile*)dtAlloc(sizeof(dtCompressedTile)*m_params.maxTiles, DT_ALLOC_PERM); + if (!m_tiles) + return DT_FAILURE | DT_OUT_OF_MEMORY; + m_posLookup = (dtCompressedTile**)dtAlloc(sizeof(dtCompressedTile*)*m_tileLutSize, DT_ALLOC_PERM); + if (!m_posLookup) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(m_tiles, 0, sizeof(dtCompressedTile)*m_params.maxTiles); + memset(m_posLookup, 0, sizeof(dtCompressedTile*)*m_tileLutSize); + m_nextFreeTile = 0; + for (int i = m_params.maxTiles-1; i >= 0; --i) + { + m_tiles[i].salt = 1; + m_tiles[i].next = m_nextFreeTile; + m_nextFreeTile = &m_tiles[i]; + } + + // Init ID generator values. + m_tileBits = dtIlog2(dtNextPow2((unsigned int)m_params.maxTiles)); + // Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow. + m_saltBits = dtMin((unsigned int)31, 32 - m_tileBits); + if (m_saltBits < 10) + return DT_FAILURE | DT_INVALID_PARAM; + + return DT_SUCCESS; +} + +int dtTileCache::getTilesAt(const int tx, const int ty, dtCompressedTileRef* tiles, const int maxTiles) const +{ + int n = 0; + + // Find tile based on hash. + int h = computeTileHash(tx,ty,m_tileLutMask); + dtCompressedTile* tile = m_posLookup[h]; + while (tile) + { + if (tile->header && + tile->header->tx == tx && + tile->header->ty == ty) + { + if (n < maxTiles) + tiles[n++] = getTileRef(tile); + } + tile = tile->next; + } + + return n; +} + +dtCompressedTile* dtTileCache::getTileAt(const int tx, const int ty, const int tlayer) +{ + // Find tile based on hash. + int h = computeTileHash(tx,ty,m_tileLutMask); + dtCompressedTile* tile = m_posLookup[h]; + while (tile) + { + if (tile->header && + tile->header->tx == tx && + tile->header->ty == ty && + tile->header->tlayer == tlayer) + { + return tile; + } + tile = tile->next; + } + return 0; +} + +dtCompressedTileRef dtTileCache::getTileRef(const dtCompressedTile* tile) const +{ + if (!tile) return 0; + const unsigned int it = (unsigned int)(tile - m_tiles); + return (dtCompressedTileRef)encodeTileId(tile->salt, it); +} + +dtObstacleRef dtTileCache::getObstacleRef(const dtTileCacheObstacle* ob) const +{ + if (!ob) return 0; + const unsigned int idx = (unsigned int)(ob - m_obstacles); + return encodeObstacleId(ob->salt, idx); +} + +const dtTileCacheObstacle* dtTileCache::getObstacleByRef(dtObstacleRef ref) +{ + if (!ref) + return 0; + unsigned int idx = decodeObstacleIdObstacle(ref); + if ((int)idx >= m_params.maxObstacles) + return 0; + const dtTileCacheObstacle* ob = &m_obstacles[idx]; + unsigned int salt = decodeObstacleIdSalt(ref); + if (ob->salt != salt) + return 0; + return ob; +} + +dtStatus dtTileCache::addTile(unsigned char* data, const int dataSize, unsigned char flags, dtCompressedTileRef* result) +{ + // Make sure the data is in right format. + dtTileCacheLayerHeader* header = (dtTileCacheLayerHeader*)data; + if (header->magic != DT_TILECACHE_MAGIC) + return DT_FAILURE | DT_WRONG_MAGIC; + if (header->version != DT_TILECACHE_VERSION) + return DT_FAILURE | DT_WRONG_VERSION; + + // Make sure the location is free. + if (getTileAt(header->tx, header->ty, header->tlayer)) + return DT_FAILURE; + + // Allocate a tile. + dtCompressedTile* tile = 0; + if (m_nextFreeTile) + { + tile = m_nextFreeTile; + m_nextFreeTile = tile->next; + tile->next = 0; + } + + // Make sure we could allocate a tile. + if (!tile) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + // Insert tile into the position lut. + int h = computeTileHash(header->tx, header->ty, m_tileLutMask); + tile->next = m_posLookup[h]; + m_posLookup[h] = tile; + + // Init tile. + const int headerSize = dtAlign4(sizeof(dtTileCacheLayerHeader)); + tile->header = (dtTileCacheLayerHeader*)data; + tile->data = data; + tile->dataSize = dataSize; + tile->compressed = tile->data + headerSize; + tile->compressedSize = tile->dataSize - headerSize; + tile->flags = flags; + + if (result) + *result = getTileRef(tile); + + return DT_SUCCESS; +} + +dtStatus dtTileCache::removeTile(dtCompressedTileRef ref, unsigned char** data, int* dataSize) +{ + if (!ref) + return DT_FAILURE | DT_INVALID_PARAM; + unsigned int tileIndex = decodeTileIdTile(ref); + unsigned int tileSalt = decodeTileIdSalt(ref); + if ((int)tileIndex >= m_params.maxTiles) + return DT_FAILURE | DT_INVALID_PARAM; + dtCompressedTile* tile = &m_tiles[tileIndex]; + if (tile->salt != tileSalt) + return DT_FAILURE | DT_INVALID_PARAM; + + // Remove tile from hash lookup. + const int h = computeTileHash(tile->header->tx,tile->header->ty,m_tileLutMask); + dtCompressedTile* prev = 0; + dtCompressedTile* cur = m_posLookup[h]; + while (cur) + { + if (cur == tile) + { + if (prev) + prev->next = cur->next; + else + m_posLookup[h] = cur->next; + break; + } + prev = cur; + cur = cur->next; + } + + // Reset tile. + if (tile->flags & DT_COMPRESSEDTILE_FREE_DATA) + { + // Owns data + dtFree(tile->data); + tile->data = 0; + tile->dataSize = 0; + if (data) *data = 0; + if (dataSize) *dataSize = 0; + } + else + { + if (data) *data = tile->data; + if (dataSize) *dataSize = tile->dataSize; + } + + tile->header = 0; + tile->data = 0; + tile->dataSize = 0; + tile->compressed = 0; + tile->compressedSize = 0; + tile->flags = 0; + + // Update salt, salt should never be zero. + tile->salt = (tile->salt+1) & ((1<salt == 0) + tile->salt++; + + // Add to free list. + tile->next = m_nextFreeTile; + m_nextFreeTile = tile; + + return DT_SUCCESS; +} + + +dtStatus dtTileCache::addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result) +{ + if (m_nreqs >= MAX_REQUESTS) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + + dtTileCacheObstacle* ob = 0; + if (m_nextFreeObstacle) + { + ob = m_nextFreeObstacle; + m_nextFreeObstacle = ob->next; + ob->next = 0; + } + if (!ob) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + unsigned short salt = ob->salt; + memset(ob, 0, sizeof(dtTileCacheObstacle)); + ob->salt = salt; + ob->state = DT_OBSTACLE_PROCESSING; + ob->type = DT_OBSTACLE_CYLINDER; + dtVcopy(ob->cylinder.pos, pos); + ob->cylinder.radius = radius; + ob->cylinder.height = height; + + ObstacleRequest* req = &m_reqs[m_nreqs++]; + memset(req, 0, sizeof(ObstacleRequest)); + req->action = REQUEST_ADD; + req->ref = getObstacleRef(ob); + + if (result) + *result = req->ref; + + return DT_SUCCESS; +} + +dtStatus dtTileCache::addBoxObstacle(const float* bmin, const float* bmax, dtObstacleRef* result) +{ + if (m_nreqs >= MAX_REQUESTS) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + + dtTileCacheObstacle* ob = 0; + if (m_nextFreeObstacle) + { + ob = m_nextFreeObstacle; + m_nextFreeObstacle = ob->next; + ob->next = 0; + } + if (!ob) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + unsigned short salt = ob->salt; + memset(ob, 0, sizeof(dtTileCacheObstacle)); + ob->salt = salt; + ob->state = DT_OBSTACLE_PROCESSING; + ob->type = DT_OBSTACLE_BOX; + dtVcopy(ob->box.bmin, bmin); + dtVcopy(ob->box.bmax, bmax); + + ObstacleRequest* req = &m_reqs[m_nreqs++]; + memset(req, 0, sizeof(ObstacleRequest)); + req->action = REQUEST_ADD; + req->ref = getObstacleRef(ob); + + if (result) + *result = req->ref; + + return DT_SUCCESS; +} + +dtStatus dtTileCache::removeObstacle(const dtObstacleRef ref) +{ + if (!ref) + return DT_SUCCESS; + if (m_nreqs >= MAX_REQUESTS) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + + ObstacleRequest* req = &m_reqs[m_nreqs++]; + memset(req, 0, sizeof(ObstacleRequest)); + req->action = REQUEST_REMOVE; + req->ref = ref; + + return DT_SUCCESS; +} + +dtStatus dtTileCache::queryTiles(const float* bmin, const float* bmax, + dtCompressedTileRef* results, int* resultCount, const int maxResults) const +{ + const int MAX_TILES = 32; + dtCompressedTileRef tiles[MAX_TILES]; + + int n = 0; + + const float tw = m_params.width * m_params.cs; + const float th = m_params.height * m_params.cs; + const int tx0 = (int)dtMathFloorf((bmin[0]-m_params.orig[0]) / tw); + const int tx1 = (int)dtMathFloorf((bmax[0]-m_params.orig[0]) / tw); + const int ty0 = (int)dtMathFloorf((bmin[2]-m_params.orig[2]) / th); + const int ty1 = (int)dtMathFloorf((bmax[2]-m_params.orig[2]) / th); + + for (int ty = ty0; ty <= ty1; ++ty) + { + for (int tx = tx0; tx <= tx1; ++tx) + { + const int ntiles = getTilesAt(tx,ty,tiles,MAX_TILES); + + for (int i = 0; i < ntiles; ++i) + { + const dtCompressedTile* tile = &m_tiles[decodeTileIdTile(tiles[i])]; + float tbmin[3], tbmax[3]; + calcTightTileBounds(tile->header, tbmin, tbmax); + + if (dtOverlapBounds(bmin,bmax, tbmin,tbmax)) + { + if (n < maxResults) + results[n++] = tiles[i]; + } + } + } + } + + *resultCount = n; + + return DT_SUCCESS; +} + +dtStatus dtTileCache::update(const float /*dt*/, dtNavMesh* navmesh, + bool* upToDate) +{ + if (m_nupdate == 0) + { + // Process requests. + for (int i = 0; i < m_nreqs; ++i) + { + ObstacleRequest* req = &m_reqs[i]; + + unsigned int idx = decodeObstacleIdObstacle(req->ref); + if ((int)idx >= m_params.maxObstacles) + continue; + dtTileCacheObstacle* ob = &m_obstacles[idx]; + unsigned int salt = decodeObstacleIdSalt(req->ref); + if (ob->salt != salt) + continue; + + if (req->action == REQUEST_ADD) + { + // Find touched tiles. + float bmin[3], bmax[3]; + getObstacleBounds(ob, bmin, bmax); + + int ntouched = 0; + queryTiles(bmin, bmax, ob->touched, &ntouched, DT_MAX_TOUCHED_TILES); + ob->ntouched = (unsigned char)ntouched; + // Add tiles to update list. + ob->npending = 0; + for (int j = 0; j < ob->ntouched; ++j) + { + if (m_nupdate < MAX_UPDATE) + { + if (!contains(m_update, m_nupdate, ob->touched[j])) + m_update[m_nupdate++] = ob->touched[j]; + ob->pending[ob->npending++] = ob->touched[j]; + } + } + } + else if (req->action == REQUEST_REMOVE) + { + // Prepare to remove obstacle. + ob->state = DT_OBSTACLE_REMOVING; + // Add tiles to update list. + ob->npending = 0; + for (int j = 0; j < ob->ntouched; ++j) + { + if (m_nupdate < MAX_UPDATE) + { + if (!contains(m_update, m_nupdate, ob->touched[j])) + m_update[m_nupdate++] = ob->touched[j]; + ob->pending[ob->npending++] = ob->touched[j]; + } + } + } + } + + m_nreqs = 0; + } + + dtStatus status = DT_SUCCESS; + // Process updates + if (m_nupdate) + { + // Build mesh + const dtCompressedTileRef ref = m_update[0]; + status = buildNavMeshTile(ref, navmesh); + m_nupdate--; + if (m_nupdate > 0) + memmove(m_update, m_update+1, m_nupdate*sizeof(dtCompressedTileRef)); + + // Update obstacle states. + for (int i = 0; i < m_params.maxObstacles; ++i) + { + dtTileCacheObstacle* ob = &m_obstacles[i]; + if (ob->state == DT_OBSTACLE_PROCESSING || ob->state == DT_OBSTACLE_REMOVING) + { + // Remove handled tile from pending list. + for (int j = 0; j < (int)ob->npending; j++) + { + if (ob->pending[j] == ref) + { + ob->pending[j] = ob->pending[(int)ob->npending-1]; + ob->npending--; + break; + } + } + + // If all pending tiles processed, change state. + if (ob->npending == 0) + { + if (ob->state == DT_OBSTACLE_PROCESSING) + { + ob->state = DT_OBSTACLE_PROCESSED; + } + else if (ob->state == DT_OBSTACLE_REMOVING) + { + ob->state = DT_OBSTACLE_EMPTY; + // Update salt, salt should never be zero. + ob->salt = (ob->salt+1) & ((1<<16)-1); + if (ob->salt == 0) + ob->salt++; + // Return obstacle to free list. + ob->next = m_nextFreeObstacle; + m_nextFreeObstacle = ob; + } + } + } + } + } + + if (upToDate) + *upToDate = m_nupdate == 0 && m_nreqs == 0; + + return status; +} + + +dtStatus dtTileCache::buildNavMeshTilesAt(const int tx, const int ty, dtNavMesh* navmesh) +{ + const int MAX_TILES = 32; + dtCompressedTileRef tiles[MAX_TILES]; + const int ntiles = getTilesAt(tx,ty,tiles,MAX_TILES); + + for (int i = 0; i < ntiles; ++i) + { + dtStatus status = buildNavMeshTile(tiles[i], navmesh); + if (dtStatusFailed(status)) + return status; + } + + return DT_SUCCESS; +} + +dtStatus dtTileCache::buildNavMeshTile(const dtCompressedTileRef ref, dtNavMesh* navmesh) +{ + dtAssert(m_talloc); + dtAssert(m_tcomp); + + unsigned int idx = decodeTileIdTile(ref); + if (idx > (unsigned int)m_params.maxTiles) + return DT_FAILURE | DT_INVALID_PARAM; + const dtCompressedTile* tile = &m_tiles[idx]; + unsigned int salt = decodeTileIdSalt(ref); + if (tile->salt != salt) + return DT_FAILURE | DT_INVALID_PARAM; + + m_talloc->reset(); + + NavMeshTileBuildContext bc(m_talloc); + const int walkableClimbVx = (int)(m_params.walkableClimb / m_params.ch); + dtStatus status; + + // Decompress tile layer data. + status = dtDecompressTileCacheLayer(m_talloc, m_tcomp, tile->data, tile->dataSize, &bc.layer); + if (dtStatusFailed(status)) + return status; + + // Rasterize obstacles. + for (int i = 0; i < m_params.maxObstacles; ++i) + { + const dtTileCacheObstacle* ob = &m_obstacles[i]; + if (ob->state == DT_OBSTACLE_EMPTY || ob->state == DT_OBSTACLE_REMOVING) + continue; + if (contains(ob->touched, ob->ntouched, ref)) + { + if (ob->type == DT_OBSTACLE_CYLINDER) + { + dtMarkCylinderArea(*bc.layer, tile->header->bmin, m_params.cs, m_params.ch, + ob->cylinder.pos, ob->cylinder.radius, ob->cylinder.height, 0); + } + else if (ob->type == DT_OBSTACLE_BOX) + { + dtMarkBoxArea(*bc.layer, tile->header->bmin, m_params.cs, m_params.ch, + ob->box.bmin, ob->box.bmax, 0); + } + } + } + + // Build navmesh + status = dtBuildTileCacheRegions(m_talloc, *bc.layer, walkableClimbVx); + if (dtStatusFailed(status)) + return status; + + bc.lcset = dtAllocTileCacheContourSet(m_talloc); + if (!bc.lcset) + return status; + status = dtBuildTileCacheContours(m_talloc, *bc.layer, walkableClimbVx, + m_params.maxSimplificationError, *bc.lcset); + if (dtStatusFailed(status)) + return status; + + bc.lmesh = dtAllocTileCachePolyMesh(m_talloc); + if (!bc.lmesh) + return status; + status = dtBuildTileCachePolyMesh(m_talloc, *bc.lcset, *bc.lmesh); + if (dtStatusFailed(status)) + return status; + + // Early out if the mesh tile is empty. + if (!bc.lmesh->npolys) + { + // Remove existing tile. + navmesh->removeTile(navmesh->getTileRefAt(tile->header->tx,tile->header->ty,tile->header->tlayer),0,0); + return DT_SUCCESS; + } + + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + params.verts = bc.lmesh->verts; + params.vertCount = bc.lmesh->nverts; + params.polys = bc.lmesh->polys; + params.polyAreas = bc.lmesh->areas; + params.polyFlags = bc.lmesh->flags; + params.polyCount = bc.lmesh->npolys; + params.nvp = DT_VERTS_PER_POLYGON; + params.walkableHeight = m_params.walkableHeight; + params.walkableRadius = m_params.walkableRadius; + params.walkableClimb = m_params.walkableClimb; + params.tileX = tile->header->tx; + params.tileY = tile->header->ty; + params.tileLayer = tile->header->tlayer; + params.cs = m_params.cs; + params.ch = m_params.ch; + params.buildBvTree = false; + dtVcopy(params.bmin, tile->header->bmin); + dtVcopy(params.bmax, tile->header->bmax); + + if (m_tmproc) + { + m_tmproc->process(¶ms, bc.lmesh->areas, bc.lmesh->flags); + } + + unsigned char* navData = 0; + int navDataSize = 0; + if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) + return DT_FAILURE; + + // Remove existing tile. + navmesh->removeTile(navmesh->getTileRefAt(tile->header->tx,tile->header->ty,tile->header->tlayer),0,0); + + // Add new tile, or leave the location empty. + if (navData) + { + // Let the navmesh own the data. + status = navmesh->addTile(navData,navDataSize,DT_TILE_FREE_DATA,0,0); + if (dtStatusFailed(status)) + { + dtFree(navData); + return status; + } + } + + return DT_SUCCESS; +} + +void dtTileCache::calcTightTileBounds(const dtTileCacheLayerHeader* header, float* bmin, float* bmax) const +{ + const float cs = m_params.cs; + bmin[0] = header->bmin[0] + header->minx*cs; + bmin[1] = header->bmin[1]; + bmin[2] = header->bmin[2] + header->miny*cs; + bmax[0] = header->bmin[0] + (header->maxx+1)*cs; + bmax[1] = header->bmax[1]; + bmax[2] = header->bmin[2] + (header->maxy+1)*cs; +} + +void dtTileCache::getObstacleBounds(const struct dtTileCacheObstacle* ob, float* bmin, float* bmax) const +{ + if (ob->type == DT_OBSTACLE_CYLINDER) + { + const dtObstacleCylinder &cl = ob->cylinder; + + bmin[0] = cl.pos[0] - cl.radius; + bmin[1] = cl.pos[1]; + bmin[2] = cl.pos[2] - cl.radius; + bmax[0] = cl.pos[0] + cl.radius; + bmax[1] = cl.pos[1] + cl.height; + bmax[2] = cl.pos[2] + cl.radius; + } + else if (ob->type == DT_OBSTACLE_BOX) + { + dtVcopy(bmin, ob->box.bmin); + dtVcopy(bmax, ob->box.bmax); + } +} diff --git a/libs/recast/detour_tile_cache/src/DetourTileCacheBuilder.cpp b/libs/recast/detour_tile_cache/src/DetourTileCacheBuilder.cpp new file mode 100644 index 000000000..a81a7b439 --- /dev/null +++ b/libs/recast/detour_tile_cache/src/DetourTileCacheBuilder.cpp @@ -0,0 +1,2196 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include "DetourCommon.h" +#include "DetourMath.h" +#include "DetourStatus.h" +#include "DetourAssert.h" +#include "DetourTileCacheBuilder.h" +#include + + +template class dtFixedArray +{ + dtTileCacheAlloc* m_alloc; + T* m_ptr; + const int m_size; + inline void operator=(dtFixedArray& p); +public: + inline dtFixedArray(dtTileCacheAlloc* a, const int s) : m_alloc(a), m_ptr((T*)a->alloc(sizeof(T)*s)), m_size(s) {} + inline ~dtFixedArray() { if (m_alloc) m_alloc->free(m_ptr); } + inline operator T*() { return m_ptr; } + inline int size() const { return m_size; } +}; + +inline int getDirOffsetX(int dir) +{ + const int offset[4] = { -1, 0, 1, 0, }; + return offset[dir&0x03]; +} + +inline int getDirOffsetY(int dir) +{ + const int offset[4] = { 0, 1, 0, -1 }; + return offset[dir&0x03]; +} + +static const int MAX_VERTS_PER_POLY = 6; // TODO: use the DT_VERTS_PER_POLYGON +static const int MAX_REM_EDGES = 48; // TODO: make this an expression. + + + +dtTileCacheContourSet* dtAllocTileCacheContourSet(dtTileCacheAlloc* alloc) +{ + dtAssert(alloc); + + dtTileCacheContourSet* cset = (dtTileCacheContourSet*)alloc->alloc(sizeof(dtTileCacheContourSet)); + memset(cset, 0, sizeof(dtTileCacheContourSet)); + return cset; +} + +void dtFreeTileCacheContourSet(dtTileCacheAlloc* alloc, dtTileCacheContourSet* cset) +{ + dtAssert(alloc); + + if (!cset) return; + for (int i = 0; i < cset->nconts; ++i) + alloc->free(cset->conts[i].verts); + alloc->free(cset->conts); + alloc->free(cset); +} + +dtTileCachePolyMesh* dtAllocTileCachePolyMesh(dtTileCacheAlloc* alloc) +{ + dtAssert(alloc); + + dtTileCachePolyMesh* lmesh = (dtTileCachePolyMesh*)alloc->alloc(sizeof(dtTileCachePolyMesh)); + memset(lmesh, 0, sizeof(dtTileCachePolyMesh)); + return lmesh; +} + +void dtFreeTileCachePolyMesh(dtTileCacheAlloc* alloc, dtTileCachePolyMesh* lmesh) +{ + dtAssert(alloc); + + if (!lmesh) return; + alloc->free(lmesh->verts); + alloc->free(lmesh->polys); + alloc->free(lmesh->flags); + alloc->free(lmesh->areas); + alloc->free(lmesh); +} + + + +struct dtLayerSweepSpan +{ + unsigned short ns; // number samples + unsigned char id; // region id + unsigned char nei; // neighbour id +}; + +static const int DT_LAYER_MAX_NEIS = 16; + +struct dtLayerMonotoneRegion +{ + int area; + unsigned char neis[DT_LAYER_MAX_NEIS]; + unsigned char nneis; + unsigned char regId; + unsigned char areaId; +}; + +struct dtTempContour +{ + inline dtTempContour(unsigned char* vbuf, const int nvbuf, + unsigned short* pbuf, const int npbuf) : + verts(vbuf), nverts(0), cverts(nvbuf), + poly(pbuf), npoly(0), cpoly(npbuf) + { + } + unsigned char* verts; + int nverts; + int cverts; + unsigned short* poly; + int npoly; + int cpoly; +}; + + + + +inline bool overlapRangeExl(const unsigned short amin, const unsigned short amax, + const unsigned short bmin, const unsigned short bmax) +{ + return (amin >= bmax || amax <= bmin) ? false : true; +} + +static void addUniqueLast(unsigned char* a, unsigned char& an, unsigned char v) +{ + const int n = (int)an; + if (n > 0 && a[n-1] == v) return; + a[an] = v; + an++; +} + +inline bool isConnected(const dtTileCacheLayer& layer, + const int ia, const int ib, const int walkableClimb) +{ + if (layer.areas[ia] != layer.areas[ib]) return false; + if (dtAbs((int)layer.heights[ia] - (int)layer.heights[ib]) > walkableClimb) return false; + return true; +} + +static bool canMerge(unsigned char oldRegId, unsigned char newRegId, const dtLayerMonotoneRegion* regs, const int nregs) +{ + int count = 0; + for (int i = 0; i < nregs; ++i) + { + const dtLayerMonotoneRegion& reg = regs[i]; + if (reg.regId != oldRegId) continue; + const int nnei = (int)reg.nneis; + for (int j = 0; j < nnei; ++j) + { + if (regs[reg.neis[j]].regId == newRegId) + count++; + } + } + return count == 1; +} + + +dtStatus dtBuildTileCacheRegions(dtTileCacheAlloc* alloc, + dtTileCacheLayer& layer, + const int walkableClimb) +{ + dtAssert(alloc); + + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + + memset(layer.regs,0xff,sizeof(unsigned char)*w*h); + + const int nsweeps = w; + dtFixedArray sweeps(alloc, nsweeps); + if (!sweeps) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(sweeps,0,sizeof(dtLayerSweepSpan)*nsweeps); + + // Partition walkable area into monotone regions. + unsigned char prevCount[256]; + unsigned char regId = 0; + + for (int y = 0; y < h; ++y) + { + if (regId > 0) + memset(prevCount,0,sizeof(unsigned char)*regId); + unsigned char sweepId = 0; + + for (int x = 0; x < w; ++x) + { + const int idx = x + y*w; + if (layer.areas[idx] == DT_TILECACHE_NULL_AREA) continue; + + unsigned char sid = 0xff; + + // -x + const int xidx = (x-1)+y*w; + if (x > 0 && isConnected(layer, idx, xidx, walkableClimb)) + { + if (layer.regs[xidx] != 0xff) + sid = layer.regs[xidx]; + } + + if (sid == 0xff) + { + sid = sweepId++; + sweeps[sid].nei = 0xff; + sweeps[sid].ns = 0; + } + + // -y + const int yidx = x+(y-1)*w; + if (y > 0 && isConnected(layer, idx, yidx, walkableClimb)) + { + const unsigned char nr = layer.regs[yidx]; + if (nr != 0xff) + { + // Set neighbour when first valid neighbour is encoutered. + if (sweeps[sid].ns == 0) + sweeps[sid].nei = nr; + + if (sweeps[sid].nei == nr) + { + // Update existing neighbour + sweeps[sid].ns++; + prevCount[nr]++; + } + else + { + // This is hit if there is nore than one neighbour. + // Invalidate the neighbour. + sweeps[sid].nei = 0xff; + } + } + } + + layer.regs[idx] = sid; + } + + // Create unique ID. + for (int i = 0; i < sweepId; ++i) + { + // If the neighbour is set and there is only one continuous connection to it, + // the sweep will be merged with the previous one, else new region is created. + if (sweeps[i].nei != 0xff && (unsigned short)prevCount[sweeps[i].nei] == sweeps[i].ns) + { + sweeps[i].id = sweeps[i].nei; + } + else + { + if (regId == 255) + { + // Region ID's overflow. + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + } + sweeps[i].id = regId++; + } + } + + // Remap local sweep ids to region ids. + for (int x = 0; x < w; ++x) + { + const int idx = x+y*w; + if (layer.regs[idx] != 0xff) + layer.regs[idx] = sweeps[layer.regs[idx]].id; + } + } + + // Allocate and init layer regions. + const int nregs = (int)regId; + dtFixedArray regs(alloc, nregs); + if (!regs) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + memset(regs, 0, sizeof(dtLayerMonotoneRegion)*nregs); + for (int i = 0; i < nregs; ++i) + regs[i].regId = 0xff; + + // Find region neighbours. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int idx = x+y*w; + const unsigned char ri = layer.regs[idx]; + if (ri == 0xff) + continue; + + // Update area. + regs[ri].area++; + regs[ri].areaId = layer.areas[idx]; + + // Update neighbours + const int ymi = x+(y-1)*w; + if (y > 0 && isConnected(layer, idx, ymi, walkableClimb)) + { + const unsigned char rai = layer.regs[ymi]; + if (rai != 0xff && rai != ri) + { + addUniqueLast(regs[ri].neis, regs[ri].nneis, rai); + addUniqueLast(regs[rai].neis, regs[rai].nneis, ri); + } + } + } + } + + for (int i = 0; i < nregs; ++i) + regs[i].regId = (unsigned char)i; + + for (int i = 0; i < nregs; ++i) + { + dtLayerMonotoneRegion& reg = regs[i]; + + int merge = -1; + int mergea = 0; + for (int j = 0; j < (int)reg.nneis; ++j) + { + const unsigned char nei = reg.neis[j]; + dtLayerMonotoneRegion& regn = regs[nei]; + if (reg.regId == regn.regId) + continue; + if (reg.areaId != regn.areaId) + continue; + if (regn.area > mergea) + { + if (canMerge(reg.regId, regn.regId, regs, nregs)) + { + mergea = regn.area; + merge = (int)nei; + } + } + } + if (merge != -1) + { + const unsigned char oldId = reg.regId; + const unsigned char newId = regs[merge].regId; + for (int j = 0; j < nregs; ++j) + if (regs[j].regId == oldId) + regs[j].regId = newId; + } + } + + // Compact ids. + unsigned char remap[256]; + memset(remap, 0, 256); + // Find number of unique regions. + regId = 0; + for (int i = 0; i < nregs; ++i) + remap[regs[i].regId] = 1; + for (int i = 0; i < 256; ++i) + if (remap[i]) + remap[i] = regId++; + // Remap ids. + for (int i = 0; i < nregs; ++i) + regs[i].regId = remap[regs[i].regId]; + + layer.regCount = regId; + + for (int i = 0; i < w*h; ++i) + { + if (layer.regs[i] != 0xff) + layer.regs[i] = regs[layer.regs[i]].regId; + } + + return DT_SUCCESS; +} + + + +static bool appendVertex(dtTempContour& cont, const int x, const int y, const int z, const int r) +{ + // Try to merge with existing segments. + if (cont.nverts > 1) + { + unsigned char* pa = &cont.verts[(cont.nverts-2)*4]; + unsigned char* pb = &cont.verts[(cont.nverts-1)*4]; + if ((int)pb[3] == r) + { + if (pa[0] == pb[0] && (int)pb[0] == x) + { + // The verts are aligned aling x-axis, update z. + pb[1] = (unsigned char)y; + pb[2] = (unsigned char)z; + return true; + } + else if (pa[2] == pb[2] && (int)pb[2] == z) + { + // The verts are aligned aling z-axis, update x. + pb[0] = (unsigned char)x; + pb[1] = (unsigned char)y; + return true; + } + } + } + + // Add new point. + if (cont.nverts+1 > cont.cverts) + return false; + + unsigned char* v = &cont.verts[cont.nverts*4]; + v[0] = (unsigned char)x; + v[1] = (unsigned char)y; + v[2] = (unsigned char)z; + v[3] = (unsigned char)r; + cont.nverts++; + + return true; +} + + +static unsigned char getNeighbourReg(dtTileCacheLayer& layer, + const int ax, const int ay, const int dir) +{ + const int w = (int)layer.header->width; + const int ia = ax + ay*w; + + const unsigned char con = layer.cons[ia] & 0xf; + const unsigned char portal = layer.cons[ia] >> 4; + const unsigned char mask = (unsigned char)(1<width; + const int h = (int)layer.header->height; + + cont.nverts = 0; + + int startX = x; + int startY = y; + int startDir = -1; + + for (int i = 0; i < 4; ++i) + { + const int dir = (i+3)&3; + unsigned char rn = getNeighbourReg(layer, x, y, dir); + if (rn != layer.regs[x+y*w]) + { + startDir = dir; + break; + } + } + if (startDir == -1) + return true; + + int dir = startDir; + const int maxIter = w*h; + + int iter = 0; + while (iter < maxIter) + { + unsigned char rn = getNeighbourReg(layer, x, y, dir); + + int nx = x; + int ny = y; + int ndir = dir; + + if (rn != layer.regs[x+y*w]) + { + // Solid edge. + int px = x; + int pz = y; + switch(dir) + { + case 0: pz++; break; + case 1: px++; pz++; break; + case 2: px++; break; + } + + // Try to merge with previous vertex. + if (!appendVertex(cont, px, (int)layer.heights[x+y*w], pz,rn)) + return false; + + ndir = (dir+1) & 0x3; // Rotate CW + } + else + { + // Move to next. + nx = x + getDirOffsetX(dir); + ny = y + getDirOffsetY(dir); + ndir = (dir+3) & 0x3; // Rotate CCW + } + + if (iter > 0 && x == startX && y == startY && dir == startDir) + break; + + x = nx; + y = ny; + dir = ndir; + + iter++; + } + + // Remove last vertex if it is duplicate of the first one. + unsigned char* pa = &cont.verts[(cont.nverts-1)*4]; + unsigned char* pb = &cont.verts[0]; + if (pa[0] == pb[0] && pa[2] == pb[2]) + cont.nverts--; + + return true; +} + + +static float distancePtSeg(const int x, const int z, + const int px, const int pz, + const int qx, const int qz) +{ + float pqx = (float)(qx - px); + float pqz = (float)(qz - pz); + float dx = (float)(x - px); + float dz = (float)(z - pz); + float d = pqx*pqx + pqz*pqz; + float t = pqx*dx + pqz*dz; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + + dx = px + t*pqx - x; + dz = pz + t*pqz - z; + + return dx*dx + dz*dz; +} + +static void simplifyContour(dtTempContour& cont, const float maxError) +{ + cont.npoly = 0; + + for (int i = 0; i < cont.nverts; ++i) + { + int j = (i+1) % cont.nverts; + // Check for start of a wall segment. + unsigned char ra = cont.verts[j*4+3]; + unsigned char rb = cont.verts[i*4+3]; + if (ra != rb) + cont.poly[cont.npoly++] = (unsigned short)i; + } + if (cont.npoly < 2) + { + // If there is no transitions at all, + // create some initial points for the simplification process. + // Find lower-left and upper-right vertices of the contour. + int llx = cont.verts[0]; + int llz = cont.verts[2]; + int lli = 0; + int urx = cont.verts[0]; + int urz = cont.verts[2]; + int uri = 0; + for (int i = 1; i < cont.nverts; ++i) + { + int x = cont.verts[i*4+0]; + int z = cont.verts[i*4+2]; + if (x < llx || (x == llx && z < llz)) + { + llx = x; + llz = z; + lli = i; + } + if (x > urx || (x == urx && z > urz)) + { + urx = x; + urz = z; + uri = i; + } + } + cont.npoly = 0; + cont.poly[cont.npoly++] = (unsigned short)lli; + cont.poly[cont.npoly++] = (unsigned short)uri; + } + + // Add points until all raw points are within + // error tolerance to the simplified shape. + for (int i = 0; i < cont.npoly; ) + { + int ii = (i+1) % cont.npoly; + + const int ai = (int)cont.poly[i]; + const int ax = (int)cont.verts[ai*4+0]; + const int az = (int)cont.verts[ai*4+2]; + + const int bi = (int)cont.poly[ii]; + const int bx = (int)cont.verts[bi*4+0]; + const int bz = (int)cont.verts[bi*4+2]; + + // Find maximum deviation from the segment. + float maxd = 0; + int maxi = -1; + int ci, cinc, endi; + + // Traverse the segment in lexilogical order so that the + // max deviation is calculated similarly when traversing + // opposite segments. + if (bx > ax || (bx == ax && bz > az)) + { + cinc = 1; + ci = (ai+cinc) % cont.nverts; + endi = bi; + } + else + { + cinc = cont.nverts-1; + ci = (bi+cinc) % cont.nverts; + endi = ai; + } + + // Tessellate only outer edges or edges between areas. + while (ci != endi) + { + float d = distancePtSeg(cont.verts[ci*4+0], cont.verts[ci*4+2], ax, az, bx, bz); + if (d > maxd) + { + maxd = d; + maxi = ci; + } + ci = (ci+cinc) % cont.nverts; + } + + + // If the max deviation is larger than accepted error, + // add new point, else continue to next segment. + if (maxi != -1 && maxd > (maxError*maxError)) + { + cont.npoly++; + for (int j = cont.npoly-1; j > i; --j) + cont.poly[j] = cont.poly[j-1]; + cont.poly[i+1] = (unsigned short)maxi; + } + else + { + ++i; + } + } + + // Remap vertices + int start = 0; + for (int i = 1; i < cont.npoly; ++i) + if (cont.poly[i] < cont.poly[start]) + start = i; + + cont.nverts = 0; + for (int i = 0; i < cont.npoly; ++i) + { + const int j = (start+i) % cont.npoly; + unsigned char* src = &cont.verts[cont.poly[j]*4]; + unsigned char* dst = &cont.verts[cont.nverts*4]; + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + cont.nverts++; + } +} + +static unsigned char getCornerHeight(dtTileCacheLayer& layer, + const int x, const int y, const int z, + const int walkableClimb, + bool& shouldRemove) +{ + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + + int n = 0; + + unsigned char portal = 0xf; + unsigned char height = 0; + unsigned char preg = 0xff; + bool allSameReg = true; + + for (int dz = -1; dz <= 0; ++dz) + { + for (int dx = -1; dx <= 0; ++dx) + { + const int px = x+dx; + const int pz = z+dz; + if (px >= 0 && pz >= 0 && px < w && pz < h) + { + const int idx = px + pz*w; + const int lh = (int)layer.heights[idx]; + if (dtAbs(lh-y) <= walkableClimb && layer.areas[idx] != DT_TILECACHE_NULL_AREA) + { + height = dtMax(height, (unsigned char)lh); + portal &= (layer.cons[idx] >> 4); + if (preg != 0xff && preg != layer.regs[idx]) + allSameReg = false; + preg = layer.regs[idx]; + n++; + } + } + } + } + + int portalCount = 0; + for (int dir = 0; dir < 4; ++dir) + if (portal & (1< 1 && portalCount == 1 && allSameReg) + { + shouldRemove = true; + } + + return height; +} + + +// TODO: move this somewhere else, once the layer meshing is done. +dtStatus dtBuildTileCacheContours(dtTileCacheAlloc* alloc, + dtTileCacheLayer& layer, + const int walkableClimb, const float maxError, + dtTileCacheContourSet& lcset) +{ + dtAssert(alloc); + + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + + lcset.nconts = layer.regCount; + lcset.conts = (dtTileCacheContour*)alloc->alloc(sizeof(dtTileCacheContour)*lcset.nconts); + if (!lcset.conts) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(lcset.conts, 0, sizeof(dtTileCacheContour)*lcset.nconts); + + // Allocate temp buffer for contour tracing. + const int maxTempVerts = (w+h)*2 * 2; // Twice around the layer. + + dtFixedArray tempVerts(alloc, maxTempVerts*4); + if (!tempVerts) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + dtFixedArray tempPoly(alloc, maxTempVerts); + if (!tempPoly) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + dtTempContour temp(tempVerts, maxTempVerts, tempPoly, maxTempVerts); + + // Find contours. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const int idx = x+y*w; + const unsigned char ri = layer.regs[idx]; + if (ri == 0xff) + continue; + + dtTileCacheContour& cont = lcset.conts[ri]; + + if (cont.nverts > 0) + continue; + + cont.reg = ri; + cont.area = layer.areas[idx]; + + if (!walkContour(layer, x, y, temp)) + { + // Too complex contour. + // Note: If you hit here ofte, try increasing 'maxTempVerts'. + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + } + + simplifyContour(temp, maxError); + + // Store contour. + cont.nverts = temp.nverts; + if (cont.nverts > 0) + { + cont.verts = (unsigned char*)alloc->alloc(sizeof(unsigned char)*4*temp.nverts); + if (!cont.verts) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + for (int i = 0, j = temp.nverts-1; i < temp.nverts; j=i++) + { + unsigned char* dst = &cont.verts[j*4]; + unsigned char* v = &temp.verts[j*4]; + unsigned char* vn = &temp.verts[i*4]; + unsigned char nei = vn[3]; // The neighbour reg is stored at segment vertex of a segment. + bool shouldRemove = false; + unsigned char lh = getCornerHeight(layer, (int)v[0], (int)v[1], (int)v[2], + walkableClimb, shouldRemove); + + dst[0] = v[0]; + dst[1] = lh; + dst[2] = v[2]; + + // Store portal direction and remove status to the fourth component. + dst[3] = 0x0f; + if (nei != 0xff && nei >= 0xf8) + dst[3] = nei - 0xf8; + if (shouldRemove) + dst[3] |= 0x80; + } + } + } + } + + return DT_SUCCESS; +} + + + +static const int VERTEX_BUCKET_COUNT2 = (1<<8); + +inline int computeVertexHash2(int x, int y, int z) +{ + const unsigned int h1 = 0x8da6b343; // Large multiplicative constants; + const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes + const unsigned int h3 = 0xcb1ab31f; + unsigned int n = h1 * x + h2 * y + h3 * z; + return (int)(n & (VERTEX_BUCKET_COUNT2-1)); +} + +static unsigned short addVertex(unsigned short x, unsigned short y, unsigned short z, + unsigned short* verts, unsigned short* firstVert, unsigned short* nextVert, int& nv) +{ + int bucket = computeVertexHash2(x, 0, z); + unsigned short i = firstVert[bucket]; + + while (i != DT_TILECACHE_NULL_IDX) + { + const unsigned short* v = &verts[i*3]; + if (v[0] == x && v[2] == z && (dtAbs(v[1] - y) <= 2)) + return i; + i = nextVert[i]; // next + } + + // Could not find, create new. + i = (unsigned short)nv; nv++; + unsigned short* v = &verts[i*3]; + v[0] = x; + v[1] = y; + v[2] = z; + nextVert[i] = firstVert[bucket]; + firstVert[bucket] = i; + + return (unsigned short)i; +} + + +struct rcEdge +{ + unsigned short vert[2]; + unsigned short polyEdge[2]; + unsigned short poly[2]; +}; + +static bool buildMeshAdjacency(dtTileCacheAlloc* alloc, + unsigned short* polys, const int npolys, + const unsigned short* verts, const int nverts, + const dtTileCacheContourSet& lcset) +{ + // Based on code by Eric Lengyel from: + // http://www.terathon.com/code/edges.php + + const int maxEdgeCount = npolys*MAX_VERTS_PER_POLY; + dtFixedArray firstEdge(alloc, nverts + maxEdgeCount); + if (!firstEdge) + return false; + unsigned short* nextEdge = firstEdge + nverts; + int edgeCount = 0; + + dtFixedArray edges(alloc, maxEdgeCount); + if (!edges) + return false; + + for (int i = 0; i < nverts; i++) + firstEdge[i] = DT_TILECACHE_NULL_IDX; + + for (int i = 0; i < npolys; ++i) + { + unsigned short* t = &polys[i*MAX_VERTS_PER_POLY*2]; + for (int j = 0; j < MAX_VERTS_PER_POLY; ++j) + { + if (t[j] == DT_TILECACHE_NULL_IDX) break; + unsigned short v0 = t[j]; + unsigned short v1 = (j+1 >= MAX_VERTS_PER_POLY || t[j+1] == DT_TILECACHE_NULL_IDX) ? t[0] : t[j+1]; + if (v0 < v1) + { + rcEdge& edge = edges[edgeCount]; + edge.vert[0] = v0; + edge.vert[1] = v1; + edge.poly[0] = (unsigned short)i; + edge.polyEdge[0] = (unsigned short)j; + edge.poly[1] = (unsigned short)i; + edge.polyEdge[1] = 0xff; + // Insert edge + nextEdge[edgeCount] = firstEdge[v0]; + firstEdge[v0] = (unsigned short)edgeCount; + edgeCount++; + } + } + } + + for (int i = 0; i < npolys; ++i) + { + unsigned short* t = &polys[i*MAX_VERTS_PER_POLY*2]; + for (int j = 0; j < MAX_VERTS_PER_POLY; ++j) + { + if (t[j] == DT_TILECACHE_NULL_IDX) break; + unsigned short v0 = t[j]; + unsigned short v1 = (j+1 >= MAX_VERTS_PER_POLY || t[j+1] == DT_TILECACHE_NULL_IDX) ? t[0] : t[j+1]; + if (v0 > v1) + { + bool found = false; + for (unsigned short e = firstEdge[v1]; e != DT_TILECACHE_NULL_IDX; e = nextEdge[e]) + { + rcEdge& edge = edges[e]; + if (edge.vert[1] == v0 && edge.poly[0] == edge.poly[1]) + { + edge.poly[1] = (unsigned short)i; + edge.polyEdge[1] = (unsigned short)j; + found = true; + break; + } + } + if (!found) + { + // Matching edge not found, it is an open edge, add it. + rcEdge& edge = edges[edgeCount]; + edge.vert[0] = v1; + edge.vert[1] = v0; + edge.poly[0] = (unsigned short)i; + edge.polyEdge[0] = (unsigned short)j; + edge.poly[1] = (unsigned short)i; + edge.polyEdge[1] = 0xff; + // Insert edge + nextEdge[edgeCount] = firstEdge[v1]; + firstEdge[v1] = (unsigned short)edgeCount; + edgeCount++; + } + } + } + } + + // Mark portal edges. + for (int i = 0; i < lcset.nconts; ++i) + { + dtTileCacheContour& cont = lcset.conts[i]; + if (cont.nverts < 3) + continue; + + for (int j = 0, k = cont.nverts-1; j < cont.nverts; k=j++) + { + const unsigned char* va = &cont.verts[k*4]; + const unsigned char* vb = &cont.verts[j*4]; + const unsigned char dir = va[3] & 0xf; + if (dir == 0xf) + continue; + + if (dir == 0 || dir == 2) + { + // Find matching vertical edge + const unsigned short x = (unsigned short)va[0]; + unsigned short zmin = (unsigned short)va[2]; + unsigned short zmax = (unsigned short)vb[2]; + if (zmin > zmax) + dtSwap(zmin, zmax); + + for (int m = 0; m < edgeCount; ++m) + { + rcEdge& e = edges[m]; + // Skip connected edges. + if (e.poly[0] != e.poly[1]) + continue; + const unsigned short* eva = &verts[e.vert[0]*3]; + const unsigned short* evb = &verts[e.vert[1]*3]; + if (eva[0] == x && evb[0] == x) + { + unsigned short ezmin = eva[2]; + unsigned short ezmax = evb[2]; + if (ezmin > ezmax) + dtSwap(ezmin, ezmax); + if (overlapRangeExl(zmin,zmax, ezmin, ezmax)) + { + // Reuse the other polyedge to store dir. + e.polyEdge[1] = dir; + } + } + } + } + else + { + // Find matching vertical edge + const unsigned short z = (unsigned short)va[2]; + unsigned short xmin = (unsigned short)va[0]; + unsigned short xmax = (unsigned short)vb[0]; + if (xmin > xmax) + dtSwap(xmin, xmax); + for (int m = 0; m < edgeCount; ++m) + { + rcEdge& e = edges[m]; + // Skip connected edges. + if (e.poly[0] != e.poly[1]) + continue; + const unsigned short* eva = &verts[e.vert[0]*3]; + const unsigned short* evb = &verts[e.vert[1]*3]; + if (eva[2] == z && evb[2] == z) + { + unsigned short exmin = eva[0]; + unsigned short exmax = evb[0]; + if (exmin > exmax) + dtSwap(exmin, exmax); + if (overlapRangeExl(xmin,xmax, exmin, exmax)) + { + // Reuse the other polyedge to store dir. + e.polyEdge[1] = dir; + } + } + } + } + } + } + + + // Store adjacency + for (int i = 0; i < edgeCount; ++i) + { + const rcEdge& e = edges[i]; + if (e.poly[0] != e.poly[1]) + { + unsigned short* p0 = &polys[e.poly[0]*MAX_VERTS_PER_POLY*2]; + unsigned short* p1 = &polys[e.poly[1]*MAX_VERTS_PER_POLY*2]; + p0[MAX_VERTS_PER_POLY + e.polyEdge[0]] = e.poly[1]; + p1[MAX_VERTS_PER_POLY + e.polyEdge[1]] = e.poly[0]; + } + else if (e.polyEdge[1] != 0xff) + { + unsigned short* p0 = &polys[e.poly[0]*MAX_VERTS_PER_POLY*2]; + p0[MAX_VERTS_PER_POLY + e.polyEdge[0]] = 0x8000 | (unsigned short)e.polyEdge[1]; + } + + } + + return true; +} + + +// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv). +inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; } +inline int next(int i, int n) { return i+1 < n ? i+1 : 0; } + +inline int area2(const unsigned char* a, const unsigned char* b, const unsigned char* c) +{ + return ((int)b[0] - (int)a[0]) * ((int)c[2] - (int)a[2]) - ((int)c[0] - (int)a[0]) * ((int)b[2] - (int)a[2]); +} + +// Exclusive or: true iff exactly one argument is true. +// The arguments are negated to ensure that they are 0/1 +// values. Then the bitwise Xor operator may apply. +// (This idea is due to Michael Baldwin.) +inline bool xorb(bool x, bool y) +{ + return !x ^ !y; +} + +// Returns true iff c is strictly to the left of the directed +// line through a to b. +inline bool left(const unsigned char* a, const unsigned char* b, const unsigned char* c) +{ + return area2(a, b, c) < 0; +} + +inline bool leftOn(const unsigned char* a, const unsigned char* b, const unsigned char* c) +{ + return area2(a, b, c) <= 0; +} + +inline bool collinear(const unsigned char* a, const unsigned char* b, const unsigned char* c) +{ + return area2(a, b, c) == 0; +} + +// Returns true iff ab properly intersects cd: they share +// a point interior to both segments. The properness of the +// intersection is ensured by using strict leftness. +static bool intersectProp(const unsigned char* a, const unsigned char* b, + const unsigned char* c, const unsigned char* d) +{ + // Eliminate improper cases. + if (collinear(a,b,c) || collinear(a,b,d) || + collinear(c,d,a) || collinear(c,d,b)) + return false; + + return xorb(left(a,b,c), left(a,b,d)) && xorb(left(c,d,a), left(c,d,b)); +} + +// Returns T iff (a,b,c) are collinear and point c lies +// on the closed segement ab. +static bool between(const unsigned char* a, const unsigned char* b, const unsigned char* c) +{ + if (!collinear(a, b, c)) + return false; + // If ab not vertical, check betweenness on x; else on y. + if (a[0] != b[0]) + return ((a[0] <= c[0]) && (c[0] <= b[0])) || ((a[0] >= c[0]) && (c[0] >= b[0])); + else + return ((a[2] <= c[2]) && (c[2] <= b[2])) || ((a[2] >= c[2]) && (c[2] >= b[2])); +} + +// Returns true iff segments ab and cd intersect, properly or improperly. +static bool intersect(const unsigned char* a, const unsigned char* b, + const unsigned char* c, const unsigned char* d) +{ + if (intersectProp(a, b, c, d)) + return true; + else if (between(a, b, c) || between(a, b, d) || + between(c, d, a) || between(c, d, b)) + return true; + else + return false; +} + +static bool vequal(const unsigned char* a, const unsigned char* b) +{ + return a[0] == b[0] && a[2] == b[2]; +} + +// Returns T iff (v_i, v_j) is a proper internal *or* external +// diagonal of P, *ignoring edges incident to v_i and v_j*. +static bool diagonalie(int i, int j, int n, const unsigned char* verts, const unsigned short* indices) +{ + const unsigned char* d0 = &verts[(indices[i] & 0x7fff) * 4]; + const unsigned char* d1 = &verts[(indices[j] & 0x7fff) * 4]; + + // For each edge (k,k+1) of P + for (int k = 0; k < n; k++) + { + int k1 = next(k, n); + // Skip edges incident to i or j + if (!((k == i) || (k1 == i) || (k == j) || (k1 == j))) + { + const unsigned char* p0 = &verts[(indices[k] & 0x7fff) * 4]; + const unsigned char* p1 = &verts[(indices[k1] & 0x7fff) * 4]; + + if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1)) + continue; + + if (intersect(d0, d1, p0, p1)) + return false; + } + } + return true; +} + +// Returns true iff the diagonal (i,j) is strictly internal to the +// polygon P in the neighborhood of the i endpoint. +static bool inCone(int i, int j, int n, const unsigned char* verts, const unsigned short* indices) +{ + const unsigned char* pi = &verts[(indices[i] & 0x7fff) * 4]; + const unsigned char* pj = &verts[(indices[j] & 0x7fff) * 4]; + const unsigned char* pi1 = &verts[(indices[next(i, n)] & 0x7fff) * 4]; + const unsigned char* pin1 = &verts[(indices[prev(i, n)] & 0x7fff) * 4]; + + // If P[i] is a convex vertex [ i+1 left or on (i-1,i) ]. + if (leftOn(pin1, pi, pi1)) + return left(pi, pj, pin1) && left(pj, pi, pi1); + // Assume (i-1,i,i+1) not collinear. + // else P[i] is reflex. + return !(leftOn(pi, pj, pi1) && leftOn(pj, pi, pin1)); +} + +// Returns T iff (v_i, v_j) is a proper internal +// diagonal of P. +static bool diagonal(int i, int j, int n, const unsigned char* verts, const unsigned short* indices) +{ + return inCone(i, j, n, verts, indices) && diagonalie(i, j, n, verts, indices); +} + +static int triangulate(int n, const unsigned char* verts, unsigned short* indices, unsigned short* tris) +{ + int ntris = 0; + unsigned short* dst = tris; + + // The last bit of the index is used to indicate if the vertex can be removed. + for (int i = 0; i < n; i++) + { + int i1 = next(i, n); + int i2 = next(i1, n); + if (diagonal(i, i2, n, verts, indices)) + indices[i1] |= 0x8000; + } + + while (n > 3) + { + int minLen = -1; + int mini = -1; + for (int i = 0; i < n; i++) + { + int i1 = next(i, n); + if (indices[i1] & 0x8000) + { + const unsigned char* p0 = &verts[(indices[i] & 0x7fff) * 4]; + const unsigned char* p2 = &verts[(indices[next(i1, n)] & 0x7fff) * 4]; + + const int dx = (int)p2[0] - (int)p0[0]; + const int dz = (int)p2[2] - (int)p0[2]; + const int len = dx*dx + dz*dz; + if (minLen < 0 || len < minLen) + { + minLen = len; + mini = i; + } + } + } + + if (mini == -1) + { + // Should not happen. + /* printf("mini == -1 ntris=%d n=%d\n", ntris, n); + for (int i = 0; i < n; i++) + { + printf("%d ", indices[i] & 0x0fffffff); + } + printf("\n");*/ + return -ntris; + } + + int i = mini; + int i1 = next(i, n); + int i2 = next(i1, n); + + *dst++ = indices[i] & 0x7fff; + *dst++ = indices[i1] & 0x7fff; + *dst++ = indices[i2] & 0x7fff; + ntris++; + + // Removes P[i1] by copying P[i+1]...P[n-1] left one index. + n--; + for (int k = i1; k < n; k++) + indices[k] = indices[k+1]; + + if (i1 >= n) i1 = 0; + i = prev(i1,n); + // Update diagonal flags. + if (diagonal(prev(i, n), i1, n, verts, indices)) + indices[i] |= 0x8000; + else + indices[i] &= 0x7fff; + + if (diagonal(i, next(i1, n), n, verts, indices)) + indices[i1] |= 0x8000; + else + indices[i1] &= 0x7fff; + } + + // Append the remaining triangle. + *dst++ = indices[0] & 0x7fff; + *dst++ = indices[1] & 0x7fff; + *dst++ = indices[2] & 0x7fff; + ntris++; + + return ntris; +} + + +static int countPolyVerts(const unsigned short* p) +{ + for (int i = 0; i < MAX_VERTS_PER_POLY; ++i) + if (p[i] == DT_TILECACHE_NULL_IDX) + return i; + return MAX_VERTS_PER_POLY; +} + +inline bool uleft(const unsigned short* a, const unsigned short* b, const unsigned short* c) +{ + return ((int)b[0] - (int)a[0]) * ((int)c[2] - (int)a[2]) - + ((int)c[0] - (int)a[0]) * ((int)b[2] - (int)a[2]) < 0; +} + +static int getPolyMergeValue(unsigned short* pa, unsigned short* pb, + const unsigned short* verts, int& ea, int& eb) +{ + const int na = countPolyVerts(pa); + const int nb = countPolyVerts(pb); + + // If the merged polygon would be too big, do not merge. + if (na+nb-2 > MAX_VERTS_PER_POLY) + return -1; + + // Check if the polygons share an edge. + ea = -1; + eb = -1; + + for (int i = 0; i < na; ++i) + { + unsigned short va0 = pa[i]; + unsigned short va1 = pa[(i+1) % na]; + if (va0 > va1) + dtSwap(va0, va1); + for (int j = 0; j < nb; ++j) + { + unsigned short vb0 = pb[j]; + unsigned short vb1 = pb[(j+1) % nb]; + if (vb0 > vb1) + dtSwap(vb0, vb1); + if (va0 == vb0 && va1 == vb1) + { + ea = i; + eb = j; + break; + } + } + } + + // No common edge, cannot merge. + if (ea == -1 || eb == -1) + return -1; + + // Check to see if the merged polygon would be convex. + unsigned short va, vb, vc; + + va = pa[(ea+na-1) % na]; + vb = pa[ea]; + vc = pb[(eb+2) % nb]; + if (!uleft(&verts[va*3], &verts[vb*3], &verts[vc*3])) + return -1; + + va = pb[(eb+nb-1) % nb]; + vb = pb[eb]; + vc = pa[(ea+2) % na]; + if (!uleft(&verts[va*3], &verts[vb*3], &verts[vc*3])) + return -1; + + va = pa[ea]; + vb = pa[(ea+1)%na]; + + int dx = (int)verts[va*3+0] - (int)verts[vb*3+0]; + int dy = (int)verts[va*3+2] - (int)verts[vb*3+2]; + + return dx*dx + dy*dy; +} + +static void mergePolys(unsigned short* pa, unsigned short* pb, int ea, int eb) +{ + unsigned short tmp[MAX_VERTS_PER_POLY*2]; + + const int na = countPolyVerts(pa); + const int nb = countPolyVerts(pb); + + // Merge polygons. + memset(tmp, 0xff, sizeof(unsigned short)*MAX_VERTS_PER_POLY*2); + int n = 0; + // Add pa + for (int i = 0; i < na-1; ++i) + tmp[n++] = pa[(ea+1+i) % na]; + // Add pb + for (int i = 0; i < nb-1; ++i) + tmp[n++] = pb[(eb+1+i) % nb]; + + memcpy(pa, tmp, sizeof(unsigned short)*MAX_VERTS_PER_POLY); +} + + +static void pushFront(unsigned short v, unsigned short* arr, int& an) +{ + an++; + for (int i = an-1; i > 0; --i) + arr[i] = arr[i-1]; + arr[0] = v; +} + +static void pushBack(unsigned short v, unsigned short* arr, int& an) +{ + arr[an] = v; + an++; +} + +static bool canRemoveVertex(dtTileCachePolyMesh& mesh, const unsigned short rem) +{ + // Count number of polygons to remove. + int numRemovedVerts = 0; + int numTouchedVerts = 0; + int numRemainingEdges = 0; + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*MAX_VERTS_PER_POLY*2]; + const int nv = countPolyVerts(p); + int numRemoved = 0; + int numVerts = 0; + for (int j = 0; j < nv; ++j) + { + if (p[j] == rem) + { + numTouchedVerts++; + numRemoved++; + } + numVerts++; + } + if (numRemoved) + { + numRemovedVerts += numRemoved; + numRemainingEdges += numVerts-(numRemoved+1); + } + } + + // There would be too few edges remaining to create a polygon. + // This can happen for example when a tip of a triangle is marked + // as deletion, but there are no other polys that share the vertex. + // In this case, the vertex should not be removed. + if (numRemainingEdges <= 2) + return false; + + // Check that there is enough memory for the test. + const int maxEdges = numTouchedVerts*2; + if (maxEdges > MAX_REM_EDGES) + return false; + + // Find edges which share the removed vertex. + unsigned short edges[MAX_REM_EDGES]; + int nedges = 0; + + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*MAX_VERTS_PER_POLY*2]; + const int nv = countPolyVerts(p); + + // Collect edges which touches the removed vertex. + for (int j = 0, k = nv-1; j < nv; k = j++) + { + if (p[j] == rem || p[k] == rem) + { + // Arrange edge so that a=rem. + int a = p[j], b = p[k]; + if (b == rem) + dtSwap(a,b); + + // Check if the edge exists + bool exists = false; + for (int m = 0; m < nedges; ++m) + { + unsigned short* e = &edges[m*3]; + if (e[1] == b) + { + // Exists, increment vertex share count. + e[2]++; + exists = true; + } + } + // Add new edge. + if (!exists) + { + unsigned short* e = &edges[nedges*3]; + e[0] = (unsigned short)a; + e[1] = (unsigned short)b; + e[2] = 1; + nedges++; + } + } + } + } + + // There should be no more than 2 open edges. + // This catches the case that two non-adjacent polygons + // share the removed vertex. In that case, do not remove the vertex. + int numOpenEdges = 0; + for (int i = 0; i < nedges; ++i) + { + if (edges[i*3+2] < 2) + numOpenEdges++; + } + if (numOpenEdges > 2) + return false; + + return true; +} + +static dtStatus removeVertex(dtTileCachePolyMesh& mesh, const unsigned short rem, const int maxTris) +{ + // Count number of polygons to remove. + int numRemovedVerts = 0; + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*MAX_VERTS_PER_POLY*2]; + const int nv = countPolyVerts(p); + for (int j = 0; j < nv; ++j) + { + if (p[j] == rem) + numRemovedVerts++; + } + } + + int nedges = 0; + unsigned short edges[MAX_REM_EDGES*3]; + int nhole = 0; + unsigned short hole[MAX_REM_EDGES]; + int nharea = 0; + unsigned short harea[MAX_REM_EDGES]; + + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*MAX_VERTS_PER_POLY*2]; + const int nv = countPolyVerts(p); + bool hasRem = false; + for (int j = 0; j < nv; ++j) + if (p[j] == rem) hasRem = true; + if (hasRem) + { + // Collect edges which does not touch the removed vertex. + for (int j = 0, k = nv-1; j < nv; k = j++) + { + if (p[j] != rem && p[k] != rem) + { + if (nedges >= MAX_REM_EDGES) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + unsigned short* e = &edges[nedges*3]; + e[0] = p[k]; + e[1] = p[j]; + e[2] = mesh.areas[i]; + nedges++; + } + } + // Remove the polygon. + unsigned short* p2 = &mesh.polys[(mesh.npolys-1)*MAX_VERTS_PER_POLY*2]; + memcpy(p,p2,sizeof(unsigned short)*MAX_VERTS_PER_POLY); + memset(p+MAX_VERTS_PER_POLY,0xff,sizeof(unsigned short)*MAX_VERTS_PER_POLY); + mesh.areas[i] = mesh.areas[mesh.npolys-1]; + mesh.npolys--; + --i; + } + } + + // Remove vertex. + for (int i = (int)rem; i < mesh.nverts; ++i) + { + mesh.verts[i*3+0] = mesh.verts[(i+1)*3+0]; + mesh.verts[i*3+1] = mesh.verts[(i+1)*3+1]; + mesh.verts[i*3+2] = mesh.verts[(i+1)*3+2]; + } + mesh.nverts--; + + // Adjust indices to match the removed vertex layout. + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*MAX_VERTS_PER_POLY*2]; + const int nv = countPolyVerts(p); + for (int j = 0; j < nv; ++j) + if (p[j] > rem) p[j]--; + } + for (int i = 0; i < nedges; ++i) + { + if (edges[i*3+0] > rem) edges[i*3+0]--; + if (edges[i*3+1] > rem) edges[i*3+1]--; + } + + if (nedges == 0) + return DT_SUCCESS; + + // Start with one vertex, keep appending connected + // segments to the start and end of the hole. + pushBack(edges[0], hole, nhole); + pushBack(edges[2], harea, nharea); + + while (nedges) + { + bool match = false; + + for (int i = 0; i < nedges; ++i) + { + const unsigned short ea = edges[i*3+0]; + const unsigned short eb = edges[i*3+1]; + const unsigned short a = edges[i*3+2]; + bool add = false; + if (hole[0] == eb) + { + // The segment matches the beginning of the hole boundary. + if (nhole >= MAX_REM_EDGES) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + pushFront(ea, hole, nhole); + pushFront(a, harea, nharea); + add = true; + } + else if (hole[nhole-1] == ea) + { + // The segment matches the end of the hole boundary. + if (nhole >= MAX_REM_EDGES) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + pushBack(eb, hole, nhole); + pushBack(a, harea, nharea); + add = true; + } + if (add) + { + // The edge segment was added, remove it. + edges[i*3+0] = edges[(nedges-1)*3+0]; + edges[i*3+1] = edges[(nedges-1)*3+1]; + edges[i*3+2] = edges[(nedges-1)*3+2]; + --nedges; + match = true; + --i; + } + } + + if (!match) + break; + } + + + unsigned short tris[MAX_REM_EDGES*3]; + unsigned char tverts[MAX_REM_EDGES*3]; + unsigned short tpoly[MAX_REM_EDGES*3]; + + // Generate temp vertex array for triangulation. + for (int i = 0; i < nhole; ++i) + { + const unsigned short pi = hole[i]; + tverts[i*4+0] = (unsigned char)mesh.verts[pi*3+0]; + tverts[i*4+1] = (unsigned char)mesh.verts[pi*3+1]; + tverts[i*4+2] = (unsigned char)mesh.verts[pi*3+2]; + tverts[i*4+3] = 0; + tpoly[i] = (unsigned short)i; + } + + // Triangulate the hole. + int ntris = triangulate(nhole, tverts, tpoly, tris); + if (ntris < 0) + { + // TODO: issue warning! + ntris = -ntris; + } + + if (ntris > MAX_REM_EDGES) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + + unsigned short polys[MAX_REM_EDGES*MAX_VERTS_PER_POLY]; + unsigned char pareas[MAX_REM_EDGES]; + + // Build initial polygons. + int npolys = 0; + memset(polys, 0xff, ntris*MAX_VERTS_PER_POLY*sizeof(unsigned short)); + for (int j = 0; j < ntris; ++j) + { + unsigned short* t = &tris[j*3]; + if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2]) + { + polys[npolys*MAX_VERTS_PER_POLY+0] = hole[t[0]]; + polys[npolys*MAX_VERTS_PER_POLY+1] = hole[t[1]]; + polys[npolys*MAX_VERTS_PER_POLY+2] = hole[t[2]]; + pareas[npolys] = (unsigned char)harea[t[0]]; + npolys++; + } + } + if (!npolys) + return DT_SUCCESS; + + // Merge polygons. + int maxVertsPerPoly = MAX_VERTS_PER_POLY; + if (maxVertsPerPoly > 3) + { + for (;;) + { + // Find best polygons to merge. + int bestMergeVal = 0; + int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0; + + for (int j = 0; j < npolys-1; ++j) + { + unsigned short* pj = &polys[j*MAX_VERTS_PER_POLY]; + for (int k = j+1; k < npolys; ++k) + { + unsigned short* pk = &polys[k*MAX_VERTS_PER_POLY]; + int ea, eb; + int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb); + if (v > bestMergeVal) + { + bestMergeVal = v; + bestPa = j; + bestPb = k; + bestEa = ea; + bestEb = eb; + } + } + } + + if (bestMergeVal > 0) + { + // Found best, merge. + unsigned short* pa = &polys[bestPa*MAX_VERTS_PER_POLY]; + unsigned short* pb = &polys[bestPb*MAX_VERTS_PER_POLY]; + mergePolys(pa, pb, bestEa, bestEb); + memcpy(pb, &polys[(npolys-1)*MAX_VERTS_PER_POLY], sizeof(unsigned short)*MAX_VERTS_PER_POLY); + pareas[bestPb] = pareas[npolys-1]; + npolys--; + } + else + { + // Could not merge any polygons, stop. + break; + } + } + } + + // Store polygons. + for (int i = 0; i < npolys; ++i) + { + if (mesh.npolys >= maxTris) break; + unsigned short* p = &mesh.polys[mesh.npolys*MAX_VERTS_PER_POLY*2]; + memset(p,0xff,sizeof(unsigned short)*MAX_VERTS_PER_POLY*2); + for (int j = 0; j < MAX_VERTS_PER_POLY; ++j) + p[j] = polys[i*MAX_VERTS_PER_POLY+j]; + mesh.areas[mesh.npolys] = pareas[i]; + mesh.npolys++; + if (mesh.npolys > maxTris) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + } + + return DT_SUCCESS; +} + + +dtStatus dtBuildTileCachePolyMesh(dtTileCacheAlloc* alloc, + dtTileCacheContourSet& lcset, + dtTileCachePolyMesh& mesh) +{ + dtAssert(alloc); + + int maxVertices = 0; + int maxTris = 0; + int maxVertsPerCont = 0; + for (int i = 0; i < lcset.nconts; ++i) + { + // Skip null contours. + if (lcset.conts[i].nverts < 3) continue; + maxVertices += lcset.conts[i].nverts; + maxTris += lcset.conts[i].nverts - 2; + maxVertsPerCont = dtMax(maxVertsPerCont, lcset.conts[i].nverts); + } + + // TODO: warn about too many vertices? + + mesh.nvp = MAX_VERTS_PER_POLY; + + dtFixedArray vflags(alloc, maxVertices); + if (!vflags) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(vflags, 0, maxVertices); + + mesh.verts = (unsigned short*)alloc->alloc(sizeof(unsigned short)*maxVertices*3); + if (!mesh.verts) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + mesh.polys = (unsigned short*)alloc->alloc(sizeof(unsigned short)*maxTris*MAX_VERTS_PER_POLY*2); + if (!mesh.polys) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + mesh.areas = (unsigned char*)alloc->alloc(sizeof(unsigned char)*maxTris); + if (!mesh.areas) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + mesh.flags = (unsigned short*)alloc->alloc(sizeof(unsigned short)*maxTris); + if (!mesh.flags) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + // Just allocate and clean the mesh flags array. The user is resposible for filling it. + memset(mesh.flags, 0, sizeof(unsigned short) * maxTris); + + mesh.nverts = 0; + mesh.npolys = 0; + + memset(mesh.verts, 0, sizeof(unsigned short)*maxVertices*3); + memset(mesh.polys, 0xff, sizeof(unsigned short)*maxTris*MAX_VERTS_PER_POLY*2); + memset(mesh.areas, 0, sizeof(unsigned char)*maxTris); + + unsigned short firstVert[VERTEX_BUCKET_COUNT2]; + for (int i = 0; i < VERTEX_BUCKET_COUNT2; ++i) + firstVert[i] = DT_TILECACHE_NULL_IDX; + + dtFixedArray nextVert(alloc, maxVertices); + if (!nextVert) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(nextVert, 0, sizeof(unsigned short)*maxVertices); + + dtFixedArray indices(alloc, maxVertsPerCont); + if (!indices) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + dtFixedArray tris(alloc, maxVertsPerCont*3); + if (!tris) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + dtFixedArray polys(alloc, maxVertsPerCont*MAX_VERTS_PER_POLY); + if (!polys) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + for (int i = 0; i < lcset.nconts; ++i) + { + dtTileCacheContour& cont = lcset.conts[i]; + + // Skip null contours. + if (cont.nverts < 3) + continue; + + // Triangulate contour + for (int j = 0; j < cont.nverts; ++j) + indices[j] = (unsigned short)j; + + int ntris = triangulate(cont.nverts, cont.verts, &indices[0], &tris[0]); + if (ntris <= 0) + { + // TODO: issue warning! + ntris = -ntris; + } + + // Add and merge vertices. + for (int j = 0; j < cont.nverts; ++j) + { + const unsigned char* v = &cont.verts[j*4]; + indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2], + mesh.verts, firstVert, nextVert, mesh.nverts); + if (v[3] & 0x80) + { + // This vertex should be removed. + vflags[indices[j]] = 1; + } + } + + // Build initial polygons. + int npolys = 0; + memset(polys, 0xff, sizeof(unsigned short) * maxVertsPerCont * MAX_VERTS_PER_POLY); + for (int j = 0; j < ntris; ++j) + { + const unsigned short* t = &tris[j*3]; + if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2]) + { + polys[npolys*MAX_VERTS_PER_POLY+0] = indices[t[0]]; + polys[npolys*MAX_VERTS_PER_POLY+1] = indices[t[1]]; + polys[npolys*MAX_VERTS_PER_POLY+2] = indices[t[2]]; + npolys++; + } + } + if (!npolys) + continue; + + // Merge polygons. + int maxVertsPerPoly =MAX_VERTS_PER_POLY ; + if (maxVertsPerPoly > 3) + { + for(;;) + { + // Find best polygons to merge. + int bestMergeVal = 0; + int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0; + + for (int j = 0; j < npolys-1; ++j) + { + unsigned short* pj = &polys[j*MAX_VERTS_PER_POLY]; + for (int k = j+1; k < npolys; ++k) + { + unsigned short* pk = &polys[k*MAX_VERTS_PER_POLY]; + int ea, eb; + int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb); + if (v > bestMergeVal) + { + bestMergeVal = v; + bestPa = j; + bestPb = k; + bestEa = ea; + bestEb = eb; + } + } + } + + if (bestMergeVal > 0) + { + // Found best, merge. + unsigned short* pa = &polys[bestPa*MAX_VERTS_PER_POLY]; + unsigned short* pb = &polys[bestPb*MAX_VERTS_PER_POLY]; + mergePolys(pa, pb, bestEa, bestEb); + memcpy(pb, &polys[(npolys-1)*MAX_VERTS_PER_POLY], sizeof(unsigned short)*MAX_VERTS_PER_POLY); + npolys--; + } + else + { + // Could not merge any polygons, stop. + break; + } + } + } + + // Store polygons. + for (int j = 0; j < npolys; ++j) + { + unsigned short* p = &mesh.polys[mesh.npolys*MAX_VERTS_PER_POLY*2]; + unsigned short* q = &polys[j*MAX_VERTS_PER_POLY]; + for (int k = 0; k < MAX_VERTS_PER_POLY; ++k) + p[k] = q[k]; + mesh.areas[mesh.npolys] = cont.area; + mesh.npolys++; + if (mesh.npolys > maxTris) + return DT_FAILURE | DT_BUFFER_TOO_SMALL; + } + } + + + // Remove edge vertices. + for (int i = 0; i < mesh.nverts; ++i) + { + if (vflags[i]) + { + if (!canRemoveVertex(mesh, (unsigned short)i)) + continue; + dtStatus status = removeVertex(mesh, (unsigned short)i, maxTris); + if (dtStatusFailed(status)) + return status; + // Remove vertex + // Note: mesh.nverts is already decremented inside removeVertex()! + for (int j = i; j < mesh.nverts; ++j) + vflags[j] = vflags[j+1]; + --i; + } + } + + // Calculate adjacency. + if (!buildMeshAdjacency(alloc, mesh.polys, mesh.npolys, mesh.verts, mesh.nverts, lcset)) + return DT_FAILURE | DT_OUT_OF_MEMORY; + + return DT_SUCCESS; +} + +dtStatus dtMarkCylinderArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch, + const float* pos, const float radius, const float height, const unsigned char areaId) +{ + float bmin[3], bmax[3]; + bmin[0] = pos[0] - radius; + bmin[1] = pos[1]; + bmin[2] = pos[2] - radius; + bmax[0] = pos[0] + radius; + bmax[1] = pos[1] + height; + bmax[2] = pos[2] + radius; + const float r2 = dtSqr(radius/cs + 0.5f); + + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + const float ics = 1.0f/cs; + const float ich = 1.0f/ch; + + const float px = (pos[0]-orig[0])*ics; + const float pz = (pos[2]-orig[2])*ics; + + int minx = (int)dtMathFloorf((bmin[0]-orig[0])*ics); + int miny = (int)dtMathFloorf((bmin[1]-orig[1])*ich); + int minz = (int)dtMathFloorf((bmin[2]-orig[2])*ics); + int maxx = (int)dtMathFloorf((bmax[0]-orig[0])*ics); + int maxy = (int)dtMathFloorf((bmax[1]-orig[1])*ich); + int maxz = (int)dtMathFloorf((bmax[2]-orig[2])*ics); + + if (maxx < 0) return DT_SUCCESS; + if (minx >= w) return DT_SUCCESS; + if (maxz < 0) return DT_SUCCESS; + if (minz >= h) return DT_SUCCESS; + + if (minx < 0) minx = 0; + if (maxx >= w) maxx = w-1; + if (minz < 0) minz = 0; + if (maxz >= h) maxz = h-1; + + for (int z = minz; z <= maxz; ++z) + { + for (int x = minx; x <= maxx; ++x) + { + const float dx = (float)(x+0.5f) - px; + const float dz = (float)(z+0.5f) - pz; + if (dx*dx + dz*dz > r2) + continue; + const int y = layer.heights[x+z*w]; + if (y < miny || y > maxy) + continue; + layer.areas[x+z*w] = areaId; + } + } + + return DT_SUCCESS; +} + +dtStatus dtMarkBoxArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch, + const float* bmin, const float* bmax, const unsigned char areaId) +{ + const int w = (int)layer.header->width; + const int h = (int)layer.header->height; + const float ics = 1.0f/cs; + const float ich = 1.0f/ch; + + int minx = (int)floorf((bmin[0]-orig[0])*ics); + int miny = (int)floorf((bmin[1]-orig[1])*ich); + int minz = (int)floorf((bmin[2]-orig[2])*ics); + int maxx = (int)floorf((bmax[0]-orig[0])*ics); + int maxy = (int)floorf((bmax[1]-orig[1])*ich); + int maxz = (int)floorf((bmax[2]-orig[2])*ics); + + if (maxx < 0) return DT_SUCCESS; + if (minx >= w) return DT_SUCCESS; + if (maxz < 0) return DT_SUCCESS; + if (minz >= h) return DT_SUCCESS; + + if (minx < 0) minx = 0; + if (maxx >= w) maxx = w-1; + if (minz < 0) minz = 0; + if (maxz >= h) maxz = h-1; + + for (int z = minz; z <= maxz; ++z) + { + for (int x = minx; x <= maxx; ++x) + { + const int y = layer.heights[x+z*w]; + if (y < miny || y > maxy) + continue; + layer.areas[x+z*w] = areaId; + } + } + + return DT_SUCCESS; +} + +dtStatus dtBuildTileCacheLayer(dtTileCacheCompressor* comp, + dtTileCacheLayerHeader* header, + const unsigned char* heights, + const unsigned char* areas, + const unsigned char* cons, + unsigned char** outData, int* outDataSize) +{ + const int headerSize = dtAlign4(sizeof(dtTileCacheLayerHeader)); + const int gridSize = (int)header->width * (int)header->height; + const int maxDataSize = headerSize + comp->maxCompressedSize(gridSize*3); + unsigned char* data = (unsigned char*)dtAlloc(maxDataSize, DT_ALLOC_PERM); + if (!data) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(data, 0, maxDataSize); + + // Store header + memcpy(data, header, sizeof(dtTileCacheLayerHeader)); + + // Concatenate grid data for compression. + const int bufferSize = gridSize*3; + unsigned char* buffer = (unsigned char*)dtAlloc(bufferSize, DT_ALLOC_TEMP); + if (!buffer) + { + dtFree(data); + return DT_FAILURE | DT_OUT_OF_MEMORY; + } + + memcpy(buffer, heights, gridSize); + memcpy(buffer+gridSize, areas, gridSize); + memcpy(buffer+gridSize*2, cons, gridSize); + + // Compress + unsigned char* compressed = data + headerSize; + const int maxCompressedSize = maxDataSize - headerSize; + int compressedSize = 0; + dtStatus status = comp->compress(buffer, bufferSize, compressed, maxCompressedSize, &compressedSize); + if (dtStatusFailed(status)) + { + dtFree(buffer); + dtFree(data); + return status; + } + + *outData = data; + *outDataSize = headerSize + compressedSize; + + dtFree(buffer); + + return DT_SUCCESS; +} + +void dtFreeTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheLayer* layer) +{ + dtAssert(alloc); + // The layer is allocated as one conitguous blob of data. + alloc->free(layer); +} + +dtStatus dtDecompressTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheCompressor* comp, + unsigned char* compressed, const int compressedSize, + dtTileCacheLayer** layerOut) +{ + dtAssert(alloc); + dtAssert(comp); + + if (!layerOut) + return DT_FAILURE | DT_INVALID_PARAM; + if (!compressed) + return DT_FAILURE | DT_INVALID_PARAM; + + *layerOut = 0; + + dtTileCacheLayerHeader* compressedHeader = (dtTileCacheLayerHeader*)compressed; + if (compressedHeader->magic != DT_TILECACHE_MAGIC) + return DT_FAILURE | DT_WRONG_MAGIC; + if (compressedHeader->version != DT_TILECACHE_VERSION) + return DT_FAILURE | DT_WRONG_VERSION; + + const int layerSize = dtAlign4(sizeof(dtTileCacheLayer)); + const int headerSize = dtAlign4(sizeof(dtTileCacheLayerHeader)); + const int gridSize = (int)compressedHeader->width * (int)compressedHeader->height; + const int bufferSize = layerSize + headerSize + gridSize*4; + + unsigned char* buffer = (unsigned char*)alloc->alloc(bufferSize); + if (!buffer) + return DT_FAILURE | DT_OUT_OF_MEMORY; + memset(buffer, 0, bufferSize); + + dtTileCacheLayer* layer = (dtTileCacheLayer*)buffer; + dtTileCacheLayerHeader* header = (dtTileCacheLayerHeader*)(buffer + layerSize); + unsigned char* grids = buffer + layerSize + headerSize; + const int gridsSize = bufferSize - (layerSize + headerSize); + + // Copy header + memcpy(header, compressedHeader, headerSize); + // Decompress grid. + int size = 0; + dtStatus status = comp->decompress(compressed+headerSize, compressedSize-headerSize, + grids, gridsSize, &size); + if (dtStatusFailed(status)) + { + dtFree(buffer); + return status; + } + + layer->header = header; + layer->heights = grids; + layer->areas = grids + gridSize; + layer->cons = grids + gridSize*2; + layer->regs = grids + gridSize*3; + + *layerOut = layer; + + return DT_SUCCESS; +} + + + +bool dtTileCacheHeaderSwapEndian(unsigned char* data, const int dataSize) +{ + dtIgnoreUnused(dataSize); + dtTileCacheLayerHeader* header = (dtTileCacheLayerHeader*)data; + + int swappedMagic = DT_TILECACHE_MAGIC; + int swappedVersion = DT_TILECACHE_VERSION; + dtSwapEndian(&swappedMagic); + dtSwapEndian(&swappedVersion); + + if ((header->magic != DT_TILECACHE_MAGIC || header->version != DT_TILECACHE_VERSION) && + (header->magic != swappedMagic || header->version != swappedVersion)) + { + return false; + } + + dtSwapEndian(&header->magic); + dtSwapEndian(&header->version); + dtSwapEndian(&header->tx); + dtSwapEndian(&header->ty); + dtSwapEndian(&header->tlayer); + dtSwapEndian(&header->bmin[0]); + dtSwapEndian(&header->bmin[1]); + dtSwapEndian(&header->bmin[2]); + dtSwapEndian(&header->bmax[0]); + dtSwapEndian(&header->bmax[1]); + dtSwapEndian(&header->bmax[2]); + dtSwapEndian(&header->hmin); + dtSwapEndian(&header->hmax); + + // width, height, minx, maxx, miny, maxy are unsigned char, no need to swap. + + return true; +} + diff --git a/libs/recast/recast/include/Recast.h b/libs/recast/recast/include/Recast.h new file mode 100644 index 000000000..e85c0d2e2 --- /dev/null +++ b/libs/recast/recast/include/Recast.h @@ -0,0 +1,1200 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef RECAST_H +#define RECAST_H + +/// The value of PI used by Recast. +static const float RC_PI = 3.14159265f; + +/// Recast log categories. +/// @see rcContext +enum rcLogCategory +{ + RC_LOG_PROGRESS = 1, ///< A progress log entry. + RC_LOG_WARNING, ///< A warning log entry. + RC_LOG_ERROR, ///< An error log entry. +}; + +/// Recast performance timer categories. +/// @see rcContext +enum rcTimerLabel +{ + /// The user defined total time of the build. + RC_TIMER_TOTAL, + /// A user defined build time. + RC_TIMER_TEMP, + /// The time to rasterize the triangles. (See: #rcRasterizeTriangle) + RC_TIMER_RASTERIZE_TRIANGLES, + /// The time to build the compact heightfield. (See: #rcBuildCompactHeightfield) + RC_TIMER_BUILD_COMPACTHEIGHTFIELD, + /// The total time to build the contours. (See: #rcBuildContours) + RC_TIMER_BUILD_CONTOURS, + /// The time to trace the boundaries of the contours. (See: #rcBuildContours) + RC_TIMER_BUILD_CONTOURS_TRACE, + /// The time to simplify the contours. (See: #rcBuildContours) + RC_TIMER_BUILD_CONTOURS_SIMPLIFY, + /// The time to filter ledge spans. (See: #rcFilterLedgeSpans) + RC_TIMER_FILTER_BORDER, + /// The time to filter low height spans. (See: #rcFilterWalkableLowHeightSpans) + RC_TIMER_FILTER_WALKABLE, + /// The time to apply the median filter. (See: #rcMedianFilterWalkableArea) + RC_TIMER_MEDIAN_AREA, + /// The time to filter low obstacles. (See: #rcFilterLowHangingWalkableObstacles) + RC_TIMER_FILTER_LOW_OBSTACLES, + /// The time to build the polygon mesh. (See: #rcBuildPolyMesh) + RC_TIMER_BUILD_POLYMESH, + /// The time to merge polygon meshes. (See: #rcMergePolyMeshes) + RC_TIMER_MERGE_POLYMESH, + /// The time to erode the walkable area. (See: #rcErodeWalkableArea) + RC_TIMER_ERODE_AREA, + /// The time to mark a box area. (See: #rcMarkBoxArea) + RC_TIMER_MARK_BOX_AREA, + /// The time to mark a cylinder area. (See: #rcMarkCylinderArea) + RC_TIMER_MARK_CYLINDER_AREA, + /// The time to mark a convex polygon area. (See: #rcMarkConvexPolyArea) + RC_TIMER_MARK_CONVEXPOLY_AREA, + /// The total time to build the distance field. (See: #rcBuildDistanceField) + RC_TIMER_BUILD_DISTANCEFIELD, + /// The time to build the distances of the distance field. (See: #rcBuildDistanceField) + RC_TIMER_BUILD_DISTANCEFIELD_DIST, + /// The time to blur the distance field. (See: #rcBuildDistanceField) + RC_TIMER_BUILD_DISTANCEFIELD_BLUR, + /// The total time to build the regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone) + RC_TIMER_BUILD_REGIONS, + /// The total time to apply the watershed algorithm. (See: #rcBuildRegions) + RC_TIMER_BUILD_REGIONS_WATERSHED, + /// The time to expand regions while applying the watershed algorithm. (See: #rcBuildRegions) + RC_TIMER_BUILD_REGIONS_EXPAND, + /// The time to flood regions while applying the watershed algorithm. (See: #rcBuildRegions) + RC_TIMER_BUILD_REGIONS_FLOOD, + /// The time to filter out small regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone) + RC_TIMER_BUILD_REGIONS_FILTER, + /// The time to build heightfield layers. (See: #rcBuildHeightfieldLayers) + RC_TIMER_BUILD_LAYERS, + /// The time to build the polygon mesh detail. (See: #rcBuildPolyMeshDetail) + RC_TIMER_BUILD_POLYMESHDETAIL, + /// The time to merge polygon mesh details. (See: #rcMergePolyMeshDetails) + RC_TIMER_MERGE_POLYMESHDETAIL, + /// The maximum number of timers. (Used for iterating timers.) + RC_MAX_TIMERS +}; + +/// Provides an interface for optional logging and performance tracking of the Recast +/// build process. +/// @ingroup recast +class rcContext +{ +public: + + /// Contructor. + /// @param[in] state TRUE if the logging and performance timers should be enabled. [Default: true] + inline rcContext(bool state = true) : m_logEnabled(state), m_timerEnabled(state) {} + virtual ~rcContext() {} + + /// Enables or disables logging. + /// @param[in] state TRUE if logging should be enabled. + inline void enableLog(bool state) { m_logEnabled = state; } + + /// Clears all log entries. + inline void resetLog() { if (m_logEnabled) doResetLog(); } + + /// Logs a message. + /// @param[in] category The category of the message. + /// @param[in] format The message. + void log(const rcLogCategory category, const char* format, ...); + + /// Enables or disables the performance timers. + /// @param[in] state TRUE if timers should be enabled. + inline void enableTimer(bool state) { m_timerEnabled = state; } + + /// Clears all peformance timers. (Resets all to unused.) + inline void resetTimers() { if (m_timerEnabled) doResetTimers(); } + + /// Starts the specified performance timer. + /// @param label The category of the timer. + inline void startTimer(const rcTimerLabel label) { if (m_timerEnabled) doStartTimer(label); } + + /// Stops the specified performance timer. + /// @param label The category of the timer. + inline void stopTimer(const rcTimerLabel label) { if (m_timerEnabled) doStopTimer(label); } + + /// Returns the total accumulated time of the specified performance timer. + /// @param label The category of the timer. + /// @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started. + inline int getAccumulatedTime(const rcTimerLabel label) const { return m_timerEnabled ? doGetAccumulatedTime(label) : -1; } + +protected: + + /// Clears all log entries. + virtual void doResetLog() {} + + /// Logs a message. + /// @param[in] category The category of the message. + /// @param[in] msg The formatted message. + /// @param[in] len The length of the formatted message. + virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {} + + /// Clears all timers. (Resets all to unused.) + virtual void doResetTimers() {} + + /// Starts the specified performance timer. + /// @param[in] label The category of timer. + virtual void doStartTimer(const rcTimerLabel /*label*/) {} + + /// Stops the specified performance timer. + /// @param[in] label The category of the timer. + virtual void doStopTimer(const rcTimerLabel /*label*/) {} + + /// Returns the total accumulated time of the specified performance timer. + /// @param[in] label The category of the timer. + /// @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started. + virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; } + + /// True if logging is enabled. + bool m_logEnabled; + + /// True if the performance timers are enabled. + bool m_timerEnabled; +}; + +/// A helper to first start a timer and then stop it when this helper goes out of scope. +/// @see rcContext +class rcScopedTimer +{ +public: + /// Constructs an instance and starts the timer. + /// @param[in] ctx The context to use. + /// @param[in] label The category of the timer. + inline rcScopedTimer(rcContext* ctx, const rcTimerLabel label) : m_ctx(ctx), m_label(label) { m_ctx->startTimer(m_label); } + inline ~rcScopedTimer() { m_ctx->stopTimer(m_label); } + +private: + // Explicitly disabled copy constructor and copy assignment operator. + rcScopedTimer(const rcScopedTimer&); + rcScopedTimer& operator=(const rcScopedTimer&); + + rcContext* const m_ctx; + const rcTimerLabel m_label; +}; + +/// Specifies a configuration to use when performing Recast builds. +/// @ingroup recast +struct rcConfig +{ + /// The width of the field along the x-axis. [Limit: >= 0] [Units: vx] + int width; + + /// The height of the field along the z-axis. [Limit: >= 0] [Units: vx] + int height; + + /// The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx] + int tileSize; + + /// The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx] + int borderSize; + + /// The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu] + float cs; + + /// The y-axis cell size to use for fields. [Limit: > 0] [Units: wu] + float ch; + + /// The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu] + float bmin[3]; + + /// The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu] + float bmax[3]; + + /// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees] + float walkableSlopeAngle; + + /// Minimum floor to 'ceiling' height that will still allow the floor area to + /// be considered walkable. [Limit: >= 3] [Units: vx] + int walkableHeight; + + /// Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx] + int walkableClimb; + + /// The distance to erode/shrink the walkable area of the heightfield away from + /// obstructions. [Limit: >=0] [Units: vx] + int walkableRadius; + + /// The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx] + int maxEdgeLen; + + /// The maximum distance a simplfied contour's border edges should deviate + /// the original raw contour. [Limit: >=0] [Units: vx] + float maxSimplificationError; + + /// The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx] + int minRegionArea; + + /// Any regions with a span count smaller than this value will, if possible, + /// be merged with larger regions. [Limit: >=0] [Units: vx] + int mergeRegionArea; + + /// The maximum number of vertices allowed for polygons generated during the + /// contour to polygon conversion process. [Limit: >= 3] + int maxVertsPerPoly; + + /// Sets the sampling distance to use when generating the detail mesh. + /// (For height detail only.) [Limits: 0 or >= 0.9] [Units: wu] + float detailSampleDist; + + /// The maximum distance the detail mesh surface should deviate from heightfield + /// data. (For height detail only.) [Limit: >=0] [Units: wu] + float detailSampleMaxError; +}; + +/// Defines the number of bits allocated to rcSpan::smin and rcSpan::smax. +static const int RC_SPAN_HEIGHT_BITS = 13; +/// Defines the maximum value for rcSpan::smin and rcSpan::smax. +static const int RC_SPAN_MAX_HEIGHT = (1 << RC_SPAN_HEIGHT_BITS) - 1; + +/// The number of spans allocated per span spool. +/// @see rcSpanPool +static const int RC_SPANS_PER_POOL = 2048; + +/// Represents a span in a heightfield. +/// @see rcHeightfield +struct rcSpan +{ + unsigned int smin : RC_SPAN_HEIGHT_BITS; ///< The lower limit of the span. [Limit: < #smax] + unsigned int smax : RC_SPAN_HEIGHT_BITS; ///< The upper limit of the span. [Limit: <= #RC_SPAN_MAX_HEIGHT] + unsigned int area : 6; ///< The area id assigned to the span. + rcSpan* next; ///< The next span higher up in column. +}; + +/// A memory pool used for quick allocation of spans within a heightfield. +/// @see rcHeightfield +struct rcSpanPool +{ + rcSpanPool* next; ///< The next span pool. + rcSpan items[RC_SPANS_PER_POOL]; ///< Array of spans in the pool. +}; + +/// A dynamic heightfield representing obstructed space. +/// @ingroup recast +struct rcHeightfield +{ + rcHeightfield(); + ~rcHeightfield(); + + int width; ///< The width of the heightfield. (Along the x-axis in cell units.) + int height; ///< The height of the heightfield. (Along the z-axis in cell units.) + float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] + float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] + float cs; ///< The size of each cell. (On the xz-plane.) + float ch; ///< The height of each cell. (The minimum increment along the y-axis.) + rcSpan** spans; ///< Heightfield of spans (width*height). + rcSpanPool* pools; ///< Linked list of span pools. + rcSpan* freelist; ///< The next free span. + +private: + // Explicitly-disabled copy constructor and copy assignment operator. + rcHeightfield(const rcHeightfield&); + rcHeightfield& operator=(const rcHeightfield&); +}; + +/// Provides information on the content of a cell column in a compact heightfield. +struct rcCompactCell +{ + unsigned int index : 24; ///< Index to the first span in the column. + unsigned int count : 8; ///< Number of spans in the column. +}; + +/// Represents a span of unobstructed space within a compact heightfield. +struct rcCompactSpan +{ + unsigned short y; ///< The lower extent of the span. (Measured from the heightfield's base.) + unsigned short reg; ///< The id of the region the span belongs to. (Or zero if not in a region.) + unsigned int con : 24; ///< Packed neighbor connection data. + unsigned int h : 8; ///< The height of the span. (Measured from #y.) +}; + +/// A compact, static heightfield representing unobstructed space. +/// @ingroup recast +struct rcCompactHeightfield +{ + int width; ///< The width of the heightfield. (Along the x-axis in cell units.) + int height; ///< The height of the heightfield. (Along the z-axis in cell units.) + int spanCount; ///< The number of spans in the heightfield. + int walkableHeight; ///< The walkable height used during the build of the field. (See: rcConfig::walkableHeight) + int walkableClimb; ///< The walkable climb used during the build of the field. (See: rcConfig::walkableClimb) + int borderSize; ///< The AABB border size used during the build of the field. (See: rcConfig::borderSize) + unsigned short maxDistance; ///< The maximum distance value of any span within the field. + unsigned short maxRegions; ///< The maximum region id of any span within the field. + float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] + float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] + float cs; ///< The size of each cell. (On the xz-plane.) + float ch; ///< The height of each cell. (The minimum increment along the y-axis.) + rcCompactCell* cells; ///< Array of cells. [Size: #width*#height] + rcCompactSpan* spans; ///< Array of spans. [Size: #spanCount] + unsigned short* dist; ///< Array containing border distance data. [Size: #spanCount] + unsigned char* areas; ///< Array containing area id data. [Size: #spanCount] +}; + +/// Represents a heightfield layer within a layer set. +/// @see rcHeightfieldLayerSet +struct rcHeightfieldLayer +{ + float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] + float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] + float cs; ///< The size of each cell. (On the xz-plane.) + float ch; ///< The height of each cell. (The minimum increment along the y-axis.) + int width; ///< The width of the heightfield. (Along the x-axis in cell units.) + int height; ///< The height of the heightfield. (Along the z-axis in cell units.) + int minx; ///< The minimum x-bounds of usable data. + int maxx; ///< The maximum x-bounds of usable data. + int miny; ///< The minimum y-bounds of usable data. (Along the z-axis.) + int maxy; ///< The maximum y-bounds of usable data. (Along the z-axis.) + int hmin; ///< The minimum height bounds of usable data. (Along the y-axis.) + int hmax; ///< The maximum height bounds of usable data. (Along the y-axis.) + unsigned char* heights; ///< The heightfield. [Size: width * height] + unsigned char* areas; ///< Area ids. [Size: Same as #heights] + unsigned char* cons; ///< Packed neighbor connection information. [Size: Same as #heights] +}; + +/// Represents a set of heightfield layers. +/// @ingroup recast +/// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet +struct rcHeightfieldLayerSet +{ + rcHeightfieldLayer* layers; ///< The layers in the set. [Size: #nlayers] + int nlayers; ///< The number of layers in the set. +}; + +/// Represents a simple, non-overlapping contour in field space. +struct rcContour +{ + int* verts; ///< Simplified contour vertex and connection data. [Size: 4 * #nverts] + int nverts; ///< The number of vertices in the simplified contour. + int* rverts; ///< Raw contour vertex and connection data. [Size: 4 * #nrverts] + int nrverts; ///< The number of vertices in the raw contour. + unsigned short reg; ///< The region id of the contour. + unsigned char area; ///< The area id of the contour. +}; + +/// Represents a group of related contours. +/// @ingroup recast +struct rcContourSet +{ + rcContour* conts; ///< An array of the contours in the set. [Size: #nconts] + int nconts; ///< The number of contours in the set. + float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] + float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] + float cs; ///< The size of each cell. (On the xz-plane.) + float ch; ///< The height of each cell. (The minimum increment along the y-axis.) + int width; ///< The width of the set. (Along the x-axis in cell units.) + int height; ///< The height of the set. (Along the z-axis in cell units.) + int borderSize; ///< The AABB border size used to generate the source data from which the contours were derived. + float maxError; ///< The max edge error that this contour set was simplified with. +}; + +/// Represents a polygon mesh suitable for use in building a navigation mesh. +/// @ingroup recast +struct rcPolyMesh +{ + unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts] + unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp] + unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys] + unsigned short* flags; ///< The user defined flags for each polygon. [Length: #maxpolys] + unsigned char* areas; ///< The area id assigned to each polygon. [Length: #maxpolys] + int nverts; ///< The number of vertices. + int npolys; ///< The number of polygons. + int maxpolys; ///< The number of allocated polygons. + int nvp; ///< The maximum number of vertices per polygon. + float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] + float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] + float cs; ///< The size of each cell. (On the xz-plane.) + float ch; ///< The height of each cell. (The minimum increment along the y-axis.) + int borderSize; ///< The AABB border size used to generate the source data from which the mesh was derived. + float maxEdgeError; ///< The max error of the polygon edges in the mesh. +}; + +/// Contains triangle meshes that represent detailed height data associated +/// with the polygons in its associated polygon mesh object. +/// @ingroup recast +struct rcPolyMeshDetail +{ + unsigned int* meshes; ///< The sub-mesh data. [Size: 4*#nmeshes] + float* verts; ///< The mesh vertices. [Size: 3*#nverts] + unsigned char* tris; ///< The mesh triangles. [Size: 4*#ntris] + int nmeshes; ///< The number of sub-meshes defined by #meshes. + int nverts; ///< The number of vertices in #verts. + int ntris; ///< The number of triangles in #tris. +}; + +/// @name Allocation Functions +/// Functions used to allocate and de-allocate Recast objects. +/// @see rcAllocSetCustom +/// @{ + +/// Allocates a heightfield object using the Recast allocator. +/// @return A heightfield that is ready for initialization, or null on failure. +/// @ingroup recast +/// @see rcCreateHeightfield, rcFreeHeightField +rcHeightfield* rcAllocHeightfield(); + +/// Frees the specified heightfield object using the Recast allocator. +/// @param[in] hf A heightfield allocated using #rcAllocHeightfield +/// @ingroup recast +/// @see rcAllocHeightfield +void rcFreeHeightField(rcHeightfield* hf); + +/// Allocates a compact heightfield object using the Recast allocator. +/// @return A compact heightfield that is ready for initialization, or null on failure. +/// @ingroup recast +/// @see rcBuildCompactHeightfield, rcFreeCompactHeightfield +rcCompactHeightfield* rcAllocCompactHeightfield(); + +/// Frees the specified compact heightfield object using the Recast allocator. +/// @param[in] chf A compact heightfield allocated using #rcAllocCompactHeightfield +/// @ingroup recast +/// @see rcAllocCompactHeightfield +void rcFreeCompactHeightfield(rcCompactHeightfield* chf); + +/// Allocates a heightfield layer set using the Recast allocator. +/// @return A heightfield layer set that is ready for initialization, or null on failure. +/// @ingroup recast +/// @see rcBuildHeightfieldLayers, rcFreeHeightfieldLayerSet +rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet(); + +/// Frees the specified heightfield layer set using the Recast allocator. +/// @param[in] lset A heightfield layer set allocated using #rcAllocHeightfieldLayerSet +/// @ingroup recast +/// @see rcAllocHeightfieldLayerSet +void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset); + +/// Allocates a contour set object using the Recast allocator. +/// @return A contour set that is ready for initialization, or null on failure. +/// @ingroup recast +/// @see rcBuildContours, rcFreeContourSet +rcContourSet* rcAllocContourSet(); + +/// Frees the specified contour set using the Recast allocator. +/// @param[in] cset A contour set allocated using #rcAllocContourSet +/// @ingroup recast +/// @see rcAllocContourSet +void rcFreeContourSet(rcContourSet* cset); + +/// Allocates a polygon mesh object using the Recast allocator. +/// @return A polygon mesh that is ready for initialization, or null on failure. +/// @ingroup recast +/// @see rcBuildPolyMesh, rcFreePolyMesh +rcPolyMesh* rcAllocPolyMesh(); + +/// Frees the specified polygon mesh using the Recast allocator. +/// @param[in] pmesh A polygon mesh allocated using #rcAllocPolyMesh +/// @ingroup recast +/// @see rcAllocPolyMesh +void rcFreePolyMesh(rcPolyMesh* pmesh); + +/// Allocates a detail mesh object using the Recast allocator. +/// @return A detail mesh that is ready for initialization, or null on failure. +/// @ingroup recast +/// @see rcBuildPolyMeshDetail, rcFreePolyMeshDetail +rcPolyMeshDetail* rcAllocPolyMeshDetail(); + +/// Frees the specified detail mesh using the Recast allocator. +/// @param[in] dmesh A detail mesh allocated using #rcAllocPolyMeshDetail +/// @ingroup recast +/// @see rcAllocPolyMeshDetail +void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh); + +/// @} + +/// Heighfield border flag. +/// If a heightfield region ID has this bit set, then the region is a border +/// region and its spans are considered unwalkable. +/// (Used during the region and contour build process.) +/// @see rcCompactSpan::reg +static const unsigned short RC_BORDER_REG = 0x8000; + +/// Polygon touches multiple regions. +/// If a polygon has this region ID it was merged with or created +/// from polygons of different regions during the polymesh +/// build step that removes redundant border vertices. +/// (Used during the polymesh and detail polymesh build processes) +/// @see rcPolyMesh::regs +static const unsigned short RC_MULTIPLE_REGS = 0; + +/// Border vertex flag. +/// If a region ID has this bit set, then the associated element lies on +/// a tile border. If a contour vertex's region ID has this bit set, the +/// vertex will later be removed in order to match the segments and vertices +/// at tile boundaries. +/// (Used during the build process.) +/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts +static const int RC_BORDER_VERTEX = 0x10000; + +/// Area border flag. +/// If a region ID has this bit set, then the associated element lies on +/// the border of an area. +/// (Used during the region and contour build process.) +/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts +static const int RC_AREA_BORDER = 0x20000; + +/// Contour build flags. +/// @see rcBuildContours +enum rcBuildContoursFlags +{ + RC_CONTOUR_TESS_WALL_EDGES = 0x01, ///< Tessellate solid (impassable) edges during contour simplification. + RC_CONTOUR_TESS_AREA_EDGES = 0x02, ///< Tessellate edges between areas during contour simplification. +}; + +/// Applied to the region id field of contour vertices in order to extract the region id. +/// The region id field of a vertex may have several flags applied to it. So the +/// fields value can't be used directly. +/// @see rcContour::verts, rcContour::rverts +static const int RC_CONTOUR_REG_MASK = 0xffff; + +/// An value which indicates an invalid index within a mesh. +/// @note This does not necessarily indicate an error. +/// @see rcPolyMesh::polys +static const unsigned short RC_MESH_NULL_IDX = 0xffff; + +/// Represents the null area. +/// When a data element is given this value it is considered to no longer be +/// assigned to a usable area. (E.g. It is unwalkable.) +static const unsigned char RC_NULL_AREA = 0; + +/// The default area id used to indicate a walkable polygon. +/// This is also the maximum allowed area id, and the only non-null area id +/// recognized by some steps in the build process. +static const unsigned char RC_WALKABLE_AREA = 63; + +/// The value returned by #rcGetCon if the specified direction is not connected +/// to another span. (Has no neighbor.) +static const int RC_NOT_CONNECTED = 0x3f; + +/// @name General helper functions +/// @{ + +/// Used to ignore a function parameter. VS complains about unused parameters +/// and this silences the warning. +/// @param [in] _ Unused parameter +template void rcIgnoreUnused(const T&) { } + +/// Swaps the values of the two parameters. +/// @param[in,out] a Value A +/// @param[in,out] b Value B +template inline void rcSwap(T& a, T& b) { T t = a; a = b; b = t; } + +/// Returns the minimum of two values. +/// @param[in] a Value A +/// @param[in] b Value B +/// @return The minimum of the two values. +template inline T rcMin(T a, T b) { return a < b ? a : b; } + +/// Returns the maximum of two values. +/// @param[in] a Value A +/// @param[in] b Value B +/// @return The maximum of the two values. +template inline T rcMax(T a, T b) { return a > b ? a : b; } + +/// Returns the absolute value. +/// @param[in] a The value. +/// @return The absolute value of the specified value. +template inline T rcAbs(T a) { return a < 0 ? -a : a; } + +/// Returns the square of the value. +/// @param[in] a The value. +/// @return The square of the value. +template inline T rcSqr(T a) { return a*a; } + +/// Clamps the value to the specified range. +/// @param[in] v The value to clamp. +/// @param[in] mn The minimum permitted return value. +/// @param[in] mx The maximum permitted return value. +/// @return The value, clamped to the specified range. +template inline T rcClamp(T v, T mn, T mx) { return v < mn ? mn : (v > mx ? mx : v); } + +/// Returns the square root of the value. +/// @param[in] x The value. +/// @return The square root of the vlaue. +float rcSqrt(float x); + +/// @} +/// @name Vector helper functions. +/// @{ + +/// Derives the cross product of two vectors. (@p v1 x @p v2) +/// @param[out] dest The cross product. [(x, y, z)] +/// @param[in] v1 A Vector [(x, y, z)] +/// @param[in] v2 A vector [(x, y, z)] +inline void rcVcross(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[1]*v2[2] - v1[2]*v2[1]; + dest[1] = v1[2]*v2[0] - v1[0]*v2[2]; + dest[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +/// Derives the dot product of two vectors. (@p v1 . @p v2) +/// @param[in] v1 A Vector [(x, y, z)] +/// @param[in] v2 A vector [(x, y, z)] +/// @return The dot product. +inline float rcVdot(const float* v1, const float* v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +/// Performs a scaled vector addition. (@p v1 + (@p v2 * @p s)) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector. [(x, y, z)] +/// @param[in] v2 The vector to scale and add to @p v1. [(x, y, z)] +/// @param[in] s The amount to scale @p v2 by before adding to @p v1. +inline void rcVmad(float* dest, const float* v1, const float* v2, const float s) +{ + dest[0] = v1[0]+v2[0]*s; + dest[1] = v1[1]+v2[1]*s; + dest[2] = v1[2]+v2[2]*s; +} + +/// Performs a vector addition. (@p v1 + @p v2) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector. [(x, y, z)] +/// @param[in] v2 The vector to add to @p v1. [(x, y, z)] +inline void rcVadd(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[0]+v2[0]; + dest[1] = v1[1]+v2[1]; + dest[2] = v1[2]+v2[2]; +} + +/// Performs a vector subtraction. (@p v1 - @p v2) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector. [(x, y, z)] +/// @param[in] v2 The vector to subtract from @p v1. [(x, y, z)] +inline void rcVsub(float* dest, const float* v1, const float* v2) +{ + dest[0] = v1[0]-v2[0]; + dest[1] = v1[1]-v2[1]; + dest[2] = v1[2]-v2[2]; +} + +/// Selects the minimum value of each element from the specified vectors. +/// @param[in,out] mn A vector. (Will be updated with the result.) [(x, y, z)] +/// @param[in] v A vector. [(x, y, z)] +inline void rcVmin(float* mn, const float* v) +{ + mn[0] = rcMin(mn[0], v[0]); + mn[1] = rcMin(mn[1], v[1]); + mn[2] = rcMin(mn[2], v[2]); +} + +/// Selects the maximum value of each element from the specified vectors. +/// @param[in,out] mx A vector. (Will be updated with the result.) [(x, y, z)] +/// @param[in] v A vector. [(x, y, z)] +inline void rcVmax(float* mx, const float* v) +{ + mx[0] = rcMax(mx[0], v[0]); + mx[1] = rcMax(mx[1], v[1]); + mx[2] = rcMax(mx[2], v[2]); +} + +/// Performs a vector copy. +/// @param[out] dest The result. [(x, y, z)] +/// @param[in] v The vector to copy. [(x, y, z)] +inline void rcVcopy(float* dest, const float* v) +{ + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; +} + +/// Returns the distance between two points. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The distance between the two points. +inline float rcVdist(const float* v1, const float* v2) +{ + float dx = v2[0] - v1[0]; + float dy = v2[1] - v1[1]; + float dz = v2[2] - v1[2]; + return rcSqrt(dx*dx + dy*dy + dz*dz); +} + +/// Returns the square of the distance between two points. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The square of the distance between the two points. +inline float rcVdistSqr(const float* v1, const float* v2) +{ + float dx = v2[0] - v1[0]; + float dy = v2[1] - v1[1]; + float dz = v2[2] - v1[2]; + return dx*dx + dy*dy + dz*dz; +} + +/// Normalizes the vector. +/// @param[in,out] v The vector to normalize. [(x, y, z)] +inline void rcVnormalize(float* v) +{ + float d = 1.0f / rcSqrt(rcSqr(v[0]) + rcSqr(v[1]) + rcSqr(v[2])); + v[0] *= d; + v[1] *= d; + v[2] *= d; +} + +/// @} +/// @name Heightfield Functions +/// @see rcHeightfield +/// @{ + +/// Calculates the bounding box of an array of vertices. +/// @ingroup recast +/// @param[in] verts An array of vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices in the @p verts array. +/// @param[out] bmin The minimum bounds of the AABB. [(x, y, z)] [Units: wu] +/// @param[out] bmax The maximum bounds of the AABB. [(x, y, z)] [Units: wu] +void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax); + +/// Calculates the grid size based on the bounding box and grid cell size. +/// @ingroup recast +/// @param[in] bmin The minimum bounds of the AABB. [(x, y, z)] [Units: wu] +/// @param[in] bmax The maximum bounds of the AABB. [(x, y, z)] [Units: wu] +/// @param[in] cs The xz-plane cell size. [Limit: > 0] [Units: wu] +/// @param[out] w The width along the x-axis. [Limit: >= 0] [Units: vx] +/// @param[out] h The height along the z-axis. [Limit: >= 0] [Units: vx] +void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int* h); + +/// Initializes a new heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] hf The allocated heightfield to initialize. +/// @param[in] width The width of the field along the x-axis. [Limit: >= 0] [Units: vx] +/// @param[in] height The height of the field along the z-axis. [Limit: >= 0] [Units: vx] +/// @param[in] bmin The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu] +/// @param[in] bmax The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu] +/// @param[in] cs The xz-plane cell size to use for the field. [Limit: > 0] [Units: wu] +/// @param[in] ch The y-axis cell size to use for field. [Limit: > 0] [Units: wu] +/// @returns True if the operation completed successfully. +bool rcCreateHeightfield(rcContext* ctx, rcHeightfield& hf, int width, int height, + const float* bmin, const float* bmax, + float cs, float ch); + +/// Sets the area id of all triangles with a slope below the specified value +/// to #RC_WALKABLE_AREA. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableSlopeAngle The maximum slope that is considered walkable. +/// [Limits: 0 <= value < 90] [Units: Degrees] +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle vertex indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] nt The number of triangles. +/// @param[out] areas The triangle area ids. [Length: >= @p nt] +void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv, + const int* tris, int nt, unsigned char* areas); + +/// Sets the area id of all triangles with a slope greater than or equal to the specified value to #RC_NULL_AREA. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableSlopeAngle The maximum slope that is considered walkable. +/// [Limits: 0 <= value < 90] [Units: Degrees] +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle vertex indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] nt The number of triangles. +/// @param[out] areas The triangle area ids. [Length: >= @p nt] +void rcClearUnwalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv, + const int* tris, int nt, unsigned char* areas); + +/// Adds a span to the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] hf An initialized heightfield. +/// @param[in] x The width index where the span is to be added. +/// [Limits: 0 <= value < rcHeightfield::width] +/// @param[in] y The height index where the span is to be added. +/// [Limits: 0 <= value < rcHeightfield::height] +/// @param[in] smin The minimum height of the span. [Limit: < @p smax] [Units: vx] +/// @param[in] smax The maximum height of the span. [Limit: <= #RC_SPAN_MAX_HEIGHT] [Units: vx] +/// @param[in] area The area id of the span. [Limit: <= #RC_WALKABLE_AREA) +/// @param[in] flagMergeThr The merge theshold. [Limit: >= 0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcAddSpan(rcContext* ctx, rcHeightfield& hf, const int x, const int y, + const unsigned short smin, const unsigned short smax, + const unsigned char area, const int flagMergeThr); + +/// Rasterizes a triangle into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] v0 Triangle vertex 0 [(x, y, z)] +/// @param[in] v1 Triangle vertex 1 [(x, y, z)] +/// @param[in] v2 Triangle vertex 2 [(x, y, z)] +/// @param[in] area The area id of the triangle. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2, + const unsigned char area, rcHeightfield& solid, + const int flagMergeThr = 1); + +/// Rasterizes an indexed triangle mesh into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] areas The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt] +/// @param[in] nt The number of triangles. +/// @param[in,out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv, + const int* tris, const unsigned char* areas, const int nt, + rcHeightfield& solid, const int flagMergeThr = 1); + +/// Rasterizes an indexed triangle mesh into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] areas The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt] +/// @param[in] nt The number of triangles. +/// @param[in,out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv, + const unsigned short* tris, const unsigned char* areas, const int nt, + rcHeightfield& solid, const int flagMergeThr = 1); + +/// Rasterizes triangles into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The triangle vertices. [(ax, ay, az, bx, by, bz, cx, by, cx) * @p nt] +/// @param[in] areas The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt] +/// @param[in] nt The number of triangles. +/// @param[in,out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt, + rcHeightfield& solid, const int flagMergeThr = 1); + +/// Marks non-walkable spans as walkable if their maximum is within @p walkableClimp of a walkable neighbor. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableClimb Maximum ledge height that is considered to still be traversable. +/// [Limit: >=0] [Units: vx] +/// @param[in,out] solid A fully built heightfield. (All spans have been added.) +void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid); + +/// Marks spans that are ledges as not-walkable. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area to +/// be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[in] walkableClimb Maximum ledge height that is considered to still be traversable. +/// [Limit: >=0] [Units: vx] +/// @param[in,out] solid A fully built heightfield. (All spans have been added.) +void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, + const int walkableClimb, rcHeightfield& solid); + +/// Marks walkable spans as not walkable if the clearence above the span is less than the specified height. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area to +/// be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[in,out] solid A fully built heightfield. (All spans have been added.) +void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid); + +/// Returns the number of spans contained in the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] hf An initialized heightfield. +/// @returns The number of spans in the heightfield. +int rcGetHeightFieldSpanCount(rcContext* ctx, rcHeightfield& hf); + +/// @} +/// @name Compact Heightfield Functions +/// @see rcCompactHeightfield +/// @{ + +/// Builds a compact heightfield representing open space, from a heightfield representing solid space. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area +/// to be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[in] walkableClimb Maximum ledge height that is considered to still be traversable. +/// [Limit: >=0] [Units: vx] +/// @param[in] hf The heightfield to be compacted. +/// @param[out] chf The resulting compact heightfield. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. +bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb, + rcHeightfield& hf, rcCompactHeightfield& chf); + +/// Erodes the walkable area within the heightfield by the specified radius. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] radius The radius of erosion. [Limits: 0 < value < 255] [Units: vx] +/// @param[in,out] chf The populated compact heightfield to erode. +/// @returns True if the operation completed successfully. +bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf); + +/// Applies a median filter to walkable area types (based on area id), removing noise. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @returns True if the operation completed successfully. +bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf); + +/// Applies an area id to all spans within the specified bounding box. (AABB) +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] bmin The minimum of the bounding box. [(x, y, z)] +/// @param[in] bmax The maximum of the bounding box. [(x, y, z)] +/// @param[in] areaId The area id to apply. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] chf A populated compact heightfield. +void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId, + rcCompactHeightfield& chf); + +/// Applies the area id to the all spans within the specified convex polygon. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The vertices of the polygon [Fomr: (x, y, z) * @p nverts] +/// @param[in] nverts The number of vertices in the polygon. +/// @param[in] hmin The height of the base of the polygon. +/// @param[in] hmax The height of the top of the polygon. +/// @param[in] areaId The area id to apply. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] chf A populated compact heightfield. +void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, + const float hmin, const float hmax, unsigned char areaId, + rcCompactHeightfield& chf); + +/// Helper function to offset voncex polygons for rcMarkConvexPolyArea. +/// @ingroup recast +/// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p nverts] +/// @param[in] nverts The number of vertices in the polygon. +/// @param[out] outVerts The offset vertices (should hold up to 2 * @p nverts) [Form: (x, y, z) * return value] +/// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts. +/// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts. +int rcOffsetPoly(const float* verts, const int nverts, const float offset, + float* outVerts, const int maxOutVerts); + +/// Applies the area id to all spans within the specified cylinder. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] pos The center of the base of the cylinder. [Form: (x, y, z)] +/// @param[in] r The radius of the cylinder. +/// @param[in] h The height of the cylinder. +/// @param[in] areaId The area id to apply. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] chf A populated compact heightfield. +void rcMarkCylinderArea(rcContext* ctx, const float* pos, + const float r, const float h, unsigned char areaId, + rcCompactHeightfield& chf); + +/// Builds the distance field for the specified compact heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @returns True if the operation completed successfully. +bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf); + +/// Builds region data for the heightfield using watershed partitioning. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. +/// [Limit: >=0] [Units: vx] +/// @param[in] minRegionArea The minimum number of cells allowed to form isolated island areas. +/// [Limit: >=0] [Units: vx]. +/// @param[in] mergeRegionArea Any regions with a span count smaller than this value will, if possible, +/// be merged with larger regions. [Limit: >=0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int minRegionArea, const int mergeRegionArea); + +/// Builds region data for the heightfield by partitioning the heightfield in non-overlapping layers. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. +/// [Limit: >=0] [Units: vx] +/// @param[in] minRegionArea The minimum number of cells allowed to form isolated island areas. +/// [Limit: >=0] [Units: vx]. +/// @returns True if the operation completed successfully. +bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int minRegionArea); + +/// Builds region data for the heightfield using simple monotone partitioning. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. +/// [Limit: >=0] [Units: vx] +/// @param[in] minRegionArea The minimum number of cells allowed to form isolated island areas. +/// [Limit: >=0] [Units: vx]. +/// @param[in] mergeRegionArea Any regions with a span count smaller than this value will, if possible, +/// be merged with larger regions. [Limit: >=0] [Units: vx] +/// @returns True if the operation completed successfully. +bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int minRegionArea, const int mergeRegionArea); + +/// Sets the neighbor connection data for the specified direction. +/// @param[in] s The span to update. +/// @param[in] dir The direction to set. [Limits: 0 <= value < 4] +/// @param[in] i The index of the neighbor span. +inline void rcSetCon(rcCompactSpan& s, int dir, int i) +{ + const unsigned int shift = (unsigned int)dir*6; + unsigned int con = s.con; + s.con = (con & ~(0x3f << shift)) | (((unsigned int)i & 0x3f) << shift); +} + +/// Gets neighbor connection data for the specified direction. +/// @param[in] s The span to check. +/// @param[in] dir The direction to check. [Limits: 0 <= value < 4] +/// @return The neighbor connection data for the specified direction, +/// or #RC_NOT_CONNECTED if there is no connection. +inline int rcGetCon(const rcCompactSpan& s, int dir) +{ + const unsigned int shift = (unsigned int)dir*6; + return (s.con >> shift) & 0x3f; +} + +/// Gets the standard width (x-axis) offset for the specified direction. +/// @param[in] dir The direction. [Limits: 0 <= value < 4] +/// @return The width offset to apply to the current cell position to move +/// in the direction. +inline int rcGetDirOffsetX(int dir) +{ + static const int offset[4] = { -1, 0, 1, 0, }; + return offset[dir&0x03]; +} + +/// Gets the standard height (z-axis) offset for the specified direction. +/// @param[in] dir The direction. [Limits: 0 <= value < 4] +/// @return The height offset to apply to the current cell position to move +/// in the direction. +inline int rcGetDirOffsetY(int dir) +{ + static const int offset[4] = { 0, 1, 0, -1 }; + return offset[dir&0x03]; +} + +/// Gets the direction for the specified offset. One of x and y should be 0. +/// @param[in] x The x offset. [Limits: -1 <= value <= 1] +/// @param[in] y The y offset. [Limits: -1 <= value <= 1] +/// @return The direction that represents the offset. +inline int rcGetDirForOffset(int x, int y) +{ + static const int dirs[5] = { 3, 0, -1, 2, 1 }; + return dirs[((y+1)<<1)+x]; +} + +/// @} +/// @name Layer, Contour, Polymesh, and Detail Mesh Functions +/// @see rcHeightfieldLayer, rcContourSet, rcPolyMesh, rcPolyMeshDetail +/// @{ + +/// Builds a layer set from the specified compact heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] chf A fully built compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. [Limit: >=0] +/// [Units: vx] +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area +/// to be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[out] lset The resulting layer set. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. +bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int walkableHeight, + rcHeightfieldLayerSet& lset); + +/// Builds a contour set from the region outlines in the provided compact heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] chf A fully built compact heightfield. +/// @param[in] maxError The maximum distance a simplfied contour's border edges should deviate +/// the original raw contour. [Limit: >=0] [Units: wu] +/// @param[in] maxEdgeLen The maximum allowed length for contour edges along the border of the mesh. +/// [Limit: >=0] [Units: vx] +/// @param[out] cset The resulting contour set. (Must be pre-allocated.) +/// @param[in] buildFlags The build flags. (See: #rcBuildContoursFlags) +/// @returns True if the operation completed successfully. +bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf, + const float maxError, const int maxEdgeLen, + rcContourSet& cset, const int buildFlags = RC_CONTOUR_TESS_WALL_EDGES); + +/// Builds a polygon mesh from the provided contours. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] cset A fully built contour set. +/// @param[in] nvp The maximum number of vertices allowed for polygons generated during the +/// contour to polygon conversion process. [Limit: >= 3] +/// @param[out] mesh The resulting polygon mesh. (Must be re-allocated.) +/// @returns True if the operation completed successfully. +bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh); + +/// Merges multiple polygon meshes into a single mesh. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] meshes An array of polygon meshes to merge. [Size: @p nmeshes] +/// @param[in] nmeshes The number of polygon meshes in the meshes array. +/// @param[in] mesh The resulting polygon mesh. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. +bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh); + +/// Builds a detail mesh from the provided polygon mesh. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] mesh A fully built polygon mesh. +/// @param[in] chf The compact heightfield used to build the polygon mesh. +/// @param[in] sampleDist Sets the distance to use when samping the heightfield. [Limit: >=0] [Units: wu] +/// @param[in] sampleMaxError The maximum distance the detail mesh surface should deviate from +/// heightfield data. [Limit: >=0] [Units: wu] +/// @param[out] dmesh The resulting detail mesh. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. +bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf, + const float sampleDist, const float sampleMaxError, + rcPolyMeshDetail& dmesh); + +/// Copies the poly mesh data from src to dst. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] src The source mesh to copy from. +/// @param[out] dst The resulting detail mesh. (Must be pre-allocated, must be empty mesh.) +/// @returns True if the operation completed successfully. +bool rcCopyPolyMesh(rcContext* ctx, const rcPolyMesh& src, rcPolyMesh& dst); + +/// Merges multiple detail meshes into a single detail mesh. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] meshes An array of detail meshes to merge. [Size: @p nmeshes] +/// @param[in] nmeshes The number of detail meshes in the meshes array. +/// @param[out] mesh The resulting detail mesh. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. +bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh); + +/// @} + +#endif // RECAST_H + +/////////////////////////////////////////////////////////////////////////// + +// Due to the large amount of detail documentation for this file, +// the content normally located at the end of the header file has been separated +// out to a file in /Docs/Extern. diff --git a/libs/recast/recast/include/RecastAlloc.h b/libs/recast/recast/include/RecastAlloc.h new file mode 100644 index 000000000..3cdd450d4 --- /dev/null +++ b/libs/recast/recast/include/RecastAlloc.h @@ -0,0 +1,146 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef RECASTALLOC_H +#define RECASTALLOC_H + +#include + +/// Provides hint values to the memory allocator on how long the +/// memory is expected to be used. +enum rcAllocHint +{ + RC_ALLOC_PERM, ///< Memory will persist after a function call. + RC_ALLOC_TEMP ///< Memory used temporarily within a function. +}; + +/// A memory allocation function. +// @param[in] size The size, in bytes of memory, to allocate. +// @param[in] rcAllocHint A hint to the allocator on how long the memory is expected to be in use. +// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed. +/// @see rcAllocSetCustom +typedef void* (rcAllocFunc)(size_t size, rcAllocHint hint); + +/// A memory deallocation function. +/// @param[in] ptr A pointer to a memory block previously allocated using #rcAllocFunc. +/// @see rcAllocSetCustom +typedef void (rcFreeFunc)(void* ptr); + +/// Sets the base custom allocation functions to be used by Recast. +/// @param[in] allocFunc The memory allocation function to be used by #rcAlloc +/// @param[in] freeFunc The memory de-allocation function to be used by #rcFree +void rcAllocSetCustom(rcAllocFunc *allocFunc, rcFreeFunc *freeFunc); + +/// Allocates a memory block. +/// @param[in] size The size, in bytes of memory, to allocate. +/// @param[in] hint A hint to the allocator on how long the memory is expected to be in use. +/// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed. +/// @see rcFree +void* rcAlloc(size_t size, rcAllocHint hint); + +/// Deallocates a memory block. +/// @param[in] ptr A pointer to a memory block previously allocated using #rcAlloc. +/// @see rcAlloc +void rcFree(void* ptr); + + +/// A simple dynamic array of integers. +class rcIntArray +{ + int* m_data; + int m_size, m_cap; + + void doResize(int n); + + // Explicitly disabled copy constructor and copy assignment operator. + rcIntArray(const rcIntArray&); + rcIntArray& operator=(const rcIntArray&); + +public: + /// Constructs an instance with an initial array size of zero. + rcIntArray() : m_data(0), m_size(0), m_cap(0) {} + + /// Constructs an instance initialized to the specified size. + /// @param[in] n The initial size of the integer array. + rcIntArray(int n) : m_data(0), m_size(0), m_cap(0) { resize(n); } + ~rcIntArray() { rcFree(m_data); } + + /// Specifies the new size of the integer array. + /// @param[in] n The new size of the integer array. + void resize(int n) + { + if (n > m_cap) + doResize(n); + + m_size = n; + } + + /// Push the specified integer onto the end of the array and increases the size by one. + /// @param[in] item The new value. + void push(int item) { resize(m_size+1); m_data[m_size-1] = item; } + + /// Returns the value at the end of the array and reduces the size by one. + /// @return The value at the end of the array. + int pop() + { + if (m_size > 0) + m_size--; + + return m_data[m_size]; + } + + /// The value at the specified array index. + /// @warning Does not provide overflow protection. + /// @param[in] i The index of the value. + const int& operator[](int i) const { return m_data[i]; } + + /// The value at the specified array index. + /// @warning Does not provide overflow protection. + /// @param[in] i The index of the value. + int& operator[](int i) { return m_data[i]; } + + /// The current size of the integer array. + int size() const { return m_size; } +}; + +/// A simple helper class used to delete an array when it goes out of scope. +/// @note This class is rarely if ever used by the end user. +template class rcScopedDelete +{ + T* ptr; +public: + + /// Constructs an instance with a null pointer. + inline rcScopedDelete() : ptr(0) {} + + /// Constructs an instance with the specified pointer. + /// @param[in] p An pointer to an allocated array. + inline rcScopedDelete(T* p) : ptr(p) {} + inline ~rcScopedDelete() { rcFree(ptr); } + + /// The root array pointer. + /// @return The root array pointer. + inline operator T*() { return ptr; } + +private: + // Explicitly disabled copy constructor and copy assignment operator. + rcScopedDelete(const rcScopedDelete&); + rcScopedDelete& operator=(const rcScopedDelete&); +}; + +#endif diff --git a/libs/recast/recast/include/RecastAssert.h b/libs/recast/recast/include/RecastAssert.h new file mode 100644 index 000000000..e7cc10e49 --- /dev/null +++ b/libs/recast/recast/include/RecastAssert.h @@ -0,0 +1,56 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#ifndef RECASTASSERT_H +#define RECASTASSERT_H + +// Note: This header file's only purpose is to include define assert. +// Feel free to change the file and include your own implementation instead. + +#ifdef NDEBUG + +// From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ +# define rcAssert(x) do { (void)sizeof(x); } while((void)(__LINE__==-1),false) + +#else + +/// An assertion failure function. +// @param[in] expression asserted expression. +// @param[in] file Filename of the failed assertion. +// @param[in] line Line number of the failed assertion. +/// @see rcAssertFailSetCustom +typedef void (rcAssertFailFunc)(const char* expression, const char* file, int line); + +/// Sets the base custom assertion failure function to be used by Recast. +/// @param[in] assertFailFunc The function to be used in case of failure of #dtAssert +void rcAssertFailSetCustom(rcAssertFailFunc *assertFailFunc); + +/// Gets the base custom assertion failure function to be used by Recast. +rcAssertFailFunc* rcAssertFailGetCustom(); + +# include +# define rcAssert(expression) \ + { \ + rcAssertFailFunc* failFunc = rcAssertFailGetCustom(); \ + if(failFunc == NULL) { assert(expression); } \ + else if(!(expression)) { (*failFunc)(#expression, __FILE__, __LINE__); } \ + } + +#endif + +#endif // RECASTASSERT_H diff --git a/libs/recast/recast/src/Recast.cpp b/libs/recast/recast/src/Recast.cpp new file mode 100644 index 000000000..8308d1973 --- /dev/null +++ b/libs/recast/recast/src/Recast.cpp @@ -0,0 +1,504 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + +float rcSqrt(float x) +{ + return sqrtf(x); +} + +/// @class rcContext +/// @par +/// +/// This class does not provide logging or timer functionality on its +/// own. Both must be provided by a concrete implementation +/// by overriding the protected member functions. Also, this class does not +/// provide an interface for extracting log messages. (Only adding them.) +/// So concrete implementations must provide one. +/// +/// If no logging or timers are required, just pass an instance of this +/// class through the Recast build process. +/// + +/// @par +/// +/// Example: +/// @code +/// // Where ctx is an instance of rcContext and filepath is a char array. +/// ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath); +/// @endcode +void rcContext::log(const rcLogCategory category, const char* format, ...) +{ + if (!m_logEnabled) + return; + static const int MSG_SIZE = 512; + char msg[MSG_SIZE]; + va_list ap; + va_start(ap, format); + int len = vsnprintf(msg, MSG_SIZE, format, ap); + if (len >= MSG_SIZE) + { + len = MSG_SIZE-1; + msg[MSG_SIZE-1] = '\0'; + } + va_end(ap); + doLog(category, msg, len); +} + +rcHeightfield* rcAllocHeightfield() +{ + return new (rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM)) rcHeightfield; +} + +rcHeightfield::rcHeightfield() + : width() + , height() + , bmin() + , bmax() + , cs() + , ch() + , spans() + , pools() + , freelist() +{ +} + +rcHeightfield::~rcHeightfield() +{ + // Delete span array. + rcFree(spans); + // Delete span pools. + while (pools) + { + rcSpanPool* next = pools->next; + rcFree(pools); + pools = next; + } +} + +void rcFreeHeightField(rcHeightfield* hf) +{ + if (!hf) return; + hf->~rcHeightfield(); + rcFree(hf); +} + +rcCompactHeightfield* rcAllocCompactHeightfield() +{ + rcCompactHeightfield* chf = (rcCompactHeightfield*)rcAlloc(sizeof(rcCompactHeightfield), RC_ALLOC_PERM); + memset(chf, 0, sizeof(rcCompactHeightfield)); + return chf; +} + +void rcFreeCompactHeightfield(rcCompactHeightfield* chf) +{ + if (!chf) return; + rcFree(chf->cells); + rcFree(chf->spans); + rcFree(chf->dist); + rcFree(chf->areas); + rcFree(chf); +} + +rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet() +{ + rcHeightfieldLayerSet* lset = (rcHeightfieldLayerSet*)rcAlloc(sizeof(rcHeightfieldLayerSet), RC_ALLOC_PERM); + memset(lset, 0, sizeof(rcHeightfieldLayerSet)); + return lset; +} + +void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset) +{ + if (!lset) return; + for (int i = 0; i < lset->nlayers; ++i) + { + rcFree(lset->layers[i].heights); + rcFree(lset->layers[i].areas); + rcFree(lset->layers[i].cons); + } + rcFree(lset->layers); + rcFree(lset); +} + + +rcContourSet* rcAllocContourSet() +{ + rcContourSet* cset = (rcContourSet*)rcAlloc(sizeof(rcContourSet), RC_ALLOC_PERM); + memset(cset, 0, sizeof(rcContourSet)); + return cset; +} + +void rcFreeContourSet(rcContourSet* cset) +{ + if (!cset) return; + for (int i = 0; i < cset->nconts; ++i) + { + rcFree(cset->conts[i].verts); + rcFree(cset->conts[i].rverts); + } + rcFree(cset->conts); + rcFree(cset); +} + +rcPolyMesh* rcAllocPolyMesh() +{ + rcPolyMesh* pmesh = (rcPolyMesh*)rcAlloc(sizeof(rcPolyMesh), RC_ALLOC_PERM); + memset(pmesh, 0, sizeof(rcPolyMesh)); + return pmesh; +} + +void rcFreePolyMesh(rcPolyMesh* pmesh) +{ + if (!pmesh) return; + rcFree(pmesh->verts); + rcFree(pmesh->polys); + rcFree(pmesh->regs); + rcFree(pmesh->flags); + rcFree(pmesh->areas); + rcFree(pmesh); +} + +rcPolyMeshDetail* rcAllocPolyMeshDetail() +{ + rcPolyMeshDetail* dmesh = (rcPolyMeshDetail*)rcAlloc(sizeof(rcPolyMeshDetail), RC_ALLOC_PERM); + memset(dmesh, 0, sizeof(rcPolyMeshDetail)); + return dmesh; +} + +void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh) +{ + if (!dmesh) return; + rcFree(dmesh->meshes); + rcFree(dmesh->verts); + rcFree(dmesh->tris); + rcFree(dmesh); +} + +void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax) +{ + // Calculate bounding box. + rcVcopy(bmin, verts); + rcVcopy(bmax, verts); + for (int i = 1; i < nv; ++i) + { + const float* v = &verts[i*3]; + rcVmin(bmin, v); + rcVmax(bmax, v); + } +} + +void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int* h) +{ + *w = (int)((bmax[0] - bmin[0])/cs+0.5f); + *h = (int)((bmax[2] - bmin[2])/cs+0.5f); +} + +/// @par +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocHeightfield, rcHeightfield +bool rcCreateHeightfield(rcContext* ctx, rcHeightfield& hf, int width, int height, + const float* bmin, const float* bmax, + float cs, float ch) +{ + rcIgnoreUnused(ctx); + + hf.width = width; + hf.height = height; + rcVcopy(hf.bmin, bmin); + rcVcopy(hf.bmax, bmax); + hf.cs = cs; + hf.ch = ch; + hf.spans = (rcSpan**)rcAlloc(sizeof(rcSpan*)*hf.width*hf.height, RC_ALLOC_PERM); + if (!hf.spans) + return false; + memset(hf.spans, 0, sizeof(rcSpan*)*hf.width*hf.height); + return true; +} + +static void calcTriNormal(const float* v0, const float* v1, const float* v2, float* norm) +{ + float e0[3], e1[3]; + rcVsub(e0, v1, v0); + rcVsub(e1, v2, v0); + rcVcross(norm, e0, e1); + rcVnormalize(norm); +} + +/// @par +/// +/// Only sets the area id's for the walkable triangles. Does not alter the +/// area id's for unwalkable triangles. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles +void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, + const float* verts, int nv, + const int* tris, int nt, + unsigned char* areas) +{ + rcIgnoreUnused(ctx); + rcIgnoreUnused(nv); + + const float walkableThr = cosf(walkableSlopeAngle/180.0f*RC_PI); + + float norm[3]; + + for (int i = 0; i < nt; ++i) + { + const int* tri = &tris[i*3]; + calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm); + // Check if the face is walkable. + if (norm[1] > walkableThr) + areas[i] = RC_WALKABLE_AREA; + } +} + +/// @par +/// +/// Only sets the area id's for the unwalkable triangles. Does not alter the +/// area id's for walkable triangles. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles +void rcClearUnwalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, + const float* verts, int /*nv*/, + const int* tris, int nt, + unsigned char* areas) +{ + rcIgnoreUnused(ctx); + + const float walkableThr = cosf(walkableSlopeAngle/180.0f*RC_PI); + + float norm[3]; + + for (int i = 0; i < nt; ++i) + { + const int* tri = &tris[i*3]; + calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm); + // Check if the face is walkable. + if (norm[1] <= walkableThr) + areas[i] = RC_NULL_AREA; + } +} + +int rcGetHeightFieldSpanCount(rcContext* ctx, rcHeightfield& hf) +{ + rcIgnoreUnused(ctx); + + const int w = hf.width; + const int h = hf.height; + int spanCount = 0; + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + for (rcSpan* s = hf.spans[x + y*w]; s; s = s->next) + { + if (s->area != RC_NULL_AREA) + spanCount++; + } + } + } + return spanCount; +} + +/// @par +/// +/// This is just the beginning of the process of fully building a compact heightfield. +/// Various filters may be applied, then the distance field and regions built. +/// E.g: #rcBuildDistanceField and #rcBuildRegions +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocCompactHeightfield, rcHeightfield, rcCompactHeightfield, rcConfig +bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb, + rcHeightfield& hf, rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_COMPACTHEIGHTFIELD); + + const int w = hf.width; + const int h = hf.height; + const int spanCount = rcGetHeightFieldSpanCount(ctx, hf); + + // Fill in header. + chf.width = w; + chf.height = h; + chf.spanCount = spanCount; + chf.walkableHeight = walkableHeight; + chf.walkableClimb = walkableClimb; + chf.maxRegions = 0; + rcVcopy(chf.bmin, hf.bmin); + rcVcopy(chf.bmax, hf.bmax); + chf.bmax[1] += walkableHeight*hf.ch; + chf.cs = hf.cs; + chf.ch = hf.ch; + chf.cells = (rcCompactCell*)rcAlloc(sizeof(rcCompactCell)*w*h, RC_ALLOC_PERM); + if (!chf.cells) + { + ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.cells' (%d)", w*h); + return false; + } + memset(chf.cells, 0, sizeof(rcCompactCell)*w*h); + chf.spans = (rcCompactSpan*)rcAlloc(sizeof(rcCompactSpan)*spanCount, RC_ALLOC_PERM); + if (!chf.spans) + { + ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.spans' (%d)", spanCount); + return false; + } + memset(chf.spans, 0, sizeof(rcCompactSpan)*spanCount); + chf.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*spanCount, RC_ALLOC_PERM); + if (!chf.areas) + { + ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.areas' (%d)", spanCount); + return false; + } + memset(chf.areas, RC_NULL_AREA, sizeof(unsigned char)*spanCount); + + const int MAX_HEIGHT = 0xffff; + + // Fill in cells and spans. + int idx = 0; + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcSpan* s = hf.spans[x + y*w]; + // If there are no spans at this cell, just leave the data to index=0, count=0. + if (!s) continue; + rcCompactCell& c = chf.cells[x+y*w]; + c.index = idx; + c.count = 0; + while (s) + { + if (s->area != RC_NULL_AREA) + { + const int bot = (int)s->smax; + const int top = s->next ? (int)s->next->smin : MAX_HEIGHT; + chf.spans[idx].y = (unsigned short)rcClamp(bot, 0, 0xffff); + chf.spans[idx].h = (unsigned char)rcClamp(top - bot, 0, 0xff); + chf.areas[idx] = s->area; + idx++; + c.count++; + } + s = s->next; + } + } + } + + // Find neighbour connections. + const int MAX_LAYERS = RC_NOT_CONNECTED-1; + int tooHighNeighbour = 0; + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + rcCompactSpan& s = chf.spans[i]; + + for (int dir = 0; dir < 4; ++dir) + { + rcSetCon(s, dir, RC_NOT_CONNECTED); + const int nx = x + rcGetDirOffsetX(dir); + const int ny = y + rcGetDirOffsetY(dir); + // First check that the neighbour cell is in bounds. + if (nx < 0 || ny < 0 || nx >= w || ny >= h) + continue; + + // Iterate over all neighbour spans and check if any of the is + // accessible from current cell. + const rcCompactCell& nc = chf.cells[nx+ny*w]; + for (int k = (int)nc.index, nk = (int)(nc.index+nc.count); k < nk; ++k) + { + const rcCompactSpan& ns = chf.spans[k]; + const int bot = rcMax(s.y, ns.y); + const int top = rcMin(s.y+s.h, ns.y+ns.h); + + // Check that the gap between the spans is walkable, + // and that the climb height between the gaps is not too high. + if ((top - bot) >= walkableHeight && rcAbs((int)ns.y - (int)s.y) <= walkableClimb) + { + // Mark direction as walkable. + const int lidx = k - (int)nc.index; + if (lidx < 0 || lidx > MAX_LAYERS) + { + tooHighNeighbour = rcMax(tooHighNeighbour, lidx); + continue; + } + rcSetCon(s, dir, lidx); + break; + } + } + + } + } + } + } + + if (tooHighNeighbour > MAX_LAYERS) + { + ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Heightfield has too many layers %d (max: %d)", + tooHighNeighbour, MAX_LAYERS); + } + + return true; +} + +/* +static int getHeightfieldMemoryUsage(const rcHeightfield& hf) +{ + int size = 0; + size += sizeof(hf); + size += hf.width * hf.height * sizeof(rcSpan*); + + rcSpanPool* pool = hf.pools; + while (pool) + { + size += (sizeof(rcSpanPool) - sizeof(rcSpan)) + sizeof(rcSpan)*RC_SPANS_PER_POOL; + pool = pool->next; + } + return size; +} + +static int getCompactHeightFieldMemoryusage(const rcCompactHeightfield& chf) +{ + int size = 0; + size += sizeof(rcCompactHeightfield); + size += sizeof(rcCompactSpan) * chf.spanCount; + size += sizeof(rcCompactCell) * chf.width * chf.height; + return size; +} +*/ diff --git a/libs/recast/recast/src/RecastAlloc.cpp b/libs/recast/recast/src/RecastAlloc.cpp new file mode 100644 index 000000000..453b5fa6a --- /dev/null +++ b/libs/recast/recast/src/RecastAlloc.cpp @@ -0,0 +1,86 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#include +#include "RecastAlloc.h" +#include "RecastAssert.h" + +static void *rcAllocDefault(size_t size, rcAllocHint) +{ + return malloc(size); +} + +static void rcFreeDefault(void *ptr) +{ + free(ptr); +} + +static rcAllocFunc* sRecastAllocFunc = rcAllocDefault; +static rcFreeFunc* sRecastFreeFunc = rcFreeDefault; + +/// @see rcAlloc, rcFree +void rcAllocSetCustom(rcAllocFunc *allocFunc, rcFreeFunc *freeFunc) +{ + sRecastAllocFunc = allocFunc ? allocFunc : rcAllocDefault; + sRecastFreeFunc = freeFunc ? freeFunc : rcFreeDefault; +} + +/// @see rcAllocSetCustom +void* rcAlloc(size_t size, rcAllocHint hint) +{ + return sRecastAllocFunc(size, hint); +} + +/// @par +/// +/// @warning This function leaves the value of @p ptr unchanged. So it still +/// points to the same (now invalid) location, and not to null. +/// +/// @see rcAllocSetCustom +void rcFree(void* ptr) +{ + if (ptr) + sRecastFreeFunc(ptr); +} + +/// @class rcIntArray +/// +/// While it is possible to pre-allocate a specific array size during +/// construction or by using the #resize method, certain methods will +/// automatically resize the array as needed. +/// +/// @warning The array memory is not initialized to zero when the size is +/// manually set during construction or when using #resize. + +/// @par +/// +/// Using this method ensures the array is at least large enough to hold +/// the specified number of elements. This can improve performance by +/// avoiding auto-resizing during use. +void rcIntArray::doResize(int n) +{ + if (!m_cap) m_cap = n; + while (m_cap < n) m_cap *= 2; + int* newData = (int*)rcAlloc(m_cap*sizeof(int), RC_ALLOC_TEMP); + rcAssert(newData); + if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(int)); + rcFree(m_data); + m_data = newData; +} + diff --git a/libs/recast/recast/src/RecastArea.cpp b/libs/recast/recast/src/RecastArea.cpp new file mode 100644 index 000000000..97139cf99 --- /dev/null +++ b/libs/recast/recast/src/RecastArea.cpp @@ -0,0 +1,591 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + +/// @par +/// +/// Basically, any spans that are closer to a boundary or obstruction than the specified radius +/// are marked as unwalkable. +/// +/// This method is usually called immediately after the heightfield has been built. +/// +/// @see rcCompactHeightfield, rcBuildCompactHeightfield, rcConfig::walkableRadius +bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + const int w = chf.width; + const int h = chf.height; + + rcScopedTimer timer(ctx, RC_TIMER_ERODE_AREA); + + unsigned char* dist = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP); + if (!dist) + { + ctx->log(RC_LOG_ERROR, "erodeWalkableArea: Out of memory 'dist' (%d).", chf.spanCount); + return false; + } + + // Init distance. + memset(dist, 0xff, sizeof(unsigned char)*chf.spanCount); + + // Mark boundary cells. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (chf.areas[i] == RC_NULL_AREA) + { + dist[i] = 0; + } + else + { + const rcCompactSpan& s = chf.spans[i]; + int nc = 0; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int nx = x + rcGetDirOffsetX(dir); + const int ny = y + rcGetDirOffsetY(dir); + const int nidx = (int)chf.cells[nx+ny*w].index + rcGetCon(s, dir); + if (chf.areas[nidx] != RC_NULL_AREA) + { + nc++; + } + } + } + // At least one missing neighbour. + if (nc != 4) + dist[i] = 0; + } + } + } + } + + unsigned char nd; + + // Pass 1 + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + + if (rcGetCon(s, 0) != RC_NOT_CONNECTED) + { + // (-1,0) + const int ax = x + rcGetDirOffsetX(0); + const int ay = y + rcGetDirOffsetY(0); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0); + const rcCompactSpan& as = chf.spans[ai]; + nd = (unsigned char)rcMin((int)dist[ai]+2, 255); + if (nd < dist[i]) + dist[i] = nd; + + // (-1,-1) + if (rcGetCon(as, 3) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(3); + const int aay = ay + rcGetDirOffsetY(3); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 3); + nd = (unsigned char)rcMin((int)dist[aai]+3, 255); + if (nd < dist[i]) + dist[i] = nd; + } + } + if (rcGetCon(s, 3) != RC_NOT_CONNECTED) + { + // (0,-1) + const int ax = x + rcGetDirOffsetX(3); + const int ay = y + rcGetDirOffsetY(3); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3); + const rcCompactSpan& as = chf.spans[ai]; + nd = (unsigned char)rcMin((int)dist[ai]+2, 255); + if (nd < dist[i]) + dist[i] = nd; + + // (1,-1) + if (rcGetCon(as, 2) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(2); + const int aay = ay + rcGetDirOffsetY(2); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 2); + nd = (unsigned char)rcMin((int)dist[aai]+3, 255); + if (nd < dist[i]) + dist[i] = nd; + } + } + } + } + } + + // Pass 2 + for (int y = h-1; y >= 0; --y) + { + for (int x = w-1; x >= 0; --x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + + if (rcGetCon(s, 2) != RC_NOT_CONNECTED) + { + // (1,0) + const int ax = x + rcGetDirOffsetX(2); + const int ay = y + rcGetDirOffsetY(2); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 2); + const rcCompactSpan& as = chf.spans[ai]; + nd = (unsigned char)rcMin((int)dist[ai]+2, 255); + if (nd < dist[i]) + dist[i] = nd; + + // (1,1) + if (rcGetCon(as, 1) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(1); + const int aay = ay + rcGetDirOffsetY(1); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 1); + nd = (unsigned char)rcMin((int)dist[aai]+3, 255); + if (nd < dist[i]) + dist[i] = nd; + } + } + if (rcGetCon(s, 1) != RC_NOT_CONNECTED) + { + // (0,1) + const int ax = x + rcGetDirOffsetX(1); + const int ay = y + rcGetDirOffsetY(1); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 1); + const rcCompactSpan& as = chf.spans[ai]; + nd = (unsigned char)rcMin((int)dist[ai]+2, 255); + if (nd < dist[i]) + dist[i] = nd; + + // (-1,1) + if (rcGetCon(as, 0) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(0); + const int aay = ay + rcGetDirOffsetY(0); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 0); + nd = (unsigned char)rcMin((int)dist[aai]+3, 255); + if (nd < dist[i]) + dist[i] = nd; + } + } + } + } + } + + const unsigned char thr = (unsigned char)(radius*2); + for (int i = 0; i < chf.spanCount; ++i) + if (dist[i] < thr) + chf.areas[i] = RC_NULL_AREA; + + rcFree(dist); + + return true; +} + +static void insertSort(unsigned char* a, const int n) +{ + int i, j; + for (i = 1; i < n; i++) + { + const unsigned char value = a[i]; + for (j = i - 1; j >= 0 && a[j] > value; j--) + a[j+1] = a[j]; + a[j+1] = value; + } +} + +/// @par +/// +/// This filter is usually applied after applying area id's using functions +/// such as #rcMarkBoxArea, #rcMarkConvexPolyArea, and #rcMarkCylinderArea. +/// +/// @see rcCompactHeightfield +bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + const int w = chf.width; + const int h = chf.height; + + rcScopedTimer timer(ctx, RC_TIMER_MEDIAN_AREA); + + unsigned char* areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP); + if (!areas) + { + ctx->log(RC_LOG_ERROR, "medianFilterWalkableArea: Out of memory 'areas' (%d).", chf.spanCount); + return false; + } + + // Init distance. + memset(areas, 0xff, sizeof(unsigned char)*chf.spanCount); + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + if (chf.areas[i] == RC_NULL_AREA) + { + areas[i] = chf.areas[i]; + continue; + } + + unsigned char nei[9]; + for (int j = 0; j < 9; ++j) + nei[j] = chf.areas[i]; + + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + if (chf.areas[ai] != RC_NULL_AREA) + nei[dir*2+0] = chf.areas[ai]; + + const rcCompactSpan& as = chf.spans[ai]; + const int dir2 = (dir+1) & 0x3; + if (rcGetCon(as, dir2) != RC_NOT_CONNECTED) + { + const int ax2 = ax + rcGetDirOffsetX(dir2); + const int ay2 = ay + rcGetDirOffsetY(dir2); + const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2); + if (chf.areas[ai2] != RC_NULL_AREA) + nei[dir*2+1] = chf.areas[ai2]; + } + } + } + insertSort(nei, 9); + areas[i] = nei[4]; + } + } + } + + memcpy(chf.areas, areas, sizeof(unsigned char)*chf.spanCount); + + rcFree(areas); + + return true; +} + +/// @par +/// +/// The value of spacial parameters are in world units. +/// +/// @see rcCompactHeightfield, rcMedianFilterWalkableArea +void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId, + rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_MARK_BOX_AREA); + + int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs); + int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch); + int minz = (int)((bmin[2]-chf.bmin[2])/chf.cs); + int maxx = (int)((bmax[0]-chf.bmin[0])/chf.cs); + int maxy = (int)((bmax[1]-chf.bmin[1])/chf.ch); + int maxz = (int)((bmax[2]-chf.bmin[2])/chf.cs); + + if (maxx < 0) return; + if (minx >= chf.width) return; + if (maxz < 0) return; + if (minz >= chf.height) return; + + if (minx < 0) minx = 0; + if (maxx >= chf.width) maxx = chf.width-1; + if (minz < 0) minz = 0; + if (maxz >= chf.height) maxz = chf.height-1; + + for (int z = minz; z <= maxz; ++z) + { + for (int x = minx; x <= maxx; ++x) + { + const rcCompactCell& c = chf.cells[x+z*chf.width]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + rcCompactSpan& s = chf.spans[i]; + if ((int)s.y >= miny && (int)s.y <= maxy) + { + if (chf.areas[i] != RC_NULL_AREA) + chf.areas[i] = areaId; + } + } + } + } +} + + +static int pointInPoly(int nvert, const float* verts, const float* p) +{ + int i, j, c = 0; + for (i = 0, j = nvert-1; i < nvert; j = i++) + { + const float* vi = &verts[i*3]; + const float* vj = &verts[j*3]; + if (((vi[2] > p[2]) != (vj[2] > p[2])) && + (p[0] < (vj[0]-vi[0]) * (p[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) ) + c = !c; + } + return c; +} + +/// @par +/// +/// The value of spacial parameters are in world units. +/// +/// The y-values of the polygon vertices are ignored. So the polygon is effectively +/// projected onto the xz-plane at @p hmin, then extruded to @p hmax. +/// +/// @see rcCompactHeightfield, rcMedianFilterWalkableArea +void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, + const float hmin, const float hmax, unsigned char areaId, + rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_MARK_CONVEXPOLY_AREA); + + float bmin[3], bmax[3]; + rcVcopy(bmin, verts); + rcVcopy(bmax, verts); + for (int i = 1; i < nverts; ++i) + { + rcVmin(bmin, &verts[i*3]); + rcVmax(bmax, &verts[i*3]); + } + bmin[1] = hmin; + bmax[1] = hmax; + + int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs); + int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch); + int minz = (int)((bmin[2]-chf.bmin[2])/chf.cs); + int maxx = (int)((bmax[0]-chf.bmin[0])/chf.cs); + int maxy = (int)((bmax[1]-chf.bmin[1])/chf.ch); + int maxz = (int)((bmax[2]-chf.bmin[2])/chf.cs); + + if (maxx < 0) return; + if (minx >= chf.width) return; + if (maxz < 0) return; + if (minz >= chf.height) return; + + if (minx < 0) minx = 0; + if (maxx >= chf.width) maxx = chf.width-1; + if (minz < 0) minz = 0; + if (maxz >= chf.height) maxz = chf.height-1; + + + // TODO: Optimize. + for (int z = minz; z <= maxz; ++z) + { + for (int x = minx; x <= maxx; ++x) + { + const rcCompactCell& c = chf.cells[x+z*chf.width]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + rcCompactSpan& s = chf.spans[i]; + if (chf.areas[i] == RC_NULL_AREA) + continue; + if ((int)s.y >= miny && (int)s.y <= maxy) + { + float p[3]; + p[0] = chf.bmin[0] + (x+0.5f)*chf.cs; + p[1] = 0; + p[2] = chf.bmin[2] + (z+0.5f)*chf.cs; + + if (pointInPoly(nverts, verts, p)) + { + chf.areas[i] = areaId; + } + } + } + } + } +} + +int rcOffsetPoly(const float* verts, const int nverts, const float offset, + float* outVerts, const int maxOutVerts) +{ + const float MITER_LIMIT = 1.20f; + + int n = 0; + + for (int i = 0; i < nverts; i++) + { + const int a = (i+nverts-1) % nverts; + const int b = i; + const int c = (i+1) % nverts; + const float* va = &verts[a*3]; + const float* vb = &verts[b*3]; + const float* vc = &verts[c*3]; + float dx0 = vb[0] - va[0]; + float dy0 = vb[2] - va[2]; + float d0 = dx0*dx0 + dy0*dy0; + if (d0 > 1e-6f) + { + d0 = 1.0f/rcSqrt(d0); + dx0 *= d0; + dy0 *= d0; + } + float dx1 = vc[0] - vb[0]; + float dy1 = vc[2] - vb[2]; + float d1 = dx1*dx1 + dy1*dy1; + if (d1 > 1e-6f) + { + d1 = 1.0f/rcSqrt(d1); + dx1 *= d1; + dy1 *= d1; + } + const float dlx0 = -dy0; + const float dly0 = dx0; + const float dlx1 = -dy1; + const float dly1 = dx1; + float cross = dx1*dy0 - dx0*dy1; + float dmx = (dlx0 + dlx1) * 0.5f; + float dmy = (dly0 + dly1) * 0.5f; + float dmr2 = dmx*dmx + dmy*dmy; + bool bevel = dmr2 * MITER_LIMIT*MITER_LIMIT < 1.0f; + if (dmr2 > 1e-6f) + { + const float scale = 1.0f / dmr2; + dmx *= scale; + dmy *= scale; + } + + if (bevel && cross < 0.0f) + { + if (n+2 >= maxOutVerts) + return 0; + float d = (1.0f - (dx0*dx1 + dy0*dy1))*0.5f; + outVerts[n*3+0] = vb[0] + (-dlx0+dx0*d)*offset; + outVerts[n*3+1] = vb[1]; + outVerts[n*3+2] = vb[2] + (-dly0+dy0*d)*offset; + n++; + outVerts[n*3+0] = vb[0] + (-dlx1-dx1*d)*offset; + outVerts[n*3+1] = vb[1]; + outVerts[n*3+2] = vb[2] + (-dly1-dy1*d)*offset; + n++; + } + else + { + if (n+1 >= maxOutVerts) + return 0; + outVerts[n*3+0] = vb[0] - dmx*offset; + outVerts[n*3+1] = vb[1]; + outVerts[n*3+2] = vb[2] - dmy*offset; + n++; + } + } + + return n; +} + + +/// @par +/// +/// The value of spacial parameters are in world units. +/// +/// @see rcCompactHeightfield, rcMedianFilterWalkableArea +void rcMarkCylinderArea(rcContext* ctx, const float* pos, + const float r, const float h, unsigned char areaId, + rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_MARK_CYLINDER_AREA); + + float bmin[3], bmax[3]; + bmin[0] = pos[0] - r; + bmin[1] = pos[1]; + bmin[2] = pos[2] - r; + bmax[0] = pos[0] + r; + bmax[1] = pos[1] + h; + bmax[2] = pos[2] + r; + const float r2 = r*r; + + int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs); + int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch); + int minz = (int)((bmin[2]-chf.bmin[2])/chf.cs); + int maxx = (int)((bmax[0]-chf.bmin[0])/chf.cs); + int maxy = (int)((bmax[1]-chf.bmin[1])/chf.ch); + int maxz = (int)((bmax[2]-chf.bmin[2])/chf.cs); + + if (maxx < 0) return; + if (minx >= chf.width) return; + if (maxz < 0) return; + if (minz >= chf.height) return; + + if (minx < 0) minx = 0; + if (maxx >= chf.width) maxx = chf.width-1; + if (minz < 0) minz = 0; + if (maxz >= chf.height) maxz = chf.height-1; + + + for (int z = minz; z <= maxz; ++z) + { + for (int x = minx; x <= maxx; ++x) + { + const rcCompactCell& c = chf.cells[x+z*chf.width]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + rcCompactSpan& s = chf.spans[i]; + + if (chf.areas[i] == RC_NULL_AREA) + continue; + + if ((int)s.y >= miny && (int)s.y <= maxy) + { + const float sx = chf.bmin[0] + (x+0.5f)*chf.cs; + const float sz = chf.bmin[2] + (z+0.5f)*chf.cs; + const float dx = sx - pos[0]; + const float dz = sz - pos[2]; + + if (dx*dx + dz*dz < r2) + { + chf.areas[i] = areaId; + } + } + } + } + } +} diff --git a/libs/recast/recast/src/RecastAssert.cpp b/libs/recast/recast/src/RecastAssert.cpp new file mode 100644 index 000000000..6297d4202 --- /dev/null +++ b/libs/recast/recast/src/RecastAssert.cpp @@ -0,0 +1,35 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include "RecastAssert.h" + +#ifndef NDEBUG + +static rcAssertFailFunc* sRecastAssertFailFunc = 0; + +void rcAssertFailSetCustom(rcAssertFailFunc *assertFailFunc) +{ + sRecastAssertFailFunc = assertFailFunc; +} + +rcAssertFailFunc* rcAssertFailGetCustom() +{ + return sRecastAssertFailFunc; +} + +#endif diff --git a/libs/recast/recast/src/RecastContour.cpp b/libs/recast/recast/src/RecastContour.cpp new file mode 100644 index 000000000..277ab0150 --- /dev/null +++ b/libs/recast/recast/src/RecastContour.cpp @@ -0,0 +1,1105 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + + +static int getCornerHeight(int x, int y, int i, int dir, + const rcCompactHeightfield& chf, + bool& isBorderVertex) +{ + const rcCompactSpan& s = chf.spans[i]; + int ch = (int)s.y; + int dirp = (dir+1) & 0x3; + + unsigned int regs[4] = {0,0,0,0}; + + // Combine region and area codes in order to prevent + // border vertices which are in between two areas to be removed. + regs[0] = chf.spans[i].reg | (chf.areas[i] << 16); + + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir); + const rcCompactSpan& as = chf.spans[ai]; + ch = rcMax(ch, (int)as.y); + regs[1] = chf.spans[ai].reg | (chf.areas[ai] << 16); + if (rcGetCon(as, dirp) != RC_NOT_CONNECTED) + { + const int ax2 = ax + rcGetDirOffsetX(dirp); + const int ay2 = ay + rcGetDirOffsetY(dirp); + const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dirp); + const rcCompactSpan& as2 = chf.spans[ai2]; + ch = rcMax(ch, (int)as2.y); + regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16); + } + } + if (rcGetCon(s, dirp) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dirp); + const int ay = y + rcGetDirOffsetY(dirp); + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dirp); + const rcCompactSpan& as = chf.spans[ai]; + ch = rcMax(ch, (int)as.y); + regs[3] = chf.spans[ai].reg | (chf.areas[ai] << 16); + if (rcGetCon(as, dir) != RC_NOT_CONNECTED) + { + const int ax2 = ax + rcGetDirOffsetX(dir); + const int ay2 = ay + rcGetDirOffsetY(dir); + const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dir); + const rcCompactSpan& as2 = chf.spans[ai2]; + ch = rcMax(ch, (int)as2.y); + regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16); + } + } + + // Check if the vertex is special edge vertex, these vertices will be removed later. + for (int j = 0; j < 4; ++j) + { + const int a = j; + const int b = (j+1) & 0x3; + const int c = (j+2) & 0x3; + const int d = (j+3) & 0x3; + + // The vertex is a border vertex there are two same exterior cells in a row, + // followed by two interior cells and none of the regions are out of bounds. + const bool twoSameExts = (regs[a] & regs[b] & RC_BORDER_REG) != 0 && regs[a] == regs[b]; + const bool twoInts = ((regs[c] | regs[d]) & RC_BORDER_REG) == 0; + const bool intsSameArea = (regs[c]>>16) == (regs[d]>>16); + const bool noZeros = regs[a] != 0 && regs[b] != 0 && regs[c] != 0 && regs[d] != 0; + if (twoSameExts && twoInts && intsSameArea && noZeros) + { + isBorderVertex = true; + break; + } + } + + return ch; +} + +static void walkContour(int x, int y, int i, + rcCompactHeightfield& chf, + unsigned char* flags, rcIntArray& points) +{ + // Choose the first non-connected edge + unsigned char dir = 0; + while ((flags[i] & (1 << dir)) == 0) + dir++; + + unsigned char startDir = dir; + int starti = i; + + const unsigned char area = chf.areas[i]; + + int iter = 0; + while (++iter < 40000) + { + if (flags[i] & (1 << dir)) + { + // Choose the edge corner + bool isBorderVertex = false; + bool isAreaBorder = false; + int px = x; + int py = getCornerHeight(x, y, i, dir, chf, isBorderVertex); + int pz = y; + switch(dir) + { + case 0: pz++; break; + case 1: px++; pz++; break; + case 2: px++; break; + } + int r = 0; + const rcCompactSpan& s = chf.spans[i]; + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir); + r = (int)chf.spans[ai].reg; + if (area != chf.areas[ai]) + isAreaBorder = true; + } + if (isBorderVertex) + r |= RC_BORDER_VERTEX; + if (isAreaBorder) + r |= RC_AREA_BORDER; + points.push(px); + points.push(py); + points.push(pz); + points.push(r); + + flags[i] &= ~(1 << dir); // Remove visited edges + dir = (dir+1) & 0x3; // Rotate CW + } + else + { + int ni = -1; + const int nx = x + rcGetDirOffsetX(dir); + const int ny = y + rcGetDirOffsetY(dir); + const rcCompactSpan& s = chf.spans[i]; + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const rcCompactCell& nc = chf.cells[nx+ny*chf.width]; + ni = (int)nc.index + rcGetCon(s, dir); + } + if (ni == -1) + { + // Should not happen. + return; + } + x = nx; + y = ny; + i = ni; + dir = (dir+3) & 0x3; // Rotate CCW + } + + if (starti == i && startDir == dir) + { + break; + } + } +} + +static float distancePtSeg(const int x, const int z, + const int px, const int pz, + const int qx, const int qz) +{ + float pqx = (float)(qx - px); + float pqz = (float)(qz - pz); + float dx = (float)(x - px); + float dz = (float)(z - pz); + float d = pqx*pqx + pqz*pqz; + float t = pqx*dx + pqz*dz; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + + dx = px + t*pqx - x; + dz = pz + t*pqz - z; + + return dx*dx + dz*dz; +} + +static void simplifyContour(rcIntArray& points, rcIntArray& simplified, + const float maxError, const int maxEdgeLen, const int buildFlags) +{ + // Add initial points. + bool hasConnections = false; + for (int i = 0; i < points.size(); i += 4) + { + if ((points[i+3] & RC_CONTOUR_REG_MASK) != 0) + { + hasConnections = true; + break; + } + } + + if (hasConnections) + { + // The contour has some portals to other regions. + // Add a new point to every location where the region changes. + for (int i = 0, ni = points.size()/4; i < ni; ++i) + { + int ii = (i+1) % ni; + const bool differentRegs = (points[i*4+3] & RC_CONTOUR_REG_MASK) != (points[ii*4+3] & RC_CONTOUR_REG_MASK); + const bool areaBorders = (points[i*4+3] & RC_AREA_BORDER) != (points[ii*4+3] & RC_AREA_BORDER); + if (differentRegs || areaBorders) + { + simplified.push(points[i*4+0]); + simplified.push(points[i*4+1]); + simplified.push(points[i*4+2]); + simplified.push(i); + } + } + } + + if (simplified.size() == 0) + { + // If there is no connections at all, + // create some initial points for the simplification process. + // Find lower-left and upper-right vertices of the contour. + int llx = points[0]; + int lly = points[1]; + int llz = points[2]; + int lli = 0; + int urx = points[0]; + int ury = points[1]; + int urz = points[2]; + int uri = 0; + for (int i = 0; i < points.size(); i += 4) + { + int x = points[i+0]; + int y = points[i+1]; + int z = points[i+2]; + if (x < llx || (x == llx && z < llz)) + { + llx = x; + lly = y; + llz = z; + lli = i/4; + } + if (x > urx || (x == urx && z > urz)) + { + urx = x; + ury = y; + urz = z; + uri = i/4; + } + } + simplified.push(llx); + simplified.push(lly); + simplified.push(llz); + simplified.push(lli); + + simplified.push(urx); + simplified.push(ury); + simplified.push(urz); + simplified.push(uri); + } + + // Add points until all raw points are within + // error tolerance to the simplified shape. + const int pn = points.size()/4; + for (int i = 0; i < simplified.size()/4; ) + { + int ii = (i+1) % (simplified.size()/4); + + int ax = simplified[i*4+0]; + int az = simplified[i*4+2]; + int ai = simplified[i*4+3]; + + int bx = simplified[ii*4+0]; + int bz = simplified[ii*4+2]; + int bi = simplified[ii*4+3]; + + // Find maximum deviation from the segment. + float maxd = 0; + int maxi = -1; + int ci, cinc, endi; + + // Traverse the segment in lexilogical order so that the + // max deviation is calculated similarly when traversing + // opposite segments. + if (bx > ax || (bx == ax && bz > az)) + { + cinc = 1; + ci = (ai+cinc) % pn; + endi = bi; + } + else + { + cinc = pn-1; + ci = (bi+cinc) % pn; + endi = ai; + rcSwap(ax, bx); + rcSwap(az, bz); + } + + // Tessellate only outer edges or edges between areas. + if ((points[ci*4+3] & RC_CONTOUR_REG_MASK) == 0 || + (points[ci*4+3] & RC_AREA_BORDER)) + { + while (ci != endi) + { + float d = distancePtSeg(points[ci*4+0], points[ci*4+2], ax, az, bx, bz); + if (d > maxd) + { + maxd = d; + maxi = ci; + } + ci = (ci+cinc) % pn; + } + } + + + // If the max deviation is larger than accepted error, + // add new point, else continue to next segment. + if (maxi != -1 && maxd > (maxError*maxError)) + { + // Add space for the new point. + simplified.resize(simplified.size()+4); + const int n = simplified.size()/4; + for (int j = n-1; j > i; --j) + { + simplified[j*4+0] = simplified[(j-1)*4+0]; + simplified[j*4+1] = simplified[(j-1)*4+1]; + simplified[j*4+2] = simplified[(j-1)*4+2]; + simplified[j*4+3] = simplified[(j-1)*4+3]; + } + // Add the point. + simplified[(i+1)*4+0] = points[maxi*4+0]; + simplified[(i+1)*4+1] = points[maxi*4+1]; + simplified[(i+1)*4+2] = points[maxi*4+2]; + simplified[(i+1)*4+3] = maxi; + } + else + { + ++i; + } + } + + // Split too long edges. + if (maxEdgeLen > 0 && (buildFlags & (RC_CONTOUR_TESS_WALL_EDGES|RC_CONTOUR_TESS_AREA_EDGES)) != 0) + { + for (int i = 0; i < simplified.size()/4; ) + { + const int ii = (i+1) % (simplified.size()/4); + + const int ax = simplified[i*4+0]; + const int az = simplified[i*4+2]; + const int ai = simplified[i*4+3]; + + const int bx = simplified[ii*4+0]; + const int bz = simplified[ii*4+2]; + const int bi = simplified[ii*4+3]; + + // Find maximum deviation from the segment. + int maxi = -1; + int ci = (ai+1) % pn; + + // Tessellate only outer edges or edges between areas. + bool tess = false; + // Wall edges. + if ((buildFlags & RC_CONTOUR_TESS_WALL_EDGES) && (points[ci*4+3] & RC_CONTOUR_REG_MASK) == 0) + tess = true; + // Edges between areas. + if ((buildFlags & RC_CONTOUR_TESS_AREA_EDGES) && (points[ci*4+3] & RC_AREA_BORDER)) + tess = true; + + if (tess) + { + int dx = bx - ax; + int dz = bz - az; + if (dx*dx + dz*dz > maxEdgeLen*maxEdgeLen) + { + // Round based on the segments in lexilogical order so that the + // max tesselation is consistent regardles in which direction + // segments are traversed. + const int n = bi < ai ? (bi+pn - ai) : (bi - ai); + if (n > 1) + { + if (bx > ax || (bx == ax && bz > az)) + maxi = (ai + n/2) % pn; + else + maxi = (ai + (n+1)/2) % pn; + } + } + } + + // If the max deviation is larger than accepted error, + // add new point, else continue to next segment. + if (maxi != -1) + { + // Add space for the new point. + simplified.resize(simplified.size()+4); + const int n = simplified.size()/4; + for (int j = n-1; j > i; --j) + { + simplified[j*4+0] = simplified[(j-1)*4+0]; + simplified[j*4+1] = simplified[(j-1)*4+1]; + simplified[j*4+2] = simplified[(j-1)*4+2]; + simplified[j*4+3] = simplified[(j-1)*4+3]; + } + // Add the point. + simplified[(i+1)*4+0] = points[maxi*4+0]; + simplified[(i+1)*4+1] = points[maxi*4+1]; + simplified[(i+1)*4+2] = points[maxi*4+2]; + simplified[(i+1)*4+3] = maxi; + } + else + { + ++i; + } + } + } + + for (int i = 0; i < simplified.size()/4; ++i) + { + // The edge vertex flag is take from the current raw point, + // and the neighbour region is take from the next raw point. + const int ai = (simplified[i*4+3]+1) % pn; + const int bi = simplified[i*4+3]; + simplified[i*4+3] = (points[ai*4+3] & (RC_CONTOUR_REG_MASK|RC_AREA_BORDER)) | (points[bi*4+3] & RC_BORDER_VERTEX); + } + +} + +static int calcAreaOfPolygon2D(const int* verts, const int nverts) +{ + int area = 0; + for (int i = 0, j = nverts-1; i < nverts; j=i++) + { + const int* vi = &verts[i*4]; + const int* vj = &verts[j*4]; + area += vi[0] * vj[2] - vj[0] * vi[2]; + } + return (area+1) / 2; +} + +// TODO: these are the same as in RecastMesh.cpp, consider using the same. +// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv). +inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; } +inline int next(int i, int n) { return i+1 < n ? i+1 : 0; } + +inline int area2(const int* a, const int* b, const int* c) +{ + return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); +} + +// Exclusive or: true iff exactly one argument is true. +// The arguments are negated to ensure that they are 0/1 +// values. Then the bitwise Xor operator may apply. +// (This idea is due to Michael Baldwin.) +inline bool xorb(bool x, bool y) +{ + return !x ^ !y; +} + +// Returns true iff c is strictly to the left of the directed +// line through a to b. +inline bool left(const int* a, const int* b, const int* c) +{ + return area2(a, b, c) < 0; +} + +inline bool leftOn(const int* a, const int* b, const int* c) +{ + return area2(a, b, c) <= 0; +} + +inline bool collinear(const int* a, const int* b, const int* c) +{ + return area2(a, b, c) == 0; +} + +// Returns true iff ab properly intersects cd: they share +// a point interior to both segments. The properness of the +// intersection is ensured by using strict leftness. +static bool intersectProp(const int* a, const int* b, const int* c, const int* d) +{ + // Eliminate improper cases. + if (collinear(a,b,c) || collinear(a,b,d) || + collinear(c,d,a) || collinear(c,d,b)) + return false; + + return xorb(left(a,b,c), left(a,b,d)) && xorb(left(c,d,a), left(c,d,b)); +} + +// Returns T iff (a,b,c) are collinear and point c lies +// on the closed segement ab. +static bool between(const int* a, const int* b, const int* c) +{ + if (!collinear(a, b, c)) + return false; + // If ab not vertical, check betweenness on x; else on y. + if (a[0] != b[0]) + return ((a[0] <= c[0]) && (c[0] <= b[0])) || ((a[0] >= c[0]) && (c[0] >= b[0])); + else + return ((a[2] <= c[2]) && (c[2] <= b[2])) || ((a[2] >= c[2]) && (c[2] >= b[2])); +} + +// Returns true iff segments ab and cd intersect, properly or improperly. +static bool intersect(const int* a, const int* b, const int* c, const int* d) +{ + if (intersectProp(a, b, c, d)) + return true; + else if (between(a, b, c) || between(a, b, d) || + between(c, d, a) || between(c, d, b)) + return true; + else + return false; +} + +static bool vequal(const int* a, const int* b) +{ + return a[0] == b[0] && a[2] == b[2]; +} + +static bool intersectSegCountour(const int* d0, const int* d1, int i, int n, const int* verts) +{ + // For each edge (k,k+1) of P + for (int k = 0; k < n; k++) + { + int k1 = next(k, n); + // Skip edges incident to i. + if (i == k || i == k1) + continue; + const int* p0 = &verts[k * 4]; + const int* p1 = &verts[k1 * 4]; + if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1)) + continue; + + if (intersect(d0, d1, p0, p1)) + return true; + } + return false; +} + +static bool inCone(int i, int n, const int* verts, const int* pj) +{ + const int* pi = &verts[i * 4]; + const int* pi1 = &verts[next(i, n) * 4]; + const int* pin1 = &verts[prev(i, n) * 4]; + + // If P[i] is a convex vertex [ i+1 left or on (i-1,i) ]. + if (leftOn(pin1, pi, pi1)) + return left(pi, pj, pin1) && left(pj, pi, pi1); + // Assume (i-1,i,i+1) not collinear. + // else P[i] is reflex. + return !(leftOn(pi, pj, pi1) && leftOn(pj, pi, pin1)); +} + + +static void removeDegenerateSegments(rcIntArray& simplified) +{ + // Remove adjacent vertices which are equal on xz-plane, + // or else the triangulator will get confused. + int npts = simplified.size()/4; + for (int i = 0; i < npts; ++i) + { + int ni = next(i, npts); + + if (vequal(&simplified[i*4], &simplified[ni*4])) + { + // Degenerate segment, remove. + for (int j = i; j < simplified.size()/4-1; ++j) + { + simplified[j*4+0] = simplified[(j+1)*4+0]; + simplified[j*4+1] = simplified[(j+1)*4+1]; + simplified[j*4+2] = simplified[(j+1)*4+2]; + simplified[j*4+3] = simplified[(j+1)*4+3]; + } + simplified.resize(simplified.size()-4); + npts--; + } + } +} + + +static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib) +{ + const int maxVerts = ca.nverts + cb.nverts + 2; + int* verts = (int*)rcAlloc(sizeof(int)*maxVerts*4, RC_ALLOC_PERM); + if (!verts) + return false; + + int nv = 0; + + // Copy contour A. + for (int i = 0; i <= ca.nverts; ++i) + { + int* dst = &verts[nv*4]; + const int* src = &ca.verts[((ia+i)%ca.nverts)*4]; + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + nv++; + } + + // Copy contour B + for (int i = 0; i <= cb.nverts; ++i) + { + int* dst = &verts[nv*4]; + const int* src = &cb.verts[((ib+i)%cb.nverts)*4]; + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + nv++; + } + + rcFree(ca.verts); + ca.verts = verts; + ca.nverts = nv; + + rcFree(cb.verts); + cb.verts = 0; + cb.nverts = 0; + + return true; +} + +struct rcContourHole +{ + rcContour* contour; + int minx, minz, leftmost; +}; + +struct rcContourRegion +{ + rcContour* outline; + rcContourHole* holes; + int nholes; +}; + +struct rcPotentialDiagonal +{ + int vert; + int dist; +}; + +// Finds the lowest leftmost vertex of a contour. +static void findLeftMostVertex(rcContour* contour, int* minx, int* minz, int* leftmost) +{ + *minx = contour->verts[0]; + *minz = contour->verts[2]; + *leftmost = 0; + for (int i = 1; i < contour->nverts; i++) + { + const int x = contour->verts[i*4+0]; + const int z = contour->verts[i*4+2]; + if (x < *minx || (x == *minx && z < *minz)) + { + *minx = x; + *minz = z; + *leftmost = i; + } + } +} + +static int compareHoles(const void* va, const void* vb) +{ + const rcContourHole* a = (const rcContourHole*)va; + const rcContourHole* b = (const rcContourHole*)vb; + if (a->minx == b->minx) + { + if (a->minz < b->minz) + return -1; + if (a->minz > b->minz) + return 1; + } + else + { + if (a->minx < b->minx) + return -1; + if (a->minx > b->minx) + return 1; + } + return 0; +} + + +static int compareDiagDist(const void* va, const void* vb) +{ + const rcPotentialDiagonal* a = (const rcPotentialDiagonal*)va; + const rcPotentialDiagonal* b = (const rcPotentialDiagonal*)vb; + if (a->dist < b->dist) + return -1; + if (a->dist > b->dist) + return 1; + return 0; +} + + +static void mergeRegionHoles(rcContext* ctx, rcContourRegion& region) +{ + // Sort holes from left to right. + for (int i = 0; i < region.nholes; i++) + findLeftMostVertex(region.holes[i].contour, ®ion.holes[i].minx, ®ion.holes[i].minz, ®ion.holes[i].leftmost); + + qsort(region.holes, region.nholes, sizeof(rcContourHole), compareHoles); + + int maxVerts = region.outline->nverts; + for (int i = 0; i < region.nholes; i++) + maxVerts += region.holes[i].contour->nverts; + + rcScopedDelete diags((rcPotentialDiagonal*)rcAlloc(sizeof(rcPotentialDiagonal)*maxVerts, RC_ALLOC_TEMP)); + if (!diags) + { + ctx->log(RC_LOG_WARNING, "mergeRegionHoles: Failed to allocated diags %d.", maxVerts); + return; + } + + rcContour* outline = region.outline; + + // Merge holes into the outline one by one. + for (int i = 0; i < region.nholes; i++) + { + rcContour* hole = region.holes[i].contour; + + int index = -1; + int bestVertex = region.holes[i].leftmost; + for (int iter = 0; iter < hole->nverts; iter++) + { + // Find potential diagonals. + // The 'best' vertex must be in the cone described by 3 cosequtive vertices of the outline. + // ..o j-1 + // | + // | * best + // | + // j o-----o j+1 + // : + int ndiags = 0; + const int* corner = &hole->verts[bestVertex*4]; + for (int j = 0; j < outline->nverts; j++) + { + if (inCone(j, outline->nverts, outline->verts, corner)) + { + int dx = outline->verts[j*4+0] - corner[0]; + int dz = outline->verts[j*4+2] - corner[2]; + diags[ndiags].vert = j; + diags[ndiags].dist = dx*dx + dz*dz; + ndiags++; + } + } + // Sort potential diagonals by distance, we want to make the connection as short as possible. + qsort(diags, ndiags, sizeof(rcPotentialDiagonal), compareDiagDist); + + // Find a diagonal that is not intersecting the outline not the remaining holes. + index = -1; + for (int j = 0; j < ndiags; j++) + { + const int* pt = &outline->verts[diags[j].vert*4]; + bool intersect = intersectSegCountour(pt, corner, diags[i].vert, outline->nverts, outline->verts); + for (int k = i; k < region.nholes && !intersect; k++) + intersect |= intersectSegCountour(pt, corner, -1, region.holes[k].contour->nverts, region.holes[k].contour->verts); + if (!intersect) + { + index = diags[j].vert; + break; + } + } + // If found non-intersecting diagonal, stop looking. + if (index != -1) + break; + // All the potential diagonals for the current vertex were intersecting, try next vertex. + bestVertex = (bestVertex + 1) % hole->nverts; + } + + if (index == -1) + { + ctx->log(RC_LOG_WARNING, "mergeHoles: Failed to find merge points for %p and %p.", region.outline, hole); + continue; + } + if (!mergeContours(*region.outline, *hole, index, bestVertex)) + { + ctx->log(RC_LOG_WARNING, "mergeHoles: Failed to merge contours %p and %p.", region.outline, hole); + continue; + } + } +} + + +/// @par +/// +/// The raw contours will match the region outlines exactly. The @p maxError and @p maxEdgeLen +/// parameters control how closely the simplified contours will match the raw contours. +/// +/// Simplified contours are generated such that the vertices for portals between areas match up. +/// (They are considered mandatory vertices.) +/// +/// Setting @p maxEdgeLength to zero will disabled the edge length feature. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocContourSet, rcCompactHeightfield, rcContourSet, rcConfig +bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf, + const float maxError, const int maxEdgeLen, + rcContourSet& cset, const int buildFlags) +{ + rcAssert(ctx); + + const int w = chf.width; + const int h = chf.height; + const int borderSize = chf.borderSize; + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_CONTOURS); + + rcVcopy(cset.bmin, chf.bmin); + rcVcopy(cset.bmax, chf.bmax); + if (borderSize > 0) + { + // If the heightfield was build with bordersize, remove the offset. + const float pad = borderSize*chf.cs; + cset.bmin[0] += pad; + cset.bmin[2] += pad; + cset.bmax[0] -= pad; + cset.bmax[2] -= pad; + } + cset.cs = chf.cs; + cset.ch = chf.ch; + cset.width = chf.width - chf.borderSize*2; + cset.height = chf.height - chf.borderSize*2; + cset.borderSize = chf.borderSize; + cset.maxError = maxError; + + int maxContours = rcMax((int)chf.maxRegions, 8); + cset.conts = (rcContour*)rcAlloc(sizeof(rcContour)*maxContours, RC_ALLOC_PERM); + if (!cset.conts) + return false; + cset.nconts = 0; + + rcScopedDelete flags((unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP)); + if (!flags) + { + ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'flags' (%d).", chf.spanCount); + return false; + } + + ctx->startTimer(RC_TIMER_BUILD_CONTOURS_TRACE); + + // Mark boundaries. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + unsigned char res = 0; + const rcCompactSpan& s = chf.spans[i]; + if (!chf.spans[i].reg || (chf.spans[i].reg & RC_BORDER_REG)) + { + flags[i] = 0; + continue; + } + for (int dir = 0; dir < 4; ++dir) + { + unsigned short r = 0; + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + r = chf.spans[ai].reg; + } + if (r == chf.spans[i].reg) + res |= (1 << dir); + } + flags[i] = res ^ 0xf; // Inverse, mark non connected edges. + } + } + } + + ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_TRACE); + + rcIntArray verts(256); + rcIntArray simplified(64); + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (flags[i] == 0 || flags[i] == 0xf) + { + flags[i] = 0; + continue; + } + const unsigned short reg = chf.spans[i].reg; + if (!reg || (reg & RC_BORDER_REG)) + continue; + const unsigned char area = chf.areas[i]; + + verts.resize(0); + simplified.resize(0); + + ctx->startTimer(RC_TIMER_BUILD_CONTOURS_TRACE); + walkContour(x, y, i, chf, flags, verts); + ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_TRACE); + + ctx->startTimer(RC_TIMER_BUILD_CONTOURS_SIMPLIFY); + simplifyContour(verts, simplified, maxError, maxEdgeLen, buildFlags); + removeDegenerateSegments(simplified); + ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_SIMPLIFY); + + + // Store region->contour remap info. + // Create contour. + if (simplified.size()/4 >= 3) + { + if (cset.nconts >= maxContours) + { + // Allocate more contours. + // This happens when a region has holes. + const int oldMax = maxContours; + maxContours *= 2; + rcContour* newConts = (rcContour*)rcAlloc(sizeof(rcContour)*maxContours, RC_ALLOC_PERM); + for (int j = 0; j < cset.nconts; ++j) + { + newConts[j] = cset.conts[j]; + // Reset source pointers to prevent data deletion. + cset.conts[j].verts = 0; + cset.conts[j].rverts = 0; + } + rcFree(cset.conts); + cset.conts = newConts; + + ctx->log(RC_LOG_WARNING, "rcBuildContours: Expanding max contours from %d to %d.", oldMax, maxContours); + } + + rcContour* cont = &cset.conts[cset.nconts++]; + + cont->nverts = simplified.size()/4; + cont->verts = (int*)rcAlloc(sizeof(int)*cont->nverts*4, RC_ALLOC_PERM); + if (!cont->verts) + { + ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'verts' (%d).", cont->nverts); + return false; + } + memcpy(cont->verts, &simplified[0], sizeof(int)*cont->nverts*4); + if (borderSize > 0) + { + // If the heightfield was build with bordersize, remove the offset. + for (int j = 0; j < cont->nverts; ++j) + { + int* v = &cont->verts[j*4]; + v[0] -= borderSize; + v[2] -= borderSize; + } + } + + cont->nrverts = verts.size()/4; + cont->rverts = (int*)rcAlloc(sizeof(int)*cont->nrverts*4, RC_ALLOC_PERM); + if (!cont->rverts) + { + ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'rverts' (%d).", cont->nrverts); + return false; + } + memcpy(cont->rverts, &verts[0], sizeof(int)*cont->nrverts*4); + if (borderSize > 0) + { + // If the heightfield was build with bordersize, remove the offset. + for (int j = 0; j < cont->nrverts; ++j) + { + int* v = &cont->rverts[j*4]; + v[0] -= borderSize; + v[2] -= borderSize; + } + } + + cont->reg = reg; + cont->area = area; + } + } + } + } + + // Merge holes if needed. + if (cset.nconts > 0) + { + // Calculate winding of all polygons. + rcScopedDelete winding((char*)rcAlloc(sizeof(char)*cset.nconts, RC_ALLOC_TEMP)); + if (!winding) + { + ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'hole' (%d).", cset.nconts); + return false; + } + int nholes = 0; + for (int i = 0; i < cset.nconts; ++i) + { + rcContour& cont = cset.conts[i]; + // If the contour is wound backwards, it is a hole. + winding[i] = calcAreaOfPolygon2D(cont.verts, cont.nverts) < 0 ? -1 : 1; + if (winding[i] < 0) + nholes++; + } + + if (nholes > 0) + { + // Collect outline contour and holes contours per region. + // We assume that there is one outline and multiple holes. + const int nregions = chf.maxRegions+1; + rcScopedDelete regions((rcContourRegion*)rcAlloc(sizeof(rcContourRegion)*nregions, RC_ALLOC_TEMP)); + if (!regions) + { + ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'regions' (%d).", nregions); + return false; + } + memset(regions, 0, sizeof(rcContourRegion)*nregions); + + rcScopedDelete holes((rcContourHole*)rcAlloc(sizeof(rcContourHole)*cset.nconts, RC_ALLOC_TEMP)); + if (!holes) + { + ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'holes' (%d).", cset.nconts); + return false; + } + memset(holes, 0, sizeof(rcContourHole)*cset.nconts); + + for (int i = 0; i < cset.nconts; ++i) + { + rcContour& cont = cset.conts[i]; + // Positively would contours are outlines, negative holes. + if (winding[i] > 0) + { + if (regions[cont.reg].outline) + ctx->log(RC_LOG_ERROR, "rcBuildContours: Multiple outlines for region %d.", cont.reg); + regions[cont.reg].outline = &cont; + } + else + { + regions[cont.reg].nholes++; + } + } + int index = 0; + for (int i = 0; i < nregions; i++) + { + if (regions[i].nholes > 0) + { + regions[i].holes = &holes[index]; + index += regions[i].nholes; + regions[i].nholes = 0; + } + } + for (int i = 0; i < cset.nconts; ++i) + { + rcContour& cont = cset.conts[i]; + rcContourRegion& reg = regions[cont.reg]; + if (winding[i] < 0) + reg.holes[reg.nholes++].contour = &cont; + } + + // Finally merge each regions holes into the outline. + for (int i = 0; i < nregions; i++) + { + rcContourRegion& reg = regions[i]; + if (!reg.nholes) continue; + + if (reg.outline) + { + mergeRegionHoles(ctx, reg); + } + else + { + // The region does not have an outline. + // This can happen if the contour becaomes selfoverlapping because of + // too aggressive simplification settings. + ctx->log(RC_LOG_ERROR, "rcBuildContours: Bad outline for region %d, contour simplification is likely too aggressive.", i); + } + } + } + + } + + return true; +} diff --git a/libs/recast/recast/src/RecastFilter.cpp b/libs/recast/recast/src/RecastFilter.cpp new file mode 100644 index 000000000..9d3e63c48 --- /dev/null +++ b/libs/recast/recast/src/RecastFilter.cpp @@ -0,0 +1,202 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include +#include "Recast.h" +#include "RecastAssert.h" + +/// @par +/// +/// Allows the formation of walkable regions that will flow over low lying +/// objects such as curbs, and up structures such as stairways. +/// +/// Two neighboring spans are walkable if: rcAbs(currentSpan.smax - neighborSpan.smax) < waklableClimb +/// +/// @warning Will override the effect of #rcFilterLedgeSpans. So if both filters are used, call +/// #rcFilterLedgeSpans after calling this filter. +/// +/// @see rcHeightfield, rcConfig +void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_FILTER_LOW_OBSTACLES); + + const int w = solid.width; + const int h = solid.height; + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + rcSpan* ps = 0; + bool previousWalkable = false; + unsigned char previousArea = RC_NULL_AREA; + + for (rcSpan* s = solid.spans[x + y*w]; s; ps = s, s = s->next) + { + const bool walkable = s->area != RC_NULL_AREA; + // If current span is not walkable, but there is walkable + // span just below it, mark the span above it walkable too. + if (!walkable && previousWalkable) + { + if (rcAbs((int)s->smax - (int)ps->smax) <= walkableClimb) + s->area = previousArea; + } + // Copy walkable flag so that it cannot propagate + // past multiple non-walkable objects. + previousWalkable = walkable; + previousArea = s->area; + } + } + } +} + +/// @par +/// +/// A ledge is a span with one or more neighbors whose maximum is further away than @p walkableClimb +/// from the current span's maximum. +/// This method removes the impact of the overestimation of conservative voxelization +/// so the resulting mesh will not have regions hanging in the air over ledges. +/// +/// A span is a ledge if: rcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb +/// +/// @see rcHeightfield, rcConfig +void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walkableClimb, + rcHeightfield& solid) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_FILTER_BORDER); + + const int w = solid.width; + const int h = solid.height; + const int MAX_HEIGHT = 0xffff; + + // Mark border spans. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next) + { + // Skip non walkable spans. + if (s->area == RC_NULL_AREA) + continue; + + const int bot = (int)(s->smax); + const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT; + + // Find neighbours minimum height. + int minh = MAX_HEIGHT; + + // Min and max height of accessible neighbours. + int asmin = s->smax; + int asmax = s->smax; + + for (int dir = 0; dir < 4; ++dir) + { + int dx = x + rcGetDirOffsetX(dir); + int dy = y + rcGetDirOffsetY(dir); + // Skip neighbours which are out of bounds. + if (dx < 0 || dy < 0 || dx >= w || dy >= h) + { + minh = rcMin(minh, -walkableClimb - bot); + continue; + } + + // From minus infinity to the first span. + rcSpan* ns = solid.spans[dx + dy*w]; + int nbot = -walkableClimb; + int ntop = ns ? (int)ns->smin : MAX_HEIGHT; + // Skip neightbour if the gap between the spans is too small. + if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight) + minh = rcMin(minh, nbot - bot); + + // Rest of the spans. + for (ns = solid.spans[dx + dy*w]; ns; ns = ns->next) + { + nbot = (int)ns->smax; + ntop = ns->next ? (int)ns->next->smin : MAX_HEIGHT; + // Skip neightbour if the gap between the spans is too small. + if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight) + { + minh = rcMin(minh, nbot - bot); + + // Find min/max accessible neighbour height. + if (rcAbs(nbot - bot) <= walkableClimb) + { + if (nbot < asmin) asmin = nbot; + if (nbot > asmax) asmax = nbot; + } + + } + } + } + + // The current span is close to a ledge if the drop to any + // neighbour span is less than the walkableClimb. + if (minh < -walkableClimb) + { + s->area = RC_NULL_AREA; + } + // If the difference between all neighbours is too large, + // we are at steep slope, mark the span as ledge. + else if ((asmax - asmin) > walkableClimb) + { + s->area = RC_NULL_AREA; + } + } + } + } +} + +/// @par +/// +/// For this filter, the clearance above the span is the distance from the span's +/// maximum to the next higher span's minimum. (Same grid column.) +/// +/// @see rcHeightfield, rcConfig +void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_FILTER_WALKABLE); + + const int w = solid.width; + const int h = solid.height; + const int MAX_HEIGHT = 0xffff; + + // Remove walkable flag from spans which do not have enough + // space above them for the agent to stand there. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next) + { + const int bot = (int)(s->smax); + const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT; + if ((top - bot) <= walkableHeight) + s->area = RC_NULL_AREA; + } + } + } +} diff --git a/libs/recast/recast/src/RecastLayers.cpp b/libs/recast/recast/src/RecastLayers.cpp new file mode 100644 index 000000000..acc97e44f --- /dev/null +++ b/libs/recast/recast/src/RecastLayers.cpp @@ -0,0 +1,644 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + + +// Must be 255 or smaller (not 256) because layer IDs are stored as +// a byte where 255 is a special value. +static const int RC_MAX_LAYERS = 63; +static const int RC_MAX_NEIS = 16; + +struct rcLayerRegion +{ + unsigned char layers[RC_MAX_LAYERS]; + unsigned char neis[RC_MAX_NEIS]; + unsigned short ymin, ymax; + unsigned char layerId; // Layer ID + unsigned char nlayers; // Layer count + unsigned char nneis; // Neighbour count + unsigned char base; // Flag indicating if the region is the base of merged regions. +}; + + +static bool contains(const unsigned char* a, const unsigned char an, const unsigned char v) +{ + const int n = (int)an; + for (int i = 0; i < n; ++i) + { + if (a[i] == v) + return true; + } + return false; +} + +static bool addUnique(unsigned char* a, unsigned char& an, int anMax, unsigned char v) +{ + if (contains(a, an, v)) + return true; + + if ((int)an >= anMax) + return false; + + a[an] = v; + an++; + return true; +} + + +inline bool overlapRange(const unsigned short amin, const unsigned short amax, + const unsigned short bmin, const unsigned short bmax) +{ + return (amin > bmax || amax < bmin) ? false : true; +} + + + +struct rcLayerSweepSpan +{ + unsigned short ns; // number samples + unsigned char id; // region id + unsigned char nei; // neighbour id +}; + +/// @par +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocHeightfieldLayerSet, rcCompactHeightfield, rcHeightfieldLayerSet, rcConfig +bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int walkableHeight, + rcHeightfieldLayerSet& lset) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_LAYERS); + + const int w = chf.width; + const int h = chf.height; + + rcScopedDelete srcReg((unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP)); + if (!srcReg) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'srcReg' (%d).", chf.spanCount); + return false; + } + memset(srcReg,0xff,sizeof(unsigned char)*chf.spanCount); + + const int nsweeps = chf.width; + rcScopedDelete sweeps((rcLayerSweepSpan*)rcAlloc(sizeof(rcLayerSweepSpan)*nsweeps, RC_ALLOC_TEMP)); + if (!sweeps) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'sweeps' (%d).", nsweeps); + return false; + } + + + // Partition walkable area into monotone regions. + int prevCount[256]; + unsigned char regId = 0; + + for (int y = borderSize; y < h-borderSize; ++y) + { + memset(prevCount,0,sizeof(int)*regId); + unsigned char sweepId = 0; + + for (int x = borderSize; x < w-borderSize; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + if (chf.areas[i] == RC_NULL_AREA) continue; + + unsigned char sid = 0xff; + + // -x + if (rcGetCon(s, 0) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(0); + const int ay = y + rcGetDirOffsetY(0); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0); + if (chf.areas[ai] != RC_NULL_AREA && srcReg[ai] != 0xff) + sid = srcReg[ai]; + } + + if (sid == 0xff) + { + sid = sweepId++; + sweeps[sid].nei = 0xff; + sweeps[sid].ns = 0; + } + + // -y + if (rcGetCon(s,3) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(3); + const int ay = y + rcGetDirOffsetY(3); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3); + const unsigned char nr = srcReg[ai]; + if (nr != 0xff) + { + // Set neighbour when first valid neighbour is encoutered. + if (sweeps[sid].ns == 0) + sweeps[sid].nei = nr; + + if (sweeps[sid].nei == nr) + { + // Update existing neighbour + sweeps[sid].ns++; + prevCount[nr]++; + } + else + { + // This is hit if there is nore than one neighbour. + // Invalidate the neighbour. + sweeps[sid].nei = 0xff; + } + } + } + + srcReg[i] = sid; + } + } + + // Create unique ID. + for (int i = 0; i < sweepId; ++i) + { + // If the neighbour is set and there is only one continuous connection to it, + // the sweep will be merged with the previous one, else new region is created. + if (sweeps[i].nei != 0xff && prevCount[sweeps[i].nei] == (int)sweeps[i].ns) + { + sweeps[i].id = sweeps[i].nei; + } + else + { + if (regId == 255) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Region ID overflow."); + return false; + } + sweeps[i].id = regId++; + } + } + + // Remap local sweep ids to region ids. + for (int x = borderSize; x < w-borderSize; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (srcReg[i] != 0xff) + srcReg[i] = sweeps[srcReg[i]].id; + } + } + } + + // Allocate and init layer regions. + const int nregs = (int)regId; + rcScopedDelete regs((rcLayerRegion*)rcAlloc(sizeof(rcLayerRegion)*nregs, RC_ALLOC_TEMP)); + if (!regs) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'regs' (%d).", nregs); + return false; + } + memset(regs, 0, sizeof(rcLayerRegion)*nregs); + for (int i = 0; i < nregs; ++i) + { + regs[i].layerId = 0xff; + regs[i].ymin = 0xffff; + regs[i].ymax = 0; + } + + // Find region neighbours and overlapping regions. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + unsigned char lregs[RC_MAX_LAYERS]; + int nlregs = 0; + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + const unsigned char ri = srcReg[i]; + if (ri == 0xff) continue; + + regs[ri].ymin = rcMin(regs[ri].ymin, s.y); + regs[ri].ymax = rcMax(regs[ri].ymax, s.y); + + // Collect all region layers. + if (nlregs < RC_MAX_LAYERS) + lregs[nlregs++] = ri; + + // Update neighbours + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + const unsigned char rai = srcReg[ai]; + if (rai != 0xff && rai != ri) + { + // Don't check return value -- if we cannot add the neighbor + // it will just cause a few more regions to be created, which + // is fine. + addUnique(regs[ri].neis, regs[ri].nneis, RC_MAX_NEIS, rai); + } + } + } + + } + + // Update overlapping regions. + for (int i = 0; i < nlregs-1; ++i) + { + for (int j = i+1; j < nlregs; ++j) + { + if (lregs[i] != lregs[j]) + { + rcLayerRegion& ri = regs[lregs[i]]; + rcLayerRegion& rj = regs[lregs[j]]; + + if (!addUnique(ri.layers, ri.nlayers, RC_MAX_LAYERS, lregs[j]) || + !addUnique(rj.layers, rj.nlayers, RC_MAX_LAYERS, lregs[i])) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: layer overflow (too many overlapping walkable platforms). Try increasing RC_MAX_LAYERS."); + return false; + } + } + } + } + + } + } + + // Create 2D layers from regions. + unsigned char layerId = 0; + + static const int MAX_STACK = 64; + unsigned char stack[MAX_STACK]; + int nstack = 0; + + for (int i = 0; i < nregs; ++i) + { + rcLayerRegion& root = regs[i]; + // Skip already visited. + if (root.layerId != 0xff) + continue; + + // Start search. + root.layerId = layerId; + root.base = 1; + + nstack = 0; + stack[nstack++] = (unsigned char)i; + + while (nstack) + { + // Pop front + rcLayerRegion& reg = regs[stack[0]]; + nstack--; + for (int j = 0; j < nstack; ++j) + stack[j] = stack[j+1]; + + const int nneis = (int)reg.nneis; + for (int j = 0; j < nneis; ++j) + { + const unsigned char nei = reg.neis[j]; + rcLayerRegion& regn = regs[nei]; + // Skip already visited. + if (regn.layerId != 0xff) + continue; + // Skip if the neighbour is overlapping root region. + if (contains(root.layers, root.nlayers, nei)) + continue; + // Skip if the height range would become too large. + const int ymin = rcMin(root.ymin, regn.ymin); + const int ymax = rcMax(root.ymax, regn.ymax); + if ((ymax - ymin) >= 255) + continue; + + if (nstack < MAX_STACK) + { + // Deepen + stack[nstack++] = (unsigned char)nei; + + // Mark layer id + regn.layerId = layerId; + // Merge current layers to root. + for (int k = 0; k < regn.nlayers; ++k) + { + if (!addUnique(root.layers, root.nlayers, RC_MAX_LAYERS, regn.layers[k])) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: layer overflow (too many overlapping walkable platforms). Try increasing RC_MAX_LAYERS."); + return false; + } + } + root.ymin = rcMin(root.ymin, regn.ymin); + root.ymax = rcMax(root.ymax, regn.ymax); + } + } + } + + layerId++; + } + + // Merge non-overlapping regions that are close in height. + const unsigned short mergeHeight = (unsigned short)walkableHeight * 4; + + for (int i = 0; i < nregs; ++i) + { + rcLayerRegion& ri = regs[i]; + if (!ri.base) continue; + + unsigned char newId = ri.layerId; + + for (;;) + { + unsigned char oldId = 0xff; + + for (int j = 0; j < nregs; ++j) + { + if (i == j) continue; + rcLayerRegion& rj = regs[j]; + if (!rj.base) continue; + + // Skip if the regions are not close to each other. + if (!overlapRange(ri.ymin,ri.ymax+mergeHeight, rj.ymin,rj.ymax+mergeHeight)) + continue; + // Skip if the height range would become too large. + const int ymin = rcMin(ri.ymin, rj.ymin); + const int ymax = rcMax(ri.ymax, rj.ymax); + if ((ymax - ymin) >= 255) + continue; + + // Make sure that there is no overlap when merging 'ri' and 'rj'. + bool overlap = false; + // Iterate over all regions which have the same layerId as 'rj' + for (int k = 0; k < nregs; ++k) + { + if (regs[k].layerId != rj.layerId) + continue; + // Check if region 'k' is overlapping region 'ri' + // Index to 'regs' is the same as region id. + if (contains(ri.layers,ri.nlayers, (unsigned char)k)) + { + overlap = true; + break; + } + } + // Cannot merge of regions overlap. + if (overlap) + continue; + + // Can merge i and j. + oldId = rj.layerId; + break; + } + + // Could not find anything to merge with, stop. + if (oldId == 0xff) + break; + + // Merge + for (int j = 0; j < nregs; ++j) + { + rcLayerRegion& rj = regs[j]; + if (rj.layerId == oldId) + { + rj.base = 0; + // Remap layerIds. + rj.layerId = newId; + // Add overlaid layers from 'rj' to 'ri'. + for (int k = 0; k < rj.nlayers; ++k) + { + if (!addUnique(ri.layers, ri.nlayers, RC_MAX_LAYERS, rj.layers[k])) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: layer overflow (too many overlapping walkable platforms). Try increasing RC_MAX_LAYERS."); + return false; + } + } + + // Update height bounds. + ri.ymin = rcMin(ri.ymin, rj.ymin); + ri.ymax = rcMax(ri.ymax, rj.ymax); + } + } + } + } + + // Compact layerIds + unsigned char remap[256]; + memset(remap, 0, 256); + + // Find number of unique layers. + layerId = 0; + for (int i = 0; i < nregs; ++i) + remap[regs[i].layerId] = 1; + for (int i = 0; i < 256; ++i) + { + if (remap[i]) + remap[i] = layerId++; + else + remap[i] = 0xff; + } + // Remap ids. + for (int i = 0; i < nregs; ++i) + regs[i].layerId = remap[regs[i].layerId]; + + // No layers, return empty. + if (layerId == 0) + return true; + + // Create layers. + rcAssert(lset.layers == 0); + + const int lw = w - borderSize*2; + const int lh = h - borderSize*2; + + // Build contracted bbox for layers. + float bmin[3], bmax[3]; + rcVcopy(bmin, chf.bmin); + rcVcopy(bmax, chf.bmax); + bmin[0] += borderSize*chf.cs; + bmin[2] += borderSize*chf.cs; + bmax[0] -= borderSize*chf.cs; + bmax[2] -= borderSize*chf.cs; + + lset.nlayers = (int)layerId; + + lset.layers = (rcHeightfieldLayer*)rcAlloc(sizeof(rcHeightfieldLayer)*lset.nlayers, RC_ALLOC_PERM); + if (!lset.layers) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'layers' (%d).", lset.nlayers); + return false; + } + memset(lset.layers, 0, sizeof(rcHeightfieldLayer)*lset.nlayers); + + + // Store layers. + for (int i = 0; i < lset.nlayers; ++i) + { + unsigned char curId = (unsigned char)i; + + rcHeightfieldLayer* layer = &lset.layers[i]; + + const int gridSize = sizeof(unsigned char)*lw*lh; + + layer->heights = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM); + if (!layer->heights) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'heights' (%d).", gridSize); + return false; + } + memset(layer->heights, 0xff, gridSize); + + layer->areas = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM); + if (!layer->areas) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'areas' (%d).", gridSize); + return false; + } + memset(layer->areas, 0, gridSize); + + layer->cons = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM); + if (!layer->cons) + { + ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'cons' (%d).", gridSize); + return false; + } + memset(layer->cons, 0, gridSize); + + // Find layer height bounds. + int hmin = 0, hmax = 0; + for (int j = 0; j < nregs; ++j) + { + if (regs[j].base && regs[j].layerId == curId) + { + hmin = (int)regs[j].ymin; + hmax = (int)regs[j].ymax; + } + } + + layer->width = lw; + layer->height = lh; + layer->cs = chf.cs; + layer->ch = chf.ch; + + // Adjust the bbox to fit the heightfield. + rcVcopy(layer->bmin, bmin); + rcVcopy(layer->bmax, bmax); + layer->bmin[1] = bmin[1] + hmin*chf.ch; + layer->bmax[1] = bmin[1] + hmax*chf.ch; + layer->hmin = hmin; + layer->hmax = hmax; + + // Update usable data region. + layer->minx = layer->width; + layer->maxx = 0; + layer->miny = layer->height; + layer->maxy = 0; + + // Copy height and area from compact heightfield. + for (int y = 0; y < lh; ++y) + { + for (int x = 0; x < lw; ++x) + { + const int cx = borderSize+x; + const int cy = borderSize+y; + const rcCompactCell& c = chf.cells[cx+cy*w]; + for (int j = (int)c.index, nj = (int)(c.index+c.count); j < nj; ++j) + { + const rcCompactSpan& s = chf.spans[j]; + // Skip unassigned regions. + if (srcReg[j] == 0xff) + continue; + // Skip of does nto belong to current layer. + unsigned char lid = regs[srcReg[j]].layerId; + if (lid != curId) + continue; + + // Update data bounds. + layer->minx = rcMin(layer->minx, x); + layer->maxx = rcMax(layer->maxx, x); + layer->miny = rcMin(layer->miny, y); + layer->maxy = rcMax(layer->maxy, y); + + // Store height and area type. + const int idx = x+y*lw; + layer->heights[idx] = (unsigned char)(s.y - hmin); + layer->areas[idx] = chf.areas[j]; + + // Check connection. + unsigned char portal = 0; + unsigned char con = 0; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = cx + rcGetDirOffsetX(dir); + const int ay = cy + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + unsigned char alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff; + // Portal mask + if (chf.areas[ai] != RC_NULL_AREA && lid != alid) + { + portal |= (unsigned char)(1< hmin) + layer->heights[idx] = rcMax(layer->heights[idx], (unsigned char)(as.y - hmin)); + } + // Valid connection mask + if (chf.areas[ai] != RC_NULL_AREA && lid == alid) + { + const int nx = ax - borderSize; + const int ny = ay - borderSize; + if (nx >= 0 && ny >= 0 && nx < lw && ny < lh) + con |= (unsigned char)(1<cons[idx] = (portal << 4) | con; + } + } + } + + if (layer->minx > layer->maxx) + layer->minx = layer->maxx = 0; + if (layer->miny > layer->maxy) + layer->miny = layer->maxy = 0; + } + + return true; +} diff --git a/libs/recast/recast/src/RecastMesh.cpp b/libs/recast/recast/src/RecastMesh.cpp new file mode 100644 index 000000000..e99eaebb7 --- /dev/null +++ b/libs/recast/recast/src/RecastMesh.cpp @@ -0,0 +1,1552 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + +struct rcEdge +{ + unsigned short vert[2]; + unsigned short polyEdge[2]; + unsigned short poly[2]; +}; + +static bool buildMeshAdjacency(unsigned short* polys, const int npolys, + const int nverts, const int vertsPerPoly) +{ + // Based on code by Eric Lengyel from: + // http://www.terathon.com/code/edges.php + + int maxEdgeCount = npolys*vertsPerPoly; + unsigned short* firstEdge = (unsigned short*)rcAlloc(sizeof(unsigned short)*(nverts + maxEdgeCount), RC_ALLOC_TEMP); + if (!firstEdge) + return false; + unsigned short* nextEdge = firstEdge + nverts; + int edgeCount = 0; + + rcEdge* edges = (rcEdge*)rcAlloc(sizeof(rcEdge)*maxEdgeCount, RC_ALLOC_TEMP); + if (!edges) + { + rcFree(firstEdge); + return false; + } + + for (int i = 0; i < nverts; i++) + firstEdge[i] = RC_MESH_NULL_IDX; + + for (int i = 0; i < npolys; ++i) + { + unsigned short* t = &polys[i*vertsPerPoly*2]; + for (int j = 0; j < vertsPerPoly; ++j) + { + if (t[j] == RC_MESH_NULL_IDX) break; + unsigned short v0 = t[j]; + unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1]; + if (v0 < v1) + { + rcEdge& edge = edges[edgeCount]; + edge.vert[0] = v0; + edge.vert[1] = v1; + edge.poly[0] = (unsigned short)i; + edge.polyEdge[0] = (unsigned short)j; + edge.poly[1] = (unsigned short)i; + edge.polyEdge[1] = 0; + // Insert edge + nextEdge[edgeCount] = firstEdge[v0]; + firstEdge[v0] = (unsigned short)edgeCount; + edgeCount++; + } + } + } + + for (int i = 0; i < npolys; ++i) + { + unsigned short* t = &polys[i*vertsPerPoly*2]; + for (int j = 0; j < vertsPerPoly; ++j) + { + if (t[j] == RC_MESH_NULL_IDX) break; + unsigned short v0 = t[j]; + unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1]; + if (v0 > v1) + { + for (unsigned short e = firstEdge[v1]; e != RC_MESH_NULL_IDX; e = nextEdge[e]) + { + rcEdge& edge = edges[e]; + if (edge.vert[1] == v0 && edge.poly[0] == edge.poly[1]) + { + edge.poly[1] = (unsigned short)i; + edge.polyEdge[1] = (unsigned short)j; + break; + } + } + } + } + } + + // Store adjacency + for (int i = 0; i < edgeCount; ++i) + { + const rcEdge& e = edges[i]; + if (e.poly[0] != e.poly[1]) + { + unsigned short* p0 = &polys[e.poly[0]*vertsPerPoly*2]; + unsigned short* p1 = &polys[e.poly[1]*vertsPerPoly*2]; + p0[vertsPerPoly + e.polyEdge[0]] = e.poly[1]; + p1[vertsPerPoly + e.polyEdge[1]] = e.poly[0]; + } + } + + rcFree(firstEdge); + rcFree(edges); + + return true; +} + + +static const int VERTEX_BUCKET_COUNT = (1<<12); + +inline int computeVertexHash(int x, int y, int z) +{ + const unsigned int h1 = 0x8da6b343; // Large multiplicative constants; + const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes + const unsigned int h3 = 0xcb1ab31f; + unsigned int n = h1 * x + h2 * y + h3 * z; + return (int)(n & (VERTEX_BUCKET_COUNT-1)); +} + +static unsigned short addVertex(unsigned short x, unsigned short y, unsigned short z, + unsigned short* verts, int* firstVert, int* nextVert, int& nv) +{ + int bucket = computeVertexHash(x, 0, z); + int i = firstVert[bucket]; + + while (i != -1) + { + const unsigned short* v = &verts[i*3]; + if (v[0] == x && (rcAbs(v[1] - y) <= 2) && v[2] == z) + return (unsigned short)i; + i = nextVert[i]; // next + } + + // Could not find, create new. + i = nv; nv++; + unsigned short* v = &verts[i*3]; + v[0] = x; + v[1] = y; + v[2] = z; + nextVert[i] = firstVert[bucket]; + firstVert[bucket] = i; + + return (unsigned short)i; +} + +// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv). +inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; } +inline int next(int i, int n) { return i+1 < n ? i+1 : 0; } + +inline int area2(const int* a, const int* b, const int* c) +{ + return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); +} + +// Exclusive or: true iff exactly one argument is true. +// The arguments are negated to ensure that they are 0/1 +// values. Then the bitwise Xor operator may apply. +// (This idea is due to Michael Baldwin.) +inline bool xorb(bool x, bool y) +{ + return !x ^ !y; +} + +// Returns true iff c is strictly to the left of the directed +// line through a to b. +inline bool left(const int* a, const int* b, const int* c) +{ + return area2(a, b, c) < 0; +} + +inline bool leftOn(const int* a, const int* b, const int* c) +{ + return area2(a, b, c) <= 0; +} + +inline bool collinear(const int* a, const int* b, const int* c) +{ + return area2(a, b, c) == 0; +} + +// Returns true iff ab properly intersects cd: they share +// a point interior to both segments. The properness of the +// intersection is ensured by using strict leftness. +static bool intersectProp(const int* a, const int* b, const int* c, const int* d) +{ + // Eliminate improper cases. + if (collinear(a,b,c) || collinear(a,b,d) || + collinear(c,d,a) || collinear(c,d,b)) + return false; + + return xorb(left(a,b,c), left(a,b,d)) && xorb(left(c,d,a), left(c,d,b)); +} + +// Returns T iff (a,b,c) are collinear and point c lies +// on the closed segement ab. +static bool between(const int* a, const int* b, const int* c) +{ + if (!collinear(a, b, c)) + return false; + // If ab not vertical, check betweenness on x; else on y. + if (a[0] != b[0]) + return ((a[0] <= c[0]) && (c[0] <= b[0])) || ((a[0] >= c[0]) && (c[0] >= b[0])); + else + return ((a[2] <= c[2]) && (c[2] <= b[2])) || ((a[2] >= c[2]) && (c[2] >= b[2])); +} + +// Returns true iff segments ab and cd intersect, properly or improperly. +static bool intersect(const int* a, const int* b, const int* c, const int* d) +{ + if (intersectProp(a, b, c, d)) + return true; + else if (between(a, b, c) || between(a, b, d) || + between(c, d, a) || between(c, d, b)) + return true; + else + return false; +} + +static bool vequal(const int* a, const int* b) +{ + return a[0] == b[0] && a[2] == b[2]; +} + +// Returns T iff (v_i, v_j) is a proper internal *or* external +// diagonal of P, *ignoring edges incident to v_i and v_j*. +static bool diagonalie(int i, int j, int n, const int* verts, int* indices) +{ + const int* d0 = &verts[(indices[i] & 0x0fffffff) * 4]; + const int* d1 = &verts[(indices[j] & 0x0fffffff) * 4]; + + // For each edge (k,k+1) of P + for (int k = 0; k < n; k++) + { + int k1 = next(k, n); + // Skip edges incident to i or j + if (!((k == i) || (k1 == i) || (k == j) || (k1 == j))) + { + const int* p0 = &verts[(indices[k] & 0x0fffffff) * 4]; + const int* p1 = &verts[(indices[k1] & 0x0fffffff) * 4]; + + if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1)) + continue; + + if (intersect(d0, d1, p0, p1)) + return false; + } + } + return true; +} + +// Returns true iff the diagonal (i,j) is strictly internal to the +// polygon P in the neighborhood of the i endpoint. +static bool inCone(int i, int j, int n, const int* verts, int* indices) +{ + const int* pi = &verts[(indices[i] & 0x0fffffff) * 4]; + const int* pj = &verts[(indices[j] & 0x0fffffff) * 4]; + const int* pi1 = &verts[(indices[next(i, n)] & 0x0fffffff) * 4]; + const int* pin1 = &verts[(indices[prev(i, n)] & 0x0fffffff) * 4]; + + // If P[i] is a convex vertex [ i+1 left or on (i-1,i) ]. + if (leftOn(pin1, pi, pi1)) + return left(pi, pj, pin1) && left(pj, pi, pi1); + // Assume (i-1,i,i+1) not collinear. + // else P[i] is reflex. + return !(leftOn(pi, pj, pi1) && leftOn(pj, pi, pin1)); +} + +// Returns T iff (v_i, v_j) is a proper internal +// diagonal of P. +static bool diagonal(int i, int j, int n, const int* verts, int* indices) +{ + return inCone(i, j, n, verts, indices) && diagonalie(i, j, n, verts, indices); +} + + +static bool diagonalieLoose(int i, int j, int n, const int* verts, int* indices) +{ + const int* d0 = &verts[(indices[i] & 0x0fffffff) * 4]; + const int* d1 = &verts[(indices[j] & 0x0fffffff) * 4]; + + // For each edge (k,k+1) of P + for (int k = 0; k < n; k++) + { + int k1 = next(k, n); + // Skip edges incident to i or j + if (!((k == i) || (k1 == i) || (k == j) || (k1 == j))) + { + const int* p0 = &verts[(indices[k] & 0x0fffffff) * 4]; + const int* p1 = &verts[(indices[k1] & 0x0fffffff) * 4]; + + if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1)) + continue; + + if (intersectProp(d0, d1, p0, p1)) + return false; + } + } + return true; +} + +static bool inConeLoose(int i, int j, int n, const int* verts, int* indices) +{ + const int* pi = &verts[(indices[i] & 0x0fffffff) * 4]; + const int* pj = &verts[(indices[j] & 0x0fffffff) * 4]; + const int* pi1 = &verts[(indices[next(i, n)] & 0x0fffffff) * 4]; + const int* pin1 = &verts[(indices[prev(i, n)] & 0x0fffffff) * 4]; + + // If P[i] is a convex vertex [ i+1 left or on (i-1,i) ]. + if (leftOn(pin1, pi, pi1)) + return leftOn(pi, pj, pin1) && leftOn(pj, pi, pi1); + // Assume (i-1,i,i+1) not collinear. + // else P[i] is reflex. + return !(leftOn(pi, pj, pi1) && leftOn(pj, pi, pin1)); +} + +static bool diagonalLoose(int i, int j, int n, const int* verts, int* indices) +{ + return inConeLoose(i, j, n, verts, indices) && diagonalieLoose(i, j, n, verts, indices); +} + + +static int triangulate(int n, const int* verts, int* indices, int* tris) +{ + int ntris = 0; + int* dst = tris; + + // The last bit of the index is used to indicate if the vertex can be removed. + for (int i = 0; i < n; i++) + { + int i1 = next(i, n); + int i2 = next(i1, n); + if (diagonal(i, i2, n, verts, indices)) + indices[i1] |= 0x80000000; + } + + while (n > 3) + { + int minLen = -1; + int mini = -1; + for (int i = 0; i < n; i++) + { + int i1 = next(i, n); + if (indices[i1] & 0x80000000) + { + const int* p0 = &verts[(indices[i] & 0x0fffffff) * 4]; + const int* p2 = &verts[(indices[next(i1, n)] & 0x0fffffff) * 4]; + + int dx = p2[0] - p0[0]; + int dy = p2[2] - p0[2]; + int len = dx*dx + dy*dy; + + if (minLen < 0 || len < minLen) + { + minLen = len; + mini = i; + } + } + } + + if (mini == -1) + { + // We might get here because the contour has overlapping segments, like this: + // + // A o-o=====o---o B + // / |C D| \. + // o o o o + // : : : : + // We'll try to recover by loosing up the inCone test a bit so that a diagonal + // like A-B or C-D can be found and we can continue. + minLen = -1; + mini = -1; + for (int i = 0; i < n; i++) + { + int i1 = next(i, n); + int i2 = next(i1, n); + if (diagonalLoose(i, i2, n, verts, indices)) + { + const int* p0 = &verts[(indices[i] & 0x0fffffff) * 4]; + const int* p2 = &verts[(indices[next(i2, n)] & 0x0fffffff) * 4]; + int dx = p2[0] - p0[0]; + int dy = p2[2] - p0[2]; + int len = dx*dx + dy*dy; + + if (minLen < 0 || len < minLen) + { + minLen = len; + mini = i; + } + } + } + if (mini == -1) + { + // The contour is messed up. This sometimes happens + // if the contour simplification is too aggressive. + return -ntris; + } + } + + int i = mini; + int i1 = next(i, n); + int i2 = next(i1, n); + + *dst++ = indices[i] & 0x0fffffff; + *dst++ = indices[i1] & 0x0fffffff; + *dst++ = indices[i2] & 0x0fffffff; + ntris++; + + // Removes P[i1] by copying P[i+1]...P[n-1] left one index. + n--; + for (int k = i1; k < n; k++) + indices[k] = indices[k+1]; + + if (i1 >= n) i1 = 0; + i = prev(i1,n); + // Update diagonal flags. + if (diagonal(prev(i, n), i1, n, verts, indices)) + indices[i] |= 0x80000000; + else + indices[i] &= 0x0fffffff; + + if (diagonal(i, next(i1, n), n, verts, indices)) + indices[i1] |= 0x80000000; + else + indices[i1] &= 0x0fffffff; + } + + // Append the remaining triangle. + *dst++ = indices[0] & 0x0fffffff; + *dst++ = indices[1] & 0x0fffffff; + *dst++ = indices[2] & 0x0fffffff; + ntris++; + + return ntris; +} + +static int countPolyVerts(const unsigned short* p, const int nvp) +{ + for (int i = 0; i < nvp; ++i) + if (p[i] == RC_MESH_NULL_IDX) + return i; + return nvp; +} + +inline bool uleft(const unsigned short* a, const unsigned short* b, const unsigned short* c) +{ + return ((int)b[0] - (int)a[0]) * ((int)c[2] - (int)a[2]) - + ((int)c[0] - (int)a[0]) * ((int)b[2] - (int)a[2]) < 0; +} + +static int getPolyMergeValue(unsigned short* pa, unsigned short* pb, + const unsigned short* verts, int& ea, int& eb, + const int nvp) +{ + const int na = countPolyVerts(pa, nvp); + const int nb = countPolyVerts(pb, nvp); + + // If the merged polygon would be too big, do not merge. + if (na+nb-2 > nvp) + return -1; + + // Check if the polygons share an edge. + ea = -1; + eb = -1; + + for (int i = 0; i < na; ++i) + { + unsigned short va0 = pa[i]; + unsigned short va1 = pa[(i+1) % na]; + if (va0 > va1) + rcSwap(va0, va1); + for (int j = 0; j < nb; ++j) + { + unsigned short vb0 = pb[j]; + unsigned short vb1 = pb[(j+1) % nb]; + if (vb0 > vb1) + rcSwap(vb0, vb1); + if (va0 == vb0 && va1 == vb1) + { + ea = i; + eb = j; + break; + } + } + } + + // No common edge, cannot merge. + if (ea == -1 || eb == -1) + return -1; + + // Check to see if the merged polygon would be convex. + unsigned short va, vb, vc; + + va = pa[(ea+na-1) % na]; + vb = pa[ea]; + vc = pb[(eb+2) % nb]; + if (!uleft(&verts[va*3], &verts[vb*3], &verts[vc*3])) + return -1; + + va = pb[(eb+nb-1) % nb]; + vb = pb[eb]; + vc = pa[(ea+2) % na]; + if (!uleft(&verts[va*3], &verts[vb*3], &verts[vc*3])) + return -1; + + va = pa[ea]; + vb = pa[(ea+1)%na]; + + int dx = (int)verts[va*3+0] - (int)verts[vb*3+0]; + int dy = (int)verts[va*3+2] - (int)verts[vb*3+2]; + + return dx*dx + dy*dy; +} + +static void mergePolyVerts(unsigned short* pa, unsigned short* pb, int ea, int eb, + unsigned short* tmp, const int nvp) +{ + const int na = countPolyVerts(pa, nvp); + const int nb = countPolyVerts(pb, nvp); + + // Merge polygons. + memset(tmp, 0xff, sizeof(unsigned short)*nvp); + int n = 0; + // Add pa + for (int i = 0; i < na-1; ++i) + tmp[n++] = pa[(ea+1+i) % na]; + // Add pb + for (int i = 0; i < nb-1; ++i) + tmp[n++] = pb[(eb+1+i) % nb]; + + memcpy(pa, tmp, sizeof(unsigned short)*nvp); +} + + +static void pushFront(int v, int* arr, int& an) +{ + an++; + for (int i = an-1; i > 0; --i) arr[i] = arr[i-1]; + arr[0] = v; +} + +static void pushBack(int v, int* arr, int& an) +{ + arr[an] = v; + an++; +} + +static bool canRemoveVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short rem) +{ + const int nvp = mesh.nvp; + + // Count number of polygons to remove. + int numRemovedVerts = 0; + int numTouchedVerts = 0; + int numRemainingEdges = 0; + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + int numRemoved = 0; + int numVerts = 0; + for (int j = 0; j < nv; ++j) + { + if (p[j] == rem) + { + numTouchedVerts++; + numRemoved++; + } + numVerts++; + } + if (numRemoved) + { + numRemovedVerts += numRemoved; + numRemainingEdges += numVerts-(numRemoved+1); + } + } + + // There would be too few edges remaining to create a polygon. + // This can happen for example when a tip of a triangle is marked + // as deletion, but there are no other polys that share the vertex. + // In this case, the vertex should not be removed. + if (numRemainingEdges <= 2) + return false; + + // Find edges which share the removed vertex. + const int maxEdges = numTouchedVerts*2; + int nedges = 0; + rcScopedDelete edges((int*)rcAlloc(sizeof(int)*maxEdges*3, RC_ALLOC_TEMP)); + if (!edges) + { + ctx->log(RC_LOG_WARNING, "canRemoveVertex: Out of memory 'edges' (%d).", maxEdges*3); + return false; + } + + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + + // Collect edges which touches the removed vertex. + for (int j = 0, k = nv-1; j < nv; k = j++) + { + if (p[j] == rem || p[k] == rem) + { + // Arrange edge so that a=rem. + int a = p[j], b = p[k]; + if (b == rem) + rcSwap(a,b); + + // Check if the edge exists + bool exists = false; + for (int m = 0; m < nedges; ++m) + { + int* e = &edges[m*3]; + if (e[1] == b) + { + // Exists, increment vertex share count. + e[2]++; + exists = true; + } + } + // Add new edge. + if (!exists) + { + int* e = &edges[nedges*3]; + e[0] = a; + e[1] = b; + e[2] = 1; + nedges++; + } + } + } + } + + // There should be no more than 2 open edges. + // This catches the case that two non-adjacent polygons + // share the removed vertex. In that case, do not remove the vertex. + int numOpenEdges = 0; + for (int i = 0; i < nedges; ++i) + { + if (edges[i*3+2] < 2) + numOpenEdges++; + } + if (numOpenEdges > 2) + return false; + + return true; +} + +static bool removeVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short rem, const int maxTris) +{ + const int nvp = mesh.nvp; + + // Count number of polygons to remove. + int numRemovedVerts = 0; + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + for (int j = 0; j < nv; ++j) + { + if (p[j] == rem) + numRemovedVerts++; + } + } + + int nedges = 0; + rcScopedDelete edges((int*)rcAlloc(sizeof(int)*numRemovedVerts*nvp*4, RC_ALLOC_TEMP)); + if (!edges) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'edges' (%d).", numRemovedVerts*nvp*4); + return false; + } + + int nhole = 0; + rcScopedDelete hole((int*)rcAlloc(sizeof(int)*numRemovedVerts*nvp, RC_ALLOC_TEMP)); + if (!hole) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hole' (%d).", numRemovedVerts*nvp); + return false; + } + + int nhreg = 0; + rcScopedDelete hreg((int*)rcAlloc(sizeof(int)*numRemovedVerts*nvp, RC_ALLOC_TEMP)); + if (!hreg) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hreg' (%d).", numRemovedVerts*nvp); + return false; + } + + int nharea = 0; + rcScopedDelete harea((int*)rcAlloc(sizeof(int)*numRemovedVerts*nvp, RC_ALLOC_TEMP)); + if (!harea) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'harea' (%d).", numRemovedVerts*nvp); + return false; + } + + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + bool hasRem = false; + for (int j = 0; j < nv; ++j) + if (p[j] == rem) hasRem = true; + if (hasRem) + { + // Collect edges which does not touch the removed vertex. + for (int j = 0, k = nv-1; j < nv; k = j++) + { + if (p[j] != rem && p[k] != rem) + { + int* e = &edges[nedges*4]; + e[0] = p[k]; + e[1] = p[j]; + e[2] = mesh.regs[i]; + e[3] = mesh.areas[i]; + nedges++; + } + } + // Remove the polygon. + unsigned short* p2 = &mesh.polys[(mesh.npolys-1)*nvp*2]; + if (p != p2) + memcpy(p,p2,sizeof(unsigned short)*nvp); + memset(p+nvp,0xff,sizeof(unsigned short)*nvp); + mesh.regs[i] = mesh.regs[mesh.npolys-1]; + mesh.areas[i] = mesh.areas[mesh.npolys-1]; + mesh.npolys--; + --i; + } + } + + // Remove vertex. + for (int i = (int)rem; i < mesh.nverts - 1; ++i) + { + mesh.verts[i*3+0] = mesh.verts[(i+1)*3+0]; + mesh.verts[i*3+1] = mesh.verts[(i+1)*3+1]; + mesh.verts[i*3+2] = mesh.verts[(i+1)*3+2]; + } + mesh.nverts--; + + // Adjust indices to match the removed vertex layout. + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + for (int j = 0; j < nv; ++j) + if (p[j] > rem) p[j]--; + } + for (int i = 0; i < nedges; ++i) + { + if (edges[i*4+0] > rem) edges[i*4+0]--; + if (edges[i*4+1] > rem) edges[i*4+1]--; + } + + if (nedges == 0) + return true; + + // Start with one vertex, keep appending connected + // segments to the start and end of the hole. + pushBack(edges[0], hole, nhole); + pushBack(edges[2], hreg, nhreg); + pushBack(edges[3], harea, nharea); + + while (nedges) + { + bool match = false; + + for (int i = 0; i < nedges; ++i) + { + const int ea = edges[i*4+0]; + const int eb = edges[i*4+1]; + const int r = edges[i*4+2]; + const int a = edges[i*4+3]; + bool add = false; + if (hole[0] == eb) + { + // The segment matches the beginning of the hole boundary. + pushFront(ea, hole, nhole); + pushFront(r, hreg, nhreg); + pushFront(a, harea, nharea); + add = true; + } + else if (hole[nhole-1] == ea) + { + // The segment matches the end of the hole boundary. + pushBack(eb, hole, nhole); + pushBack(r, hreg, nhreg); + pushBack(a, harea, nharea); + add = true; + } + if (add) + { + // The edge segment was added, remove it. + edges[i*4+0] = edges[(nedges-1)*4+0]; + edges[i*4+1] = edges[(nedges-1)*4+1]; + edges[i*4+2] = edges[(nedges-1)*4+2]; + edges[i*4+3] = edges[(nedges-1)*4+3]; + --nedges; + match = true; + --i; + } + } + + if (!match) + break; + } + + rcScopedDelete tris((int*)rcAlloc(sizeof(int)*nhole*3, RC_ALLOC_TEMP)); + if (!tris) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'tris' (%d).", nhole*3); + return false; + } + + rcScopedDelete tverts((int*)rcAlloc(sizeof(int)*nhole*4, RC_ALLOC_TEMP)); + if (!tverts) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'tverts' (%d).", nhole*4); + return false; + } + + rcScopedDelete thole((int*)rcAlloc(sizeof(int)*nhole, RC_ALLOC_TEMP)); + if (!thole) + { + ctx->log(RC_LOG_WARNING, "removeVertex: Out of memory 'thole' (%d).", nhole); + return false; + } + + // Generate temp vertex array for triangulation. + for (int i = 0; i < nhole; ++i) + { + const int pi = hole[i]; + tverts[i*4+0] = mesh.verts[pi*3+0]; + tverts[i*4+1] = mesh.verts[pi*3+1]; + tverts[i*4+2] = mesh.verts[pi*3+2]; + tverts[i*4+3] = 0; + thole[i] = i; + } + + // Triangulate the hole. + int ntris = triangulate(nhole, &tverts[0], &thole[0], tris); + if (ntris < 0) + { + ntris = -ntris; + ctx->log(RC_LOG_WARNING, "removeVertex: triangulate() returned bad results."); + } + + // Merge the hole triangles back to polygons. + rcScopedDelete polys((unsigned short*)rcAlloc(sizeof(unsigned short)*(ntris+1)*nvp, RC_ALLOC_TEMP)); + if (!polys) + { + ctx->log(RC_LOG_ERROR, "removeVertex: Out of memory 'polys' (%d).", (ntris+1)*nvp); + return false; + } + rcScopedDelete pregs((unsigned short*)rcAlloc(sizeof(unsigned short)*ntris, RC_ALLOC_TEMP)); + if (!pregs) + { + ctx->log(RC_LOG_ERROR, "removeVertex: Out of memory 'pregs' (%d).", ntris); + return false; + } + rcScopedDelete pareas((unsigned char*)rcAlloc(sizeof(unsigned char)*ntris, RC_ALLOC_TEMP)); + if (!pareas) + { + ctx->log(RC_LOG_ERROR, "removeVertex: Out of memory 'pareas' (%d).", ntris); + return false; + } + + unsigned short* tmpPoly = &polys[ntris*nvp]; + + // Build initial polygons. + int npolys = 0; + memset(polys, 0xff, ntris*nvp*sizeof(unsigned short)); + for (int j = 0; j < ntris; ++j) + { + int* t = &tris[j*3]; + if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2]) + { + polys[npolys*nvp+0] = (unsigned short)hole[t[0]]; + polys[npolys*nvp+1] = (unsigned short)hole[t[1]]; + polys[npolys*nvp+2] = (unsigned short)hole[t[2]]; + + // If this polygon covers multiple region types then + // mark it as such + if (hreg[t[0]] != hreg[t[1]] || hreg[t[1]] != hreg[t[2]]) + pregs[npolys] = RC_MULTIPLE_REGS; + else + pregs[npolys] = (unsigned short)hreg[t[0]]; + + pareas[npolys] = (unsigned char)harea[t[0]]; + npolys++; + } + } + if (!npolys) + return true; + + // Merge polygons. + if (nvp > 3) + { + for (;;) + { + // Find best polygons to merge. + int bestMergeVal = 0; + int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0; + + for (int j = 0; j < npolys-1; ++j) + { + unsigned short* pj = &polys[j*nvp]; + for (int k = j+1; k < npolys; ++k) + { + unsigned short* pk = &polys[k*nvp]; + int ea, eb; + int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb, nvp); + if (v > bestMergeVal) + { + bestMergeVal = v; + bestPa = j; + bestPb = k; + bestEa = ea; + bestEb = eb; + } + } + } + + if (bestMergeVal > 0) + { + // Found best, merge. + unsigned short* pa = &polys[bestPa*nvp]; + unsigned short* pb = &polys[bestPb*nvp]; + mergePolyVerts(pa, pb, bestEa, bestEb, tmpPoly, nvp); + if (pregs[bestPa] != pregs[bestPb]) + pregs[bestPa] = RC_MULTIPLE_REGS; + + unsigned short* last = &polys[(npolys-1)*nvp]; + if (pb != last) + memcpy(pb, last, sizeof(unsigned short)*nvp); + pregs[bestPb] = pregs[npolys-1]; + pareas[bestPb] = pareas[npolys-1]; + npolys--; + } + else + { + // Could not merge any polygons, stop. + break; + } + } + } + + // Store polygons. + for (int i = 0; i < npolys; ++i) + { + if (mesh.npolys >= maxTris) break; + unsigned short* p = &mesh.polys[mesh.npolys*nvp*2]; + memset(p,0xff,sizeof(unsigned short)*nvp*2); + for (int j = 0; j < nvp; ++j) + p[j] = polys[i*nvp+j]; + mesh.regs[mesh.npolys] = pregs[i]; + mesh.areas[mesh.npolys] = pareas[i]; + mesh.npolys++; + if (mesh.npolys > maxTris) + { + ctx->log(RC_LOG_ERROR, "removeVertex: Too many polygons %d (max:%d).", mesh.npolys, maxTris); + return false; + } + } + + return true; +} + +/// @par +/// +/// @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper +/// limit must be retricted to <= #DT_VERTS_PER_POLYGON. +/// +/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig +bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_POLYMESH); + + rcVcopy(mesh.bmin, cset.bmin); + rcVcopy(mesh.bmax, cset.bmax); + mesh.cs = cset.cs; + mesh.ch = cset.ch; + mesh.borderSize = cset.borderSize; + mesh.maxEdgeError = cset.maxError; + + int maxVertices = 0; + int maxTris = 0; + int maxVertsPerCont = 0; + for (int i = 0; i < cset.nconts; ++i) + { + // Skip null contours. + if (cset.conts[i].nverts < 3) continue; + maxVertices += cset.conts[i].nverts; + maxTris += cset.conts[i].nverts - 2; + maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts); + } + + if (maxVertices >= 0xfffe) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many vertices %d.", maxVertices); + return false; + } + + rcScopedDelete vflags((unsigned char*)rcAlloc(sizeof(unsigned char)*maxVertices, RC_ALLOC_TEMP)); + if (!vflags) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vflags' (%d).", maxVertices); + return false; + } + memset(vflags, 0, maxVertices); + + mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertices*3, RC_ALLOC_PERM); + if (!mesh.verts) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices); + return false; + } + mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris*nvp*2, RC_ALLOC_PERM); + if (!mesh.polys) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2); + return false; + } + mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris, RC_ALLOC_PERM); + if (!mesh.regs) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.regs' (%d).", maxTris); + return false; + } + mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxTris, RC_ALLOC_PERM); + if (!mesh.areas) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.areas' (%d).", maxTris); + return false; + } + + mesh.nverts = 0; + mesh.npolys = 0; + mesh.nvp = nvp; + mesh.maxpolys = maxTris; + + memset(mesh.verts, 0, sizeof(unsigned short)*maxVertices*3); + memset(mesh.polys, 0xff, sizeof(unsigned short)*maxTris*nvp*2); + memset(mesh.regs, 0, sizeof(unsigned short)*maxTris); + memset(mesh.areas, 0, sizeof(unsigned char)*maxTris); + + rcScopedDelete nextVert((int*)rcAlloc(sizeof(int)*maxVertices, RC_ALLOC_TEMP)); + if (!nextVert) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'nextVert' (%d).", maxVertices); + return false; + } + memset(nextVert, 0, sizeof(int)*maxVertices); + + rcScopedDelete firstVert((int*)rcAlloc(sizeof(int)*VERTEX_BUCKET_COUNT, RC_ALLOC_TEMP)); + if (!firstVert) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT); + return false; + } + for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i) + firstVert[i] = -1; + + rcScopedDelete indices((int*)rcAlloc(sizeof(int)*maxVertsPerCont, RC_ALLOC_TEMP)); + if (!indices) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'indices' (%d).", maxVertsPerCont); + return false; + } + rcScopedDelete tris((int*)rcAlloc(sizeof(int)*maxVertsPerCont*3, RC_ALLOC_TEMP)); + if (!tris) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'tris' (%d).", maxVertsPerCont*3); + return false; + } + rcScopedDelete polys((unsigned short*)rcAlloc(sizeof(unsigned short)*(maxVertsPerCont+1)*nvp, RC_ALLOC_TEMP)); + if (!polys) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'polys' (%d).", maxVertsPerCont*nvp); + return false; + } + unsigned short* tmpPoly = &polys[maxVertsPerCont*nvp]; + + for (int i = 0; i < cset.nconts; ++i) + { + rcContour& cont = cset.conts[i]; + + // Skip null contours. + if (cont.nverts < 3) + continue; + + // Triangulate contour + for (int j = 0; j < cont.nverts; ++j) + indices[j] = j; + + int ntris = triangulate(cont.nverts, cont.verts, &indices[0], &tris[0]); + if (ntris <= 0) + { + // Bad triangulation, should not happen. +/* printf("\tconst float bmin[3] = {%ff,%ff,%ff};\n", cset.bmin[0], cset.bmin[1], cset.bmin[2]); + printf("\tconst float cs = %ff;\n", cset.cs); + printf("\tconst float ch = %ff;\n", cset.ch); + printf("\tconst int verts[] = {\n"); + for (int k = 0; k < cont.nverts; ++k) + { + const int* v = &cont.verts[k*4]; + printf("\t\t%d,%d,%d,%d,\n", v[0], v[1], v[2], v[3]); + } + printf("\t};\n\tconst int nverts = sizeof(verts)/(sizeof(int)*4);\n");*/ + ctx->log(RC_LOG_WARNING, "rcBuildPolyMesh: Bad triangulation Contour %d.", i); + ntris = -ntris; + } + + // Add and merge vertices. + for (int j = 0; j < cont.nverts; ++j) + { + const int* v = &cont.verts[j*4]; + indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2], + mesh.verts, firstVert, nextVert, mesh.nverts); + if (v[3] & RC_BORDER_VERTEX) + { + // This vertex should be removed. + vflags[indices[j]] = 1; + } + } + + // Build initial polygons. + int npolys = 0; + memset(polys, 0xff, maxVertsPerCont*nvp*sizeof(unsigned short)); + for (int j = 0; j < ntris; ++j) + { + int* t = &tris[j*3]; + if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2]) + { + polys[npolys*nvp+0] = (unsigned short)indices[t[0]]; + polys[npolys*nvp+1] = (unsigned short)indices[t[1]]; + polys[npolys*nvp+2] = (unsigned short)indices[t[2]]; + npolys++; + } + } + if (!npolys) + continue; + + // Merge polygons. + if (nvp > 3) + { + for(;;) + { + // Find best polygons to merge. + int bestMergeVal = 0; + int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0; + + for (int j = 0; j < npolys-1; ++j) + { + unsigned short* pj = &polys[j*nvp]; + for (int k = j+1; k < npolys; ++k) + { + unsigned short* pk = &polys[k*nvp]; + int ea, eb; + int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb, nvp); + if (v > bestMergeVal) + { + bestMergeVal = v; + bestPa = j; + bestPb = k; + bestEa = ea; + bestEb = eb; + } + } + } + + if (bestMergeVal > 0) + { + // Found best, merge. + unsigned short* pa = &polys[bestPa*nvp]; + unsigned short* pb = &polys[bestPb*nvp]; + mergePolyVerts(pa, pb, bestEa, bestEb, tmpPoly, nvp); + unsigned short* lastPoly = &polys[(npolys-1)*nvp]; + if (pb != lastPoly) + memcpy(pb, lastPoly, sizeof(unsigned short)*nvp); + npolys--; + } + else + { + // Could not merge any polygons, stop. + break; + } + } + } + + // Store polygons. + for (int j = 0; j < npolys; ++j) + { + unsigned short* p = &mesh.polys[mesh.npolys*nvp*2]; + unsigned short* q = &polys[j*nvp]; + for (int k = 0; k < nvp; ++k) + p[k] = q[k]; + mesh.regs[mesh.npolys] = cont.reg; + mesh.areas[mesh.npolys] = cont.area; + mesh.npolys++; + if (mesh.npolys > maxTris) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many polygons %d (max:%d).", mesh.npolys, maxTris); + return false; + } + } + } + + + // Remove edge vertices. + for (int i = 0; i < mesh.nverts; ++i) + { + if (vflags[i]) + { + if (!canRemoveVertex(ctx, mesh, (unsigned short)i)) + continue; + if (!removeVertex(ctx, mesh, (unsigned short)i, maxTris)) + { + // Failed to remove vertex + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Failed to remove edge vertex %d.", i); + return false; + } + // Remove vertex + // Note: mesh.nverts is already decremented inside removeVertex()! + // Fixup vertex flags + for (int j = i; j < mesh.nverts; ++j) + vflags[j] = vflags[j+1]; + --i; + } + } + + // Calculate adjacency. + if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, nvp)) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Adjacency failed."); + return false; + } + + // Find portal edges + if (mesh.borderSize > 0) + { + const int w = cset.width; + const int h = cset.height; + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*2*nvp]; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) break; + // Skip connected edges. + if (p[nvp+j] != RC_MESH_NULL_IDX) + continue; + int nj = j+1; + if (nj >= nvp || p[nj] == RC_MESH_NULL_IDX) nj = 0; + const unsigned short* va = &mesh.verts[p[j]*3]; + const unsigned short* vb = &mesh.verts[p[nj]*3]; + + if ((int)va[0] == 0 && (int)vb[0] == 0) + p[nvp+j] = 0x8000 | 0; + else if ((int)va[2] == h && (int)vb[2] == h) + p[nvp+j] = 0x8000 | 1; + else if ((int)va[0] == w && (int)vb[0] == w) + p[nvp+j] = 0x8000 | 2; + else if ((int)va[2] == 0 && (int)vb[2] == 0) + p[nvp+j] = 0x8000 | 3; + } + } + } + + // Just allocate the mesh flags array. The user is resposible to fill it. + mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*mesh.npolys, RC_ALLOC_PERM); + if (!mesh.flags) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.flags' (%d).", mesh.npolys); + return false; + } + memset(mesh.flags, 0, sizeof(unsigned short) * mesh.npolys); + + if (mesh.nverts > 0xffff) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff); + } + if (mesh.npolys > 0xffff) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff); + } + + return true; +} + +/// @see rcAllocPolyMesh, rcPolyMesh +bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh) +{ + rcAssert(ctx); + + if (!nmeshes || !meshes) + return true; + + rcScopedTimer timer(ctx, RC_TIMER_MERGE_POLYMESH); + + mesh.nvp = meshes[0]->nvp; + mesh.cs = meshes[0]->cs; + mesh.ch = meshes[0]->ch; + rcVcopy(mesh.bmin, meshes[0]->bmin); + rcVcopy(mesh.bmax, meshes[0]->bmax); + + int maxVerts = 0; + int maxPolys = 0; + int maxVertsPerMesh = 0; + for (int i = 0; i < nmeshes; ++i) + { + rcVmin(mesh.bmin, meshes[i]->bmin); + rcVmax(mesh.bmax, meshes[i]->bmax); + maxVertsPerMesh = rcMax(maxVertsPerMesh, meshes[i]->nverts); + maxVerts += meshes[i]->nverts; + maxPolys += meshes[i]->npolys; + } + + mesh.nverts = 0; + mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVerts*3, RC_ALLOC_PERM); + if (!mesh.verts) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.verts' (%d).", maxVerts*3); + return false; + } + + mesh.npolys = 0; + mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys*2*mesh.nvp, RC_ALLOC_PERM); + if (!mesh.polys) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.polys' (%d).", maxPolys*2*mesh.nvp); + return false; + } + memset(mesh.polys, 0xff, sizeof(unsigned short)*maxPolys*2*mesh.nvp); + + mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys, RC_ALLOC_PERM); + if (!mesh.regs) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.regs' (%d).", maxPolys); + return false; + } + memset(mesh.regs, 0, sizeof(unsigned short)*maxPolys); + + mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxPolys, RC_ALLOC_PERM); + if (!mesh.areas) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.areas' (%d).", maxPolys); + return false; + } + memset(mesh.areas, 0, sizeof(unsigned char)*maxPolys); + + mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys, RC_ALLOC_PERM); + if (!mesh.flags) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.flags' (%d).", maxPolys); + return false; + } + memset(mesh.flags, 0, sizeof(unsigned short)*maxPolys); + + rcScopedDelete nextVert((int*)rcAlloc(sizeof(int)*maxVerts, RC_ALLOC_TEMP)); + if (!nextVert) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'nextVert' (%d).", maxVerts); + return false; + } + memset(nextVert, 0, sizeof(int)*maxVerts); + + rcScopedDelete firstVert((int*)rcAlloc(sizeof(int)*VERTEX_BUCKET_COUNT, RC_ALLOC_TEMP)); + if (!firstVert) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT); + return false; + } + for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i) + firstVert[i] = -1; + + rcScopedDelete vremap((unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertsPerMesh, RC_ALLOC_PERM)); + if (!vremap) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'vremap' (%d).", maxVertsPerMesh); + return false; + } + memset(vremap, 0, sizeof(unsigned short)*maxVertsPerMesh); + + for (int i = 0; i < nmeshes; ++i) + { + const rcPolyMesh* pmesh = meshes[i]; + + const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f); + const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f); + + bool isMinX = (ox == 0); + bool isMinZ = (oz == 0); + bool isMaxX = ((unsigned short)floorf((mesh.bmax[0] - pmesh->bmax[0]) / mesh.cs + 0.5f)) == 0; + bool isMaxZ = ((unsigned short)floorf((mesh.bmax[2] - pmesh->bmax[2]) / mesh.cs + 0.5f)) == 0; + bool isOnBorder = (isMinX || isMinZ || isMaxX || isMaxZ); + + for (int j = 0; j < pmesh->nverts; ++j) + { + unsigned short* v = &pmesh->verts[j*3]; + vremap[j] = addVertex(v[0]+ox, v[1], v[2]+oz, + mesh.verts, firstVert, nextVert, mesh.nverts); + } + + for (int j = 0; j < pmesh->npolys; ++j) + { + unsigned short* tgt = &mesh.polys[mesh.npolys*2*mesh.nvp]; + unsigned short* src = &pmesh->polys[j*2*mesh.nvp]; + mesh.regs[mesh.npolys] = pmesh->regs[j]; + mesh.areas[mesh.npolys] = pmesh->areas[j]; + mesh.flags[mesh.npolys] = pmesh->flags[j]; + mesh.npolys++; + for (int k = 0; k < mesh.nvp; ++k) + { + if (src[k] == RC_MESH_NULL_IDX) break; + tgt[k] = vremap[src[k]]; + } + + if (isOnBorder) + { + for (int k = mesh.nvp; k < mesh.nvp * 2; ++k) + { + if (src[k] & 0x8000 && src[k] != 0xffff) + { + unsigned short dir = src[k] & 0xf; + switch (dir) + { + case 0: // Portal x- + if (isMinX) + tgt[k] = src[k]; + break; + case 1: // Portal z+ + if (isMaxZ) + tgt[k] = src[k]; + break; + case 2: // Portal x+ + if (isMaxX) + tgt[k] = src[k]; + break; + case 3: // Portal z- + if (isMinZ) + tgt[k] = src[k]; + break; + } + } + } + } + } + } + + // Calculate adjacency. + if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, mesh.nvp)) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Adjacency failed."); + return false; + } + + if (mesh.nverts > 0xffff) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff); + } + if (mesh.npolys > 0xffff) + { + ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff); + } + + return true; +} + +bool rcCopyPolyMesh(rcContext* ctx, const rcPolyMesh& src, rcPolyMesh& dst) +{ + rcAssert(ctx); + + // Destination must be empty. + rcAssert(dst.verts == 0); + rcAssert(dst.polys == 0); + rcAssert(dst.regs == 0); + rcAssert(dst.areas == 0); + rcAssert(dst.flags == 0); + + dst.nverts = src.nverts; + dst.npolys = src.npolys; + dst.maxpolys = src.npolys; + dst.nvp = src.nvp; + rcVcopy(dst.bmin, src.bmin); + rcVcopy(dst.bmax, src.bmax); + dst.cs = src.cs; + dst.ch = src.ch; + dst.borderSize = src.borderSize; + dst.maxEdgeError = src.maxEdgeError; + + dst.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.nverts*3, RC_ALLOC_PERM); + if (!dst.verts) + { + ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.verts' (%d).", src.nverts*3); + return false; + } + memcpy(dst.verts, src.verts, sizeof(unsigned short)*src.nverts*3); + + dst.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.npolys*2*src.nvp, RC_ALLOC_PERM); + if (!dst.polys) + { + ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.polys' (%d).", src.npolys*2*src.nvp); + return false; + } + memcpy(dst.polys, src.polys, sizeof(unsigned short)*src.npolys*2*src.nvp); + + dst.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.npolys, RC_ALLOC_PERM); + if (!dst.regs) + { + ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.regs' (%d).", src.npolys); + return false; + } + memcpy(dst.regs, src.regs, sizeof(unsigned short)*src.npolys); + + dst.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*src.npolys, RC_ALLOC_PERM); + if (!dst.areas) + { + ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.areas' (%d).", src.npolys); + return false; + } + memcpy(dst.areas, src.areas, sizeof(unsigned char)*src.npolys); + + dst.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.npolys, RC_ALLOC_PERM); + if (!dst.flags) + { + ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.flags' (%d).", src.npolys); + return false; + } + memcpy(dst.flags, src.flags, sizeof(unsigned short)*src.npolys); + + return true; +} diff --git a/libs/recast/recast/src/RecastMeshDetail.cpp b/libs/recast/recast/src/RecastMeshDetail.cpp new file mode 100644 index 000000000..f953132f7 --- /dev/null +++ b/libs/recast/recast/src/RecastMeshDetail.cpp @@ -0,0 +1,1462 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + + +static const unsigned RC_UNSET_HEIGHT = 0xffff; + +struct rcHeightPatch +{ + inline rcHeightPatch() : data(0), xmin(0), ymin(0), width(0), height(0) {} + inline ~rcHeightPatch() { rcFree(data); } + unsigned short* data; + int xmin, ymin, width, height; +}; + + +inline float vdot2(const float* a, const float* b) +{ + return a[0]*b[0] + a[2]*b[2]; +} + +inline float vdistSq2(const float* p, const float* q) +{ + const float dx = q[0] - p[0]; + const float dy = q[2] - p[2]; + return dx*dx + dy*dy; +} + +inline float vdist2(const float* p, const float* q) +{ + return sqrtf(vdistSq2(p,q)); +} + +inline float vcross2(const float* p1, const float* p2, const float* p3) +{ + const float u1 = p2[0] - p1[0]; + const float v1 = p2[2] - p1[2]; + const float u2 = p3[0] - p1[0]; + const float v2 = p3[2] - p1[2]; + return u1 * v2 - v1 * u2; +} + +static bool circumCircle(const float* p1, const float* p2, const float* p3, + float* c, float& r) +{ + static const float EPS = 1e-6f; + // Calculate the circle relative to p1, to avoid some precision issues. + const float v1[3] = {0,0,0}; + float v2[3], v3[3]; + rcVsub(v2, p2,p1); + rcVsub(v3, p3,p1); + + const float cp = vcross2(v1, v2, v3); + if (fabsf(cp) > EPS) + { + const float v1Sq = vdot2(v1,v1); + const float v2Sq = vdot2(v2,v2); + const float v3Sq = vdot2(v3,v3); + c[0] = (v1Sq*(v2[2]-v3[2]) + v2Sq*(v3[2]-v1[2]) + v3Sq*(v1[2]-v2[2])) / (2*cp); + c[1] = 0; + c[2] = (v1Sq*(v3[0]-v2[0]) + v2Sq*(v1[0]-v3[0]) + v3Sq*(v2[0]-v1[0])) / (2*cp); + r = vdist2(c, v1); + rcVadd(c, c, p1); + return true; + } + + rcVcopy(c, p1); + r = 0; + return false; +} + +static float distPtTri(const float* p, const float* a, const float* b, const float* c) +{ + float v0[3], v1[3], v2[3]; + rcVsub(v0, c,a); + rcVsub(v1, b,a); + rcVsub(v2, p,a); + + const float dot00 = vdot2(v0, v0); + const float dot01 = vdot2(v0, v1); + const float dot02 = vdot2(v0, v2); + const float dot11 = vdot2(v1, v1); + const float dot12 = vdot2(v1, v2); + + // Compute barycentric coordinates + const float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); + const float u = (dot11 * dot02 - dot01 * dot12) * invDenom; + float v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + // If point lies inside the triangle, return interpolated y-coord. + static const float EPS = 1e-4f; + if (u >= -EPS && v >= -EPS && (u+v) <= 1+EPS) + { + const float y = a[1] + v0[1]*u + v1[1]*v; + return fabsf(y-p[1]); + } + return FLT_MAX; +} + +static float distancePtSeg(const float* pt, const float* p, const float* q) +{ + float pqx = q[0] - p[0]; + float pqy = q[1] - p[1]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dy = pt[1] - p[1]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqy*pqy + pqz*pqz; + float t = pqx*dx + pqy*dy + pqz*dz; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + + dx = p[0] + t*pqx - pt[0]; + dy = p[1] + t*pqy - pt[1]; + dz = p[2] + t*pqz - pt[2]; + + return dx*dx + dy*dy + dz*dz; +} + +static float distancePtSeg2d(const float* pt, const float* p, const float* q) +{ + float pqx = q[0] - p[0]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqz*pqz; + float t = pqx*dx + pqz*dz; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + + dx = p[0] + t*pqx - pt[0]; + dz = p[2] + t*pqz - pt[2]; + + return dx*dx + dz*dz; +} + +static float distToTriMesh(const float* p, const float* verts, const int /*nverts*/, const int* tris, const int ntris) +{ + float dmin = FLT_MAX; + for (int i = 0; i < ntris; ++i) + { + const float* va = &verts[tris[i*4+0]*3]; + const float* vb = &verts[tris[i*4+1]*3]; + const float* vc = &verts[tris[i*4+2]*3]; + float d = distPtTri(p, va,vb,vc); + if (d < dmin) + dmin = d; + } + if (dmin == FLT_MAX) return -1; + return dmin; +} + +static float distToPoly(int nvert, const float* verts, const float* p) +{ + + float dmin = FLT_MAX; + int i, j, c = 0; + for (i = 0, j = nvert-1; i < nvert; j = i++) + { + const float* vi = &verts[i*3]; + const float* vj = &verts[j*3]; + if (((vi[2] > p[2]) != (vj[2] > p[2])) && + (p[0] < (vj[0]-vi[0]) * (p[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) ) + c = !c; + dmin = rcMin(dmin, distancePtSeg2d(p, vj, vi)); + } + return c ? -dmin : dmin; +} + + +static unsigned short getHeight(const float fx, const float fy, const float fz, + const float /*cs*/, const float ics, const float ch, + const int radius, const rcHeightPatch& hp) +{ + int ix = (int)floorf(fx*ics + 0.01f); + int iz = (int)floorf(fz*ics + 0.01f); + ix = rcClamp(ix-hp.xmin, 0, hp.width - 1); + iz = rcClamp(iz-hp.ymin, 0, hp.height - 1); + unsigned short h = hp.data[ix+iz*hp.width]; + if (h == RC_UNSET_HEIGHT) + { + // Special case when data might be bad. + // Walk adjacent cells in a spiral up to 'radius', and look + // for a pixel which has a valid height. + int x = 1, z = 0, dx = 1, dz = 0; + int maxSize = radius * 2 + 1; + int maxIter = maxSize * maxSize - 1; + + int nextRingIterStart = 8; + int nextRingIters = 16; + + float dmin = FLT_MAX; + for (int i = 0; i < maxIter; i++) + { + const int nx = ix + x; + const int nz = iz + z; + + if (nx >= 0 && nz >= 0 && nx < hp.width && nz < hp.height) + { + const unsigned short nh = hp.data[nx + nz*hp.width]; + if (nh != RC_UNSET_HEIGHT) + { + const float d = fabsf(nh*ch - fy); + if (d < dmin) + { + h = nh; + dmin = d; + } + } + } + + // We are searching in a grid which looks approximately like this: + // __________ + // |2 ______ 2| + // | |1 __ 1| | + // | | |__| | | + // | |______| | + // |__________| + // We want to find the best height as close to the center cell as possible. This means that + // if we find a height in one of the neighbor cells to the center, we don't want to + // expand further out than the 8 neighbors - we want to limit our search to the closest + // of these "rings", but the best height in the ring. + // For example, the center is just 1 cell. We checked that at the entrance to the function. + // The next "ring" contains 8 cells (marked 1 above). Those are all the neighbors to the center cell. + // The next one again contains 16 cells (marked 2). In general each ring has 8 additional cells, which + // can be thought of as adding 2 cells around the "center" of each side when we expand the ring. + // Here we detect if we are about to enter the next ring, and if we are and we have found + // a height, we abort the search. + if (i + 1 == nextRingIterStart) + { + if (h != RC_UNSET_HEIGHT) + break; + + nextRingIterStart += nextRingIters; + nextRingIters += 8; + } + + if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) + { + int tmp = dx; + dx = -dz; + dz = tmp; + } + x += dx; + z += dz; + } + } + return h; +} + + +enum EdgeValues +{ + EV_UNDEF = -1, + EV_HULL = -2, +}; + +static int findEdge(const int* edges, int nedges, int s, int t) +{ + for (int i = 0; i < nedges; i++) + { + const int* e = &edges[i*4]; + if ((e[0] == s && e[1] == t) || (e[0] == t && e[1] == s)) + return i; + } + return EV_UNDEF; +} + +static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges, int s, int t, int l, int r) +{ + if (nedges >= maxEdges) + { + ctx->log(RC_LOG_ERROR, "addEdge: Too many edges (%d/%d).", nedges, maxEdges); + return EV_UNDEF; + } + + // Add edge if not already in the triangulation. + int e = findEdge(edges, nedges, s, t); + if (e == EV_UNDEF) + { + int* edge = &edges[nedges*4]; + edge[0] = s; + edge[1] = t; + edge[2] = l; + edge[3] = r; + return nedges++; + } + else + { + return EV_UNDEF; + } +} + +static void updateLeftFace(int* e, int s, int t, int f) +{ + if (e[0] == s && e[1] == t && e[2] == EV_UNDEF) + e[2] = f; + else if (e[1] == s && e[0] == t && e[3] == EV_UNDEF) + e[3] = f; +} + +static int overlapSegSeg2d(const float* a, const float* b, const float* c, const float* d) +{ + const float a1 = vcross2(a, b, d); + const float a2 = vcross2(a, b, c); + if (a1*a2 < 0.0f) + { + float a3 = vcross2(c, d, a); + float a4 = a3 + a2 - a1; + if (a3 * a4 < 0.0f) + return 1; + } + return 0; +} + +static bool overlapEdges(const float* pts, const int* edges, int nedges, int s1, int t1) +{ + for (int i = 0; i < nedges; ++i) + { + const int s0 = edges[i*4+0]; + const int t0 = edges[i*4+1]; + // Same or connected edges do not overlap. + if (s0 == s1 || s0 == t1 || t0 == s1 || t0 == t1) + continue; + if (overlapSegSeg2d(&pts[s0*3],&pts[t0*3], &pts[s1*3],&pts[t1*3])) + return true; + } + return false; +} + +static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges, int& nedges, const int maxEdges, int& nfaces, int e) +{ + static const float EPS = 1e-5f; + + int* edge = &edges[e*4]; + + // Cache s and t. + int s,t; + if (edge[2] == EV_UNDEF) + { + s = edge[0]; + t = edge[1]; + } + else if (edge[3] == EV_UNDEF) + { + s = edge[1]; + t = edge[0]; + } + else + { + // Edge already completed. + return; + } + + // Find best point on left of edge. + int pt = npts; + float c[3] = {0,0,0}; + float r = -1; + for (int u = 0; u < npts; ++u) + { + if (u == s || u == t) continue; + if (vcross2(&pts[s*3], &pts[t*3], &pts[u*3]) > EPS) + { + if (r < 0) + { + // The circle is not updated yet, do it now. + pt = u; + circumCircle(&pts[s*3], &pts[t*3], &pts[u*3], c, r); + continue; + } + const float d = vdist2(c, &pts[u*3]); + const float tol = 0.001f; + if (d > r*(1+tol)) + { + // Outside current circumcircle, skip. + continue; + } + else if (d < r*(1-tol)) + { + // Inside safe circumcircle, update circle. + pt = u; + circumCircle(&pts[s*3], &pts[t*3], &pts[u*3], c, r); + } + else + { + // Inside epsilon circum circle, do extra tests to make sure the edge is valid. + // s-u and t-u cannot overlap with s-pt nor t-pt if they exists. + if (overlapEdges(pts, edges, nedges, s,u)) + continue; + if (overlapEdges(pts, edges, nedges, t,u)) + continue; + // Edge is valid. + pt = u; + circumCircle(&pts[s*3], &pts[t*3], &pts[u*3], c, r); + } + } + } + + // Add new triangle or update edge info if s-t is on hull. + if (pt < npts) + { + // Update face information of edge being completed. + updateLeftFace(&edges[e*4], s, t, nfaces); + + // Add new edge or update face info of old edge. + e = findEdge(edges, nedges, pt, s); + if (e == EV_UNDEF) + addEdge(ctx, edges, nedges, maxEdges, pt, s, nfaces, EV_UNDEF); + else + updateLeftFace(&edges[e*4], pt, s, nfaces); + + // Add new edge or update face info of old edge. + e = findEdge(edges, nedges, t, pt); + if (e == EV_UNDEF) + addEdge(ctx, edges, nedges, maxEdges, t, pt, nfaces, EV_UNDEF); + else + updateLeftFace(&edges[e*4], t, pt, nfaces); + + nfaces++; + } + else + { + updateLeftFace(&edges[e*4], s, t, EV_HULL); + } +} + +static void delaunayHull(rcContext* ctx, const int npts, const float* pts, + const int nhull, const int* hull, + rcIntArray& tris, rcIntArray& edges) +{ + int nfaces = 0; + int nedges = 0; + const int maxEdges = npts*10; + edges.resize(maxEdges*4); + + for (int i = 0, j = nhull-1; i < nhull; j=i++) + addEdge(ctx, &edges[0], nedges, maxEdges, hull[j],hull[i], EV_HULL, EV_UNDEF); + + int currentEdge = 0; + while (currentEdge < nedges) + { + if (edges[currentEdge*4+2] == EV_UNDEF) + completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge); + if (edges[currentEdge*4+3] == EV_UNDEF) + completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge); + currentEdge++; + } + + // Create tris + tris.resize(nfaces*4); + for (int i = 0; i < nfaces*4; ++i) + tris[i] = -1; + + for (int i = 0; i < nedges; ++i) + { + const int* e = &edges[i*4]; + if (e[3] >= 0) + { + // Left face + int* t = &tris[e[3]*4]; + if (t[0] == -1) + { + t[0] = e[0]; + t[1] = e[1]; + } + else if (t[0] == e[1]) + t[2] = e[0]; + else if (t[1] == e[0]) + t[2] = e[1]; + } + if (e[2] >= 0) + { + // Right + int* t = &tris[e[2]*4]; + if (t[0] == -1) + { + t[0] = e[1]; + t[1] = e[0]; + } + else if (t[0] == e[0]) + t[2] = e[1]; + else if (t[1] == e[1]) + t[2] = e[0]; + } + } + + for (int i = 0; i < tris.size()/4; ++i) + { + int* t = &tris[i*4]; + if (t[0] == -1 || t[1] == -1 || t[2] == -1) + { + ctx->log(RC_LOG_WARNING, "delaunayHull: Removing dangling face %d [%d,%d,%d].", i, t[0],t[1],t[2]); + t[0] = tris[tris.size()-4]; + t[1] = tris[tris.size()-3]; + t[2] = tris[tris.size()-2]; + t[3] = tris[tris.size()-1]; + tris.resize(tris.size()-4); + --i; + } + } +} + +// Calculate minimum extend of the polygon. +static float polyMinExtent(const float* verts, const int nverts) +{ + float minDist = FLT_MAX; + for (int i = 0; i < nverts; i++) + { + const int ni = (i+1) % nverts; + const float* p1 = &verts[i*3]; + const float* p2 = &verts[ni*3]; + float maxEdgeDist = 0; + for (int j = 0; j < nverts; j++) + { + if (j == i || j == ni) continue; + float d = distancePtSeg2d(&verts[j*3], p1,p2); + maxEdgeDist = rcMax(maxEdgeDist, d); + } + minDist = rcMin(minDist, maxEdgeDist); + } + return rcSqrt(minDist); +} + +// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv). +inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; } +inline int next(int i, int n) { return i+1 < n ? i+1 : 0; } + +static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, rcIntArray& tris) +{ + int start = 0, left = 1, right = nhull-1; + + // Start from an ear with shortest perimeter. + // This tends to favor well formed triangles as starting point. + float dmin = 0; + for (int i = 0; i < nhull; i++) + { + int pi = prev(i, nhull); + int ni = next(i, nhull); + const float* pv = &verts[hull[pi]*3]; + const float* cv = &verts[hull[i]*3]; + const float* nv = &verts[hull[ni]*3]; + const float d = vdist2(pv,cv) + vdist2(cv,nv) + vdist2(nv,pv); + if (d < dmin) + { + start = i; + left = ni; + right = pi; + dmin = d; + } + } + + // Add first triangle + tris.push(hull[start]); + tris.push(hull[left]); + tris.push(hull[right]); + tris.push(0); + + // Triangulate the polygon by moving left or right, + // depending on which triangle has shorter perimeter. + // This heuristic was chose emprically, since it seems + // handle tesselated straight edges well. + while (next(left, nhull) != right) + { + // Check to see if se should advance left or right. + int nleft = next(left, nhull); + int nright = prev(right, nhull); + + const float* cvleft = &verts[hull[left]*3]; + const float* nvleft = &verts[hull[nleft]*3]; + const float* cvright = &verts[hull[right]*3]; + const float* nvright = &verts[hull[nright]*3]; + const float dleft = vdist2(cvleft, nvleft) + vdist2(nvleft, cvright); + const float dright = vdist2(cvright, nvright) + vdist2(cvleft, nvright); + + if (dleft < dright) + { + tris.push(hull[left]); + tris.push(hull[nleft]); + tris.push(hull[right]); + tris.push(0); + left = nleft; + } + else + { + tris.push(hull[left]); + tris.push(hull[nright]); + tris.push(hull[right]); + tris.push(0); + right = nright; + } + } +} + + +inline float getJitterX(const int i) +{ + return (((i * 0x8da6b343) & 0xffff) / 65535.0f * 2.0f) - 1.0f; +} + +inline float getJitterY(const int i) +{ + return (((i * 0xd8163841) & 0xffff) / 65535.0f * 2.0f) - 1.0f; +} + +static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin, + const float sampleDist, const float sampleMaxError, + const int heightSearchRadius, const rcCompactHeightfield& chf, + const rcHeightPatch& hp, float* verts, int& nverts, + rcIntArray& tris, rcIntArray& edges, rcIntArray& samples) +{ + static const int MAX_VERTS = 127; + static const int MAX_TRIS = 255; // Max tris for delaunay is 2n-2-k (n=num verts, k=num hull verts). + static const int MAX_VERTS_PER_EDGE = 32; + float edge[(MAX_VERTS_PER_EDGE+1)*3]; + int hull[MAX_VERTS]; + int nhull = 0; + + nverts = nin; + + for (int i = 0; i < nin; ++i) + rcVcopy(&verts[i*3], &in[i*3]); + + edges.resize(0); + tris.resize(0); + + const float cs = chf.cs; + const float ics = 1.0f/cs; + + // Calculate minimum extents of the polygon based on input data. + float minExtent = polyMinExtent(verts, nverts); + + // Tessellate outlines. + // This is done in separate pass in order to ensure + // seamless height values across the ply boundaries. + if (sampleDist > 0) + { + for (int i = 0, j = nin-1; i < nin; j=i++) + { + const float* vj = &in[j*3]; + const float* vi = &in[i*3]; + bool swapped = false; + // Make sure the segments are always handled in same order + // using lexological sort or else there will be seams. + if (fabsf(vj[0]-vi[0]) < 1e-6f) + { + if (vj[2] > vi[2]) + { + rcSwap(vj,vi); + swapped = true; + } + } + else + { + if (vj[0] > vi[0]) + { + rcSwap(vj,vi); + swapped = true; + } + } + // Create samples along the edge. + float dx = vi[0] - vj[0]; + float dy = vi[1] - vj[1]; + float dz = vi[2] - vj[2]; + float d = sqrtf(dx*dx + dz*dz); + int nn = 1 + (int)floorf(d/sampleDist); + if (nn >= MAX_VERTS_PER_EDGE) nn = MAX_VERTS_PER_EDGE-1; + if (nverts+nn >= MAX_VERTS) + nn = MAX_VERTS-1-nverts; + + for (int k = 0; k <= nn; ++k) + { + float u = (float)k/(float)nn; + float* pos = &edge[k*3]; + pos[0] = vj[0] + dx*u; + pos[1] = vj[1] + dy*u; + pos[2] = vj[2] + dz*u; + pos[1] = getHeight(pos[0],pos[1],pos[2], cs, ics, chf.ch, heightSearchRadius, hp)*chf.ch; + } + // Simplify samples. + int idx[MAX_VERTS_PER_EDGE] = {0,nn}; + int nidx = 2; + for (int k = 0; k < nidx-1; ) + { + const int a = idx[k]; + const int b = idx[k+1]; + const float* va = &edge[a*3]; + const float* vb = &edge[b*3]; + // Find maximum deviation along the segment. + float maxd = 0; + int maxi = -1; + for (int m = a+1; m < b; ++m) + { + float dev = distancePtSeg(&edge[m*3],va,vb); + if (dev > maxd) + { + maxd = dev; + maxi = m; + } + } + // If the max deviation is larger than accepted error, + // add new point, else continue to next segment. + if (maxi != -1 && maxd > rcSqr(sampleMaxError)) + { + for (int m = nidx; m > k; --m) + idx[m] = idx[m-1]; + idx[k+1] = maxi; + nidx++; + } + else + { + ++k; + } + } + + hull[nhull++] = j; + // Add new vertices. + if (swapped) + { + for (int k = nidx-2; k > 0; --k) + { + rcVcopy(&verts[nverts*3], &edge[idx[k]*3]); + hull[nhull++] = nverts; + nverts++; + } + } + else + { + for (int k = 1; k < nidx-1; ++k) + { + rcVcopy(&verts[nverts*3], &edge[idx[k]*3]); + hull[nhull++] = nverts; + nverts++; + } + } + } + } + + // If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points. + if (minExtent < sampleDist*2) + { + triangulateHull(nverts, verts, nhull, hull, tris); + return true; + } + + // Tessellate the base mesh. + // We're using the triangulateHull instead of delaunayHull as it tends to + // create a bit better triangulation for long thin triangles when there + // are no internal points. + triangulateHull(nverts, verts, nhull, hull, tris); + + if (tris.size() == 0) + { + // Could not triangulate the poly, make sure there is some valid data there. + ctx->log(RC_LOG_WARNING, "buildPolyDetail: Could not triangulate polygon (%d verts).", nverts); + return true; + } + + if (sampleDist > 0) + { + // Create sample locations in a grid. + float bmin[3], bmax[3]; + rcVcopy(bmin, in); + rcVcopy(bmax, in); + for (int i = 1; i < nin; ++i) + { + rcVmin(bmin, &in[i*3]); + rcVmax(bmax, &in[i*3]); + } + int x0 = (int)floorf(bmin[0]/sampleDist); + int x1 = (int)ceilf(bmax[0]/sampleDist); + int z0 = (int)floorf(bmin[2]/sampleDist); + int z1 = (int)ceilf(bmax[2]/sampleDist); + samples.resize(0); + for (int z = z0; z < z1; ++z) + { + for (int x = x0; x < x1; ++x) + { + float pt[3]; + pt[0] = x*sampleDist; + pt[1] = (bmax[1]+bmin[1])*0.5f; + pt[2] = z*sampleDist; + // Make sure the samples are not too close to the edges. + if (distToPoly(nin,in,pt) > -sampleDist/2) continue; + samples.push(x); + samples.push(getHeight(pt[0], pt[1], pt[2], cs, ics, chf.ch, heightSearchRadius, hp)); + samples.push(z); + samples.push(0); // Not added + } + } + + // Add the samples starting from the one that has the most + // error. The procedure stops when all samples are added + // or when the max error is within treshold. + const int nsamples = samples.size()/4; + for (int iter = 0; iter < nsamples; ++iter) + { + if (nverts >= MAX_VERTS) + break; + + // Find sample with most error. + float bestpt[3] = {0,0,0}; + float bestd = 0; + int besti = -1; + for (int i = 0; i < nsamples; ++i) + { + const int* s = &samples[i*4]; + if (s[3]) continue; // skip added. + float pt[3]; + // The sample location is jittered to get rid of some bad triangulations + // which are cause by symmetrical data from the grid structure. + pt[0] = s[0]*sampleDist + getJitterX(i)*cs*0.1f; + pt[1] = s[1]*chf.ch; + pt[2] = s[2]*sampleDist + getJitterY(i)*cs*0.1f; + float d = distToTriMesh(pt, verts, nverts, &tris[0], tris.size()/4); + if (d < 0) continue; // did not hit the mesh. + if (d > bestd) + { + bestd = d; + besti = i; + rcVcopy(bestpt,pt); + } + } + // If the max error is within accepted threshold, stop tesselating. + if (bestd <= sampleMaxError || besti == -1) + break; + // Mark sample as added. + samples[besti*4+3] = 1; + // Add the new sample point. + rcVcopy(&verts[nverts*3],bestpt); + nverts++; + + // Create new triangulation. + // TODO: Incremental add instead of full rebuild. + edges.resize(0); + tris.resize(0); + delaunayHull(ctx, nverts, verts, nhull, hull, tris, edges); + } + } + + const int ntris = tris.size()/4; + if (ntris > MAX_TRIS) + { + tris.resize(MAX_TRIS*4); + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Shrinking triangle count from %d to max %d.", ntris, MAX_TRIS); + } + + return true; +} + +static void seedArrayWithPolyCenter(rcContext* ctx, const rcCompactHeightfield& chf, + const unsigned short* poly, const int npoly, + const unsigned short* verts, const int bs, + rcHeightPatch& hp, rcIntArray& array) +{ + // Note: Reads to the compact heightfield are offset by border size (bs) + // since border size offset is already removed from the polymesh vertices. + + static const int offset[9*2] = + { + 0,0, -1,-1, 0,-1, 1,-1, 1,0, 1,1, 0,1, -1,1, -1,0, + }; + + // Find cell closest to a poly vertex + int startCellX = 0, startCellY = 0, startSpanIndex = -1; + int dmin = RC_UNSET_HEIGHT; + for (int j = 0; j < npoly && dmin > 0; ++j) + { + for (int k = 0; k < 9 && dmin > 0; ++k) + { + const int ax = (int)verts[poly[j]*3+0] + offset[k*2+0]; + const int ay = (int)verts[poly[j]*3+1]; + const int az = (int)verts[poly[j]*3+2] + offset[k*2+1]; + if (ax < hp.xmin || ax >= hp.xmin+hp.width || + az < hp.ymin || az >= hp.ymin+hp.height) + continue; + + const rcCompactCell& c = chf.cells[(ax+bs)+(az+bs)*chf.width]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni && dmin > 0; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + int d = rcAbs(ay - (int)s.y); + if (d < dmin) + { + startCellX = ax; + startCellY = az; + startSpanIndex = i; + dmin = d; + } + } + } + } + + rcAssert(startSpanIndex != -1); + // Find center of the polygon + int pcx = 0, pcy = 0; + for (int j = 0; j < npoly; ++j) + { + pcx += (int)verts[poly[j]*3+0]; + pcy += (int)verts[poly[j]*3+2]; + } + pcx /= npoly; + pcy /= npoly; + + // Use seeds array as a stack for DFS + array.resize(0); + array.push(startCellX); + array.push(startCellY); + array.push(startSpanIndex); + + int dirs[] = { 0, 1, 2, 3 }; + memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height); + // DFS to move to the center. Note that we need a DFS here and can not just move + // directly towards the center without recording intermediate nodes, even though the polygons + // are convex. In very rare we can get stuck due to contour simplification if we do not + // record nodes. + int cx = -1, cy = -1, ci = -1; + while (true) + { + if (array.size() < 3) + { + ctx->log(RC_LOG_WARNING, "Walk towards polygon center failed to reach center"); + break; + } + + ci = array.pop(); + cy = array.pop(); + cx = array.pop(); + + if (cx == pcx && cy == pcy) + break; + + // If we are already at the correct X-position, prefer direction + // directly towards the center in the Y-axis; otherwise prefer + // direction in the X-axis + int directDir; + if (cx == pcx) + directDir = rcGetDirForOffset(0, pcy > cy ? 1 : -1); + else + directDir = rcGetDirForOffset(pcx > cx ? 1 : -1, 0); + + // Push the direct dir last so we start with this on next iteration + rcSwap(dirs[directDir], dirs[3]); + + const rcCompactSpan& cs = chf.spans[ci]; + for (int i = 0; i < 4; i++) + { + int dir = dirs[i]; + if (rcGetCon(cs, dir) == RC_NOT_CONNECTED) + continue; + + int newX = cx + rcGetDirOffsetX(dir); + int newY = cy + rcGetDirOffsetY(dir); + + int hpx = newX - hp.xmin; + int hpy = newY - hp.ymin; + if (hpx < 0 || hpx >= hp.width || hpy < 0 || hpy >= hp.height) + continue; + + if (hp.data[hpx+hpy*hp.width] != 0) + continue; + + hp.data[hpx+hpy*hp.width] = 1; + array.push(newX); + array.push(newY); + array.push((int)chf.cells[(newX+bs)+(newY+bs)*chf.width].index + rcGetCon(cs, dir)); + } + + rcSwap(dirs[directDir], dirs[3]); + } + + array.resize(0); + // getHeightData seeds are given in coordinates with borders + array.push(cx+bs); + array.push(cy+bs); + array.push(ci); + + memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height); + const rcCompactSpan& cs = chf.spans[ci]; + hp.data[cx-hp.xmin+(cy-hp.ymin)*hp.width] = cs.y; +} + + +static void push3(rcIntArray& queue, int v1, int v2, int v3) +{ + queue.resize(queue.size() + 3); + queue[queue.size() - 3] = v1; + queue[queue.size() - 2] = v2; + queue[queue.size() - 1] = v3; +} + +static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf, + const unsigned short* poly, const int npoly, + const unsigned short* verts, const int bs, + rcHeightPatch& hp, rcIntArray& queue, + int region) +{ + // Note: Reads to the compact heightfield are offset by border size (bs) + // since border size offset is already removed from the polymesh vertices. + + queue.resize(0); + // Set all heights to RC_UNSET_HEIGHT. + memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height); + + bool empty = true; + + // We cannot sample from this poly if it was created from polys + // of different regions. If it was then it could potentially be overlapping + // with polys of that region and the heights sampled here could be wrong. + if (region != RC_MULTIPLE_REGS) + { + // Copy the height from the same region, and mark region borders + // as seed points to fill the rest. + for (int hy = 0; hy < hp.height; hy++) + { + int y = hp.ymin + hy + bs; + for (int hx = 0; hx < hp.width; hx++) + { + int x = hp.xmin + hx + bs; + const rcCompactCell& c = chf.cells[x + y*chf.width]; + for (int i = (int)c.index, ni = (int)(c.index + c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + if (s.reg == region) + { + // Store height + hp.data[hx + hy*hp.width] = s.y; + empty = false; + + // If any of the neighbours is not in same region, + // add the current location as flood fill start + bool border = false; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax + ay*chf.width].index + rcGetCon(s, dir); + const rcCompactSpan& as = chf.spans[ai]; + if (as.reg != region) + { + border = true; + break; + } + } + } + if (border) + push3(queue, x, y, i); + break; + } + } + } + } + } + + // if the polygon does not contain any points from the current region (rare, but happens) + // or if it could potentially be overlapping polygons of the same region, + // then use the center as the seed point. + if (empty) + seedArrayWithPolyCenter(ctx, chf, poly, npoly, verts, bs, hp, queue); + + static const int RETRACT_SIZE = 256; + int head = 0; + + // We assume the seed is centered in the polygon, so a BFS to collect + // height data will ensure we do not move onto overlapping polygons and + // sample wrong heights. + while (head*3 < queue.size()) + { + int cx = queue[head*3+0]; + int cy = queue[head*3+1]; + int ci = queue[head*3+2]; + head++; + if (head >= RETRACT_SIZE) + { + head = 0; + if (queue.size() > RETRACT_SIZE*3) + memmove(&queue[0], &queue[RETRACT_SIZE*3], sizeof(int)*(queue.size()-RETRACT_SIZE*3)); + queue.resize(queue.size()-RETRACT_SIZE*3); + } + + const rcCompactSpan& cs = chf.spans[ci]; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(cs, dir) == RC_NOT_CONNECTED) continue; + + const int ax = cx + rcGetDirOffsetX(dir); + const int ay = cy + rcGetDirOffsetY(dir); + const int hx = ax - hp.xmin - bs; + const int hy = ay - hp.ymin - bs; + + if ((unsigned int)hx >= (unsigned int)hp.width || (unsigned int)hy >= (unsigned int)hp.height) + continue; + + if (hp.data[hx + hy*hp.width] != RC_UNSET_HEIGHT) + continue; + + const int ai = (int)chf.cells[ax + ay*chf.width].index + rcGetCon(cs, dir); + const rcCompactSpan& as = chf.spans[ai]; + + hp.data[hx + hy*hp.width] = as.y; + + push3(queue, ax, ay, ai); + } + } +} + +static unsigned char getEdgeFlags(const float* va, const float* vb, + const float* vpoly, const int npoly) +{ + // Return true if edge (va,vb) is part of the polygon. + static const float thrSqr = rcSqr(0.001f); + for (int i = 0, j = npoly-1; i < npoly; j=i++) + { + if (distancePtSeg2d(va, &vpoly[j*3], &vpoly[i*3]) < thrSqr && + distancePtSeg2d(vb, &vpoly[j*3], &vpoly[i*3]) < thrSqr) + return 1; + } + return 0; +} + +static unsigned char getTriFlags(const float* va, const float* vb, const float* vc, + const float* vpoly, const int npoly) +{ + unsigned char flags = 0; + flags |= getEdgeFlags(va,vb,vpoly,npoly) << 0; + flags |= getEdgeFlags(vb,vc,vpoly,npoly) << 2; + flags |= getEdgeFlags(vc,va,vpoly,npoly) << 4; + return flags; +} + +/// @par +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig +bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf, + const float sampleDist, const float sampleMaxError, + rcPolyMeshDetail& dmesh) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_POLYMESHDETAIL); + + if (mesh.nverts == 0 || mesh.npolys == 0) + return true; + + const int nvp = mesh.nvp; + const float cs = mesh.cs; + const float ch = mesh.ch; + const float* orig = mesh.bmin; + const int borderSize = mesh.borderSize; + const int heightSearchRadius = rcMax(1, (int)ceilf(mesh.maxEdgeError)); + + rcIntArray edges(64); + rcIntArray tris(512); + rcIntArray arr(512); + rcIntArray samples(512); + float verts[256*3]; + rcHeightPatch hp; + int nPolyVerts = 0; + int maxhw = 0, maxhh = 0; + + rcScopedDelete bounds((int*)rcAlloc(sizeof(int)*mesh.npolys*4, RC_ALLOC_TEMP)); + if (!bounds) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4); + return false; + } + rcScopedDelete poly((float*)rcAlloc(sizeof(float)*nvp*3, RC_ALLOC_TEMP)); + if (!poly) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'poly' (%d).", nvp*3); + return false; + } + + // Find max size for a polygon area. + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + int& xmin = bounds[i*4+0]; + int& xmax = bounds[i*4+1]; + int& ymin = bounds[i*4+2]; + int& ymax = bounds[i*4+3]; + xmin = chf.width; + xmax = 0; + ymin = chf.height; + ymax = 0; + for (int j = 0; j < nvp; ++j) + { + if(p[j] == RC_MESH_NULL_IDX) break; + const unsigned short* v = &mesh.verts[p[j]*3]; + xmin = rcMin(xmin, (int)v[0]); + xmax = rcMax(xmax, (int)v[0]); + ymin = rcMin(ymin, (int)v[2]); + ymax = rcMax(ymax, (int)v[2]); + nPolyVerts++; + } + xmin = rcMax(0,xmin-1); + xmax = rcMin(chf.width,xmax+1); + ymin = rcMax(0,ymin-1); + ymax = rcMin(chf.height,ymax+1); + if (xmin >= xmax || ymin >= ymax) continue; + maxhw = rcMax(maxhw, xmax-xmin); + maxhh = rcMax(maxhh, ymax-ymin); + } + + hp.data = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxhw*maxhh, RC_ALLOC_TEMP); + if (!hp.data) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh); + return false; + } + + dmesh.nmeshes = mesh.npolys; + dmesh.nverts = 0; + dmesh.ntris = 0; + dmesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*dmesh.nmeshes*4, RC_ALLOC_PERM); + if (!dmesh.meshes) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4); + return false; + } + + int vcap = nPolyVerts+nPolyVerts/2; + int tcap = vcap*2; + + dmesh.nverts = 0; + dmesh.verts = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM); + if (!dmesh.verts) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3); + return false; + } + dmesh.ntris = 0; + dmesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char)*tcap*4, RC_ALLOC_PERM); + if (!dmesh.tris) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4); + return false; + } + + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + + // Store polygon vertices for processing. + int npoly = 0; + for (int j = 0; j < nvp; ++j) + { + if(p[j] == RC_MESH_NULL_IDX) break; + const unsigned short* v = &mesh.verts[p[j]*3]; + poly[j*3+0] = v[0]*cs; + poly[j*3+1] = v[1]*ch; + poly[j*3+2] = v[2]*cs; + npoly++; + } + + // Get the height data from the area of the polygon. + hp.xmin = bounds[i*4+0]; + hp.ymin = bounds[i*4+2]; + hp.width = bounds[i*4+1]-bounds[i*4+0]; + hp.height = bounds[i*4+3]-bounds[i*4+2]; + getHeightData(ctx, chf, p, npoly, mesh.verts, borderSize, hp, arr, mesh.regs[i]); + + // Build detail mesh. + int nverts = 0; + if (!buildPolyDetail(ctx, poly, npoly, + sampleDist, sampleMaxError, + heightSearchRadius, chf, hp, + verts, nverts, tris, + edges, samples)) + { + return false; + } + + // Move detail verts to world space. + for (int j = 0; j < nverts; ++j) + { + verts[j*3+0] += orig[0]; + verts[j*3+1] += orig[1] + chf.ch; // Is this offset necessary? + verts[j*3+2] += orig[2]; + } + // Offset poly too, will be used to flag checking. + for (int j = 0; j < npoly; ++j) + { + poly[j*3+0] += orig[0]; + poly[j*3+1] += orig[1]; + poly[j*3+2] += orig[2]; + } + + // Store detail submesh. + const int ntris = tris.size()/4; + + dmesh.meshes[i*4+0] = (unsigned int)dmesh.nverts; + dmesh.meshes[i*4+1] = (unsigned int)nverts; + dmesh.meshes[i*4+2] = (unsigned int)dmesh.ntris; + dmesh.meshes[i*4+3] = (unsigned int)ntris; + + // Store vertices, allocate more memory if necessary. + if (dmesh.nverts+nverts > vcap) + { + while (dmesh.nverts+nverts > vcap) + vcap += 256; + + float* newv = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM); + if (!newv) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newv' (%d).", vcap*3); + return false; + } + if (dmesh.nverts) + memcpy(newv, dmesh.verts, sizeof(float)*3*dmesh.nverts); + rcFree(dmesh.verts); + dmesh.verts = newv; + } + for (int j = 0; j < nverts; ++j) + { + dmesh.verts[dmesh.nverts*3+0] = verts[j*3+0]; + dmesh.verts[dmesh.nverts*3+1] = verts[j*3+1]; + dmesh.verts[dmesh.nverts*3+2] = verts[j*3+2]; + dmesh.nverts++; + } + + // Store triangles, allocate more memory if necessary. + if (dmesh.ntris+ntris > tcap) + { + while (dmesh.ntris+ntris > tcap) + tcap += 256; + unsigned char* newt = (unsigned char*)rcAlloc(sizeof(unsigned char)*tcap*4, RC_ALLOC_PERM); + if (!newt) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newt' (%d).", tcap*4); + return false; + } + if (dmesh.ntris) + memcpy(newt, dmesh.tris, sizeof(unsigned char)*4*dmesh.ntris); + rcFree(dmesh.tris); + dmesh.tris = newt; + } + for (int j = 0; j < ntris; ++j) + { + const int* t = &tris[j*4]; + dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0]; + dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1]; + dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2]; + dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[1]*3], &verts[t[2]*3], poly, npoly); + dmesh.ntris++; + } + } + + return true; +} + +/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail +bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_MERGE_POLYMESHDETAIL); + + int maxVerts = 0; + int maxTris = 0; + int maxMeshes = 0; + + for (int i = 0; i < nmeshes; ++i) + { + if (!meshes[i]) continue; + maxVerts += meshes[i]->nverts; + maxTris += meshes[i]->ntris; + maxMeshes += meshes[i]->nmeshes; + } + + mesh.nmeshes = 0; + mesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*maxMeshes*4, RC_ALLOC_PERM); + if (!mesh.meshes) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'pmdtl.meshes' (%d).", maxMeshes*4); + return false; + } + + mesh.ntris = 0; + mesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxTris*4, RC_ALLOC_PERM); + if (!mesh.tris) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", maxTris*4); + return false; + } + + mesh.nverts = 0; + mesh.verts = (float*)rcAlloc(sizeof(float)*maxVerts*3, RC_ALLOC_PERM); + if (!mesh.verts) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", maxVerts*3); + return false; + } + + // Merge datas. + for (int i = 0; i < nmeshes; ++i) + { + rcPolyMeshDetail* dm = meshes[i]; + if (!dm) continue; + for (int j = 0; j < dm->nmeshes; ++j) + { + unsigned int* dst = &mesh.meshes[mesh.nmeshes*4]; + unsigned int* src = &dm->meshes[j*4]; + dst[0] = (unsigned int)mesh.nverts+src[0]; + dst[1] = src[1]; + dst[2] = (unsigned int)mesh.ntris+src[2]; + dst[3] = src[3]; + mesh.nmeshes++; + } + + for (int k = 0; k < dm->nverts; ++k) + { + rcVcopy(&mesh.verts[mesh.nverts*3], &dm->verts[k*3]); + mesh.nverts++; + } + for (int k = 0; k < dm->ntris; ++k) + { + mesh.tris[mesh.ntris*4+0] = dm->tris[k*4+0]; + mesh.tris[mesh.ntris*4+1] = dm->tris[k*4+1]; + mesh.tris[mesh.ntris*4+2] = dm->tris[k*4+2]; + mesh.tris[mesh.ntris*4+3] = dm->tris[k*4+3]; + mesh.ntris++; + } + } + + return true; +} diff --git a/libs/recast/recast/src/RecastRasterization.cpp b/libs/recast/recast/src/RecastRasterization.cpp new file mode 100644 index 000000000..a4cef7490 --- /dev/null +++ b/libs/recast/recast/src/RecastRasterization.cpp @@ -0,0 +1,454 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#define _USE_MATH_DEFINES +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" + +inline bool overlapBounds(const float* amin, const float* amax, const float* bmin, const float* bmax) +{ + bool overlap = true; + overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap; + overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap; + overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap; + return overlap; +} + +inline bool overlapInterval(unsigned short amin, unsigned short amax, + unsigned short bmin, unsigned short bmax) +{ + if (amax < bmin) return false; + if (amin > bmax) return false; + return true; +} + + +static rcSpan* allocSpan(rcHeightfield& hf) +{ + // If running out of memory, allocate new page and update the freelist. + if (!hf.freelist || !hf.freelist->next) + { + // Create new page. + // Allocate memory for the new pool. + rcSpanPool* pool = (rcSpanPool*)rcAlloc(sizeof(rcSpanPool), RC_ALLOC_PERM); + if (!pool) return 0; + + // Add the pool into the list of pools. + pool->next = hf.pools; + hf.pools = pool; + // Add new items to the free list. + rcSpan* freelist = hf.freelist; + rcSpan* head = &pool->items[0]; + rcSpan* it = &pool->items[RC_SPANS_PER_POOL]; + do + { + --it; + it->next = freelist; + freelist = it; + } + while (it != head); + hf.freelist = it; + } + + // Pop item from in front of the free list. + rcSpan* it = hf.freelist; + hf.freelist = hf.freelist->next; + return it; +} + +static void freeSpan(rcHeightfield& hf, rcSpan* ptr) +{ + if (!ptr) return; + // Add the node in front of the free list. + ptr->next = hf.freelist; + hf.freelist = ptr; +} + +static bool addSpan(rcHeightfield& hf, const int x, const int y, + const unsigned short smin, const unsigned short smax, + const unsigned char area, const int flagMergeThr) +{ + + int idx = x + y*hf.width; + + rcSpan* s = allocSpan(hf); + if (!s) + return false; + s->smin = smin; + s->smax = smax; + s->area = area; + s->next = 0; + + // Empty cell, add the first span. + if (!hf.spans[idx]) + { + hf.spans[idx] = s; + return true; + } + rcSpan* prev = 0; + rcSpan* cur = hf.spans[idx]; + + // Insert and merge spans. + while (cur) + { + if (cur->smin > s->smax) + { + // Current span is further than the new span, break. + break; + } + else if (cur->smax < s->smin) + { + // Current span is before the new span advance. + prev = cur; + cur = cur->next; + } + else + { + // Merge spans. + if (cur->smin < s->smin) + s->smin = cur->smin; + if (cur->smax > s->smax) + s->smax = cur->smax; + + // Merge flags. + if (rcAbs((int)s->smax - (int)cur->smax) <= flagMergeThr) + s->area = rcMax(s->area, cur->area); + + // Remove current span. + rcSpan* next = cur->next; + freeSpan(hf, cur); + if (prev) + prev->next = next; + else + hf.spans[idx] = next; + cur = next; + } + } + + // Insert new span. + if (prev) + { + s->next = prev->next; + prev->next = s; + } + else + { + s->next = hf.spans[idx]; + hf.spans[idx] = s; + } + + return true; +} + +/// @par +/// +/// The span addition can be set to favor flags. If the span is merged to +/// another span and the new @p smax is within @p flagMergeThr units +/// from the existing span, the span flags are merged. +/// +/// @see rcHeightfield, rcSpan. +bool rcAddSpan(rcContext* ctx, rcHeightfield& hf, const int x, const int y, + const unsigned short smin, const unsigned short smax, + const unsigned char area, const int flagMergeThr) +{ + rcAssert(ctx); + + if (!addSpan(hf, x, y, smin, smax, area, flagMergeThr)) + { + ctx->log(RC_LOG_ERROR, "rcAddSpan: Out of memory."); + return false; + } + + return true; +} + +// divides a convex polygons into two convex polygons on both sides of a line +static void dividePoly(const float* in, int nin, + float* out1, int* nout1, + float* out2, int* nout2, + float x, int axis) +{ + float d[12]; + for (int i = 0; i < nin; ++i) + d[i] = x - in[i*3+axis]; + + int m = 0, n = 0; + for (int i = 0, j = nin-1; i < nin; j=i, ++i) + { + bool ina = d[j] >= 0; + bool inb = d[i] >= 0; + if (ina != inb) + { + float s = d[j] / (d[j] - d[i]); + out1[m*3+0] = in[j*3+0] + (in[i*3+0] - in[j*3+0])*s; + out1[m*3+1] = in[j*3+1] + (in[i*3+1] - in[j*3+1])*s; + out1[m*3+2] = in[j*3+2] + (in[i*3+2] - in[j*3+2])*s; + rcVcopy(out2 + n*3, out1 + m*3); + m++; + n++; + // add the i'th point to the right polygon. Do NOT add points that are on the dividing line + // since these were already added above + if (d[i] > 0) + { + rcVcopy(out1 + m*3, in + i*3); + m++; + } + else if (d[i] < 0) + { + rcVcopy(out2 + n*3, in + i*3); + n++; + } + } + else // same side + { + // add the i'th point to the right polygon. Addition is done even for points on the dividing line + if (d[i] >= 0) + { + rcVcopy(out1 + m*3, in + i*3); + m++; + if (d[i] != 0) + continue; + } + rcVcopy(out2 + n*3, in + i*3); + n++; + } + } + + *nout1 = m; + *nout2 = n; +} + + + +static bool rasterizeTri(const float* v0, const float* v1, const float* v2, + const unsigned char area, rcHeightfield& hf, + const float* bmin, const float* bmax, + const float cs, const float ics, const float ich, + const int flagMergeThr) +{ + const int w = hf.width; + const int h = hf.height; + float tmin[3], tmax[3]; + const float by = bmax[1] - bmin[1]; + + // Calculate the bounding box of the triangle. + rcVcopy(tmin, v0); + rcVcopy(tmax, v0); + rcVmin(tmin, v1); + rcVmin(tmin, v2); + rcVmax(tmax, v1); + rcVmax(tmax, v2); + + // If the triangle does not touch the bbox of the heightfield, skip the triagle. + if (!overlapBounds(bmin, bmax, tmin, tmax)) + return true; + + // Calculate the footprint of the triangle on the grid's y-axis + int y0 = (int)((tmin[2] - bmin[2])*ics); + int y1 = (int)((tmax[2] - bmin[2])*ics); + y0 = rcClamp(y0, 0, h-1); + y1 = rcClamp(y1, 0, h-1); + + // Clip the triangle into all grid cells it touches. + float buf[7*3*4]; + float *in = buf, *inrow = buf+7*3, *p1 = inrow+7*3, *p2 = p1+7*3; + + rcVcopy(&in[0], v0); + rcVcopy(&in[1*3], v1); + rcVcopy(&in[2*3], v2); + int nvrow, nvIn = 3; + + for (int y = y0; y <= y1; ++y) + { + // Clip polygon to row. Store the remaining polygon as well + const float cz = bmin[2] + y*cs; + dividePoly(in, nvIn, inrow, &nvrow, p1, &nvIn, cz+cs, 2); + rcSwap(in, p1); + if (nvrow < 3) continue; + + // find the horizontal bounds in the row + float minX = inrow[0], maxX = inrow[0]; + for (int i=1; i inrow[i*3]) minX = inrow[i*3]; + if (maxX < inrow[i*3]) maxX = inrow[i*3]; + } + int x0 = (int)((minX - bmin[0])*ics); + int x1 = (int)((maxX - bmin[0])*ics); + x0 = rcClamp(x0, 0, w-1); + x1 = rcClamp(x1, 0, w-1); + + int nv, nv2 = nvrow; + + for (int x = x0; x <= x1; ++x) + { + // Clip polygon to column. store the remaining polygon as well + const float cx = bmin[0] + x*cs; + dividePoly(inrow, nv2, p1, &nv, p2, &nv2, cx+cs, 0); + rcSwap(inrow, p2); + if (nv < 3) continue; + + // Calculate min and max of the span. + float smin = p1[1], smax = p1[1]; + for (int i = 1; i < nv; ++i) + { + smin = rcMin(smin, p1[i*3+1]); + smax = rcMax(smax, p1[i*3+1]); + } + smin -= bmin[1]; + smax -= bmin[1]; + // Skip the span if it is outside the heightfield bbox + if (smax < 0.0f) continue; + if (smin > by) continue; + // Clamp the span to the heightfield bbox. + if (smin < 0.0f) smin = 0; + if (smax > by) smax = by; + + // Snap the span to the heightfield height grid. + unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, RC_SPAN_MAX_HEIGHT); + unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), (int)ismin+1, RC_SPAN_MAX_HEIGHT); + + if (!addSpan(hf, x, y, ismin, ismax, area, flagMergeThr)) + return false; + } + } + + return true; +} + +/// @par +/// +/// No spans will be added if the triangle does not overlap the heightfield grid. +/// +/// @see rcHeightfield +bool rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2, + const unsigned char area, rcHeightfield& solid, + const int flagMergeThr) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES); + + const float ics = 1.0f/solid.cs; + const float ich = 1.0f/solid.ch; + if (!rasterizeTri(v0, v1, v2, area, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr)) + { + ctx->log(RC_LOG_ERROR, "rcRasterizeTriangle: Out of memory."); + return false; + } + + return true; +} + +/// @par +/// +/// Spans will only be added for triangles that overlap the heightfield grid. +/// +/// @see rcHeightfield +bool rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/, + const int* tris, const unsigned char* areas, const int nt, + rcHeightfield& solid, const int flagMergeThr) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES); + + const float ics = 1.0f/solid.cs; + const float ich = 1.0f/solid.ch; + // Rasterize triangles. + for (int i = 0; i < nt; ++i) + { + const float* v0 = &verts[tris[i*3+0]*3]; + const float* v1 = &verts[tris[i*3+1]*3]; + const float* v2 = &verts[tris[i*3+2]*3]; + // Rasterize. + if (!rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr)) + { + ctx->log(RC_LOG_ERROR, "rcRasterizeTriangles: Out of memory."); + return false; + } + } + + return true; +} + +/// @par +/// +/// Spans will only be added for triangles that overlap the heightfield grid. +/// +/// @see rcHeightfield +bool rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/, + const unsigned short* tris, const unsigned char* areas, const int nt, + rcHeightfield& solid, const int flagMergeThr) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES); + + const float ics = 1.0f/solid.cs; + const float ich = 1.0f/solid.ch; + // Rasterize triangles. + for (int i = 0; i < nt; ++i) + { + const float* v0 = &verts[tris[i*3+0]*3]; + const float* v1 = &verts[tris[i*3+1]*3]; + const float* v2 = &verts[tris[i*3+2]*3]; + // Rasterize. + if (!rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr)) + { + ctx->log(RC_LOG_ERROR, "rcRasterizeTriangles: Out of memory."); + return false; + } + } + + return true; +} + +/// @par +/// +/// Spans will only be added for triangles that overlap the heightfield grid. +/// +/// @see rcHeightfield +bool rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt, + rcHeightfield& solid, const int flagMergeThr) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_RASTERIZE_TRIANGLES); + + const float ics = 1.0f/solid.cs; + const float ich = 1.0f/solid.ch; + // Rasterize triangles. + for (int i = 0; i < nt; ++i) + { + const float* v0 = &verts[(i*3+0)*3]; + const float* v1 = &verts[(i*3+1)*3]; + const float* v2 = &verts[(i*3+2)*3]; + // Rasterize. + if (!rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr)) + { + ctx->log(RC_LOG_ERROR, "rcRasterizeTriangles: Out of memory."); + return false; + } + } + + return true; +} diff --git a/libs/recast/recast/src/RecastRegion.cpp b/libs/recast/recast/src/RecastRegion.cpp new file mode 100644 index 000000000..38a2bd6bf --- /dev/null +++ b/libs/recast/recast/src/RecastRegion.cpp @@ -0,0 +1,1824 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// 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. +// + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastAlloc.h" +#include "RecastAssert.h" +#include + + +static void calculateDistanceField(rcCompactHeightfield& chf, unsigned short* src, unsigned short& maxDist) +{ + const int w = chf.width; + const int h = chf.height; + + // Init distance and points. + for (int i = 0; i < chf.spanCount; ++i) + src[i] = 0xffff; + + // Mark boundary cells. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + const unsigned char area = chf.areas[i]; + + int nc = 0; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + if (area == chf.areas[ai]) + nc++; + } + } + if (nc != 4) + src[i] = 0; + } + } + } + + + // Pass 1 + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + + if (rcGetCon(s, 0) != RC_NOT_CONNECTED) + { + // (-1,0) + const int ax = x + rcGetDirOffsetX(0); + const int ay = y + rcGetDirOffsetY(0); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0); + const rcCompactSpan& as = chf.spans[ai]; + if (src[ai]+2 < src[i]) + src[i] = src[ai]+2; + + // (-1,-1) + if (rcGetCon(as, 3) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(3); + const int aay = ay + rcGetDirOffsetY(3); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 3); + if (src[aai]+3 < src[i]) + src[i] = src[aai]+3; + } + } + if (rcGetCon(s, 3) != RC_NOT_CONNECTED) + { + // (0,-1) + const int ax = x + rcGetDirOffsetX(3); + const int ay = y + rcGetDirOffsetY(3); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3); + const rcCompactSpan& as = chf.spans[ai]; + if (src[ai]+2 < src[i]) + src[i] = src[ai]+2; + + // (1,-1) + if (rcGetCon(as, 2) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(2); + const int aay = ay + rcGetDirOffsetY(2); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 2); + if (src[aai]+3 < src[i]) + src[i] = src[aai]+3; + } + } + } + } + } + + // Pass 2 + for (int y = h-1; y >= 0; --y) + { + for (int x = w-1; x >= 0; --x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + + if (rcGetCon(s, 2) != RC_NOT_CONNECTED) + { + // (1,0) + const int ax = x + rcGetDirOffsetX(2); + const int ay = y + rcGetDirOffsetY(2); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 2); + const rcCompactSpan& as = chf.spans[ai]; + if (src[ai]+2 < src[i]) + src[i] = src[ai]+2; + + // (1,1) + if (rcGetCon(as, 1) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(1); + const int aay = ay + rcGetDirOffsetY(1); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 1); + if (src[aai]+3 < src[i]) + src[i] = src[aai]+3; + } + } + if (rcGetCon(s, 1) != RC_NOT_CONNECTED) + { + // (0,1) + const int ax = x + rcGetDirOffsetX(1); + const int ay = y + rcGetDirOffsetY(1); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 1); + const rcCompactSpan& as = chf.spans[ai]; + if (src[ai]+2 < src[i]) + src[i] = src[ai]+2; + + // (-1,1) + if (rcGetCon(as, 0) != RC_NOT_CONNECTED) + { + const int aax = ax + rcGetDirOffsetX(0); + const int aay = ay + rcGetDirOffsetY(0); + const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 0); + if (src[aai]+3 < src[i]) + src[i] = src[aai]+3; + } + } + } + } + } + + maxDist = 0; + for (int i = 0; i < chf.spanCount; ++i) + maxDist = rcMax(src[i], maxDist); + +} + +static unsigned short* boxBlur(rcCompactHeightfield& chf, int thr, + unsigned short* src, unsigned short* dst) +{ + const int w = chf.width; + const int h = chf.height; + + thr *= 2; + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + const unsigned short cd = src[i]; + if (cd <= thr) + { + dst[i] = cd; + continue; + } + + int d = (int)cd; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + d += (int)src[ai]; + + const rcCompactSpan& as = chf.spans[ai]; + const int dir2 = (dir+1) & 0x3; + if (rcGetCon(as, dir2) != RC_NOT_CONNECTED) + { + const int ax2 = ax + rcGetDirOffsetX(dir2); + const int ay2 = ay + rcGetDirOffsetY(dir2); + const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2); + d += (int)src[ai2]; + } + else + { + d += cd; + } + } + else + { + d += cd*2; + } + } + dst[i] = (unsigned short)((d+5)/9); + } + } + } + return dst; +} + + +static bool floodRegion(int x, int y, int i, + unsigned short level, unsigned short r, + rcCompactHeightfield& chf, + unsigned short* srcReg, unsigned short* srcDist, + rcIntArray& stack) +{ + const int w = chf.width; + + const unsigned char area = chf.areas[i]; + + // Flood fill mark region. + stack.resize(0); + stack.push((int)x); + stack.push((int)y); + stack.push((int)i); + srcReg[i] = r; + srcDist[i] = 0; + + unsigned short lev = level >= 2 ? level-2 : 0; + int count = 0; + + while (stack.size() > 0) + { + int ci = stack.pop(); + int cy = stack.pop(); + int cx = stack.pop(); + + const rcCompactSpan& cs = chf.spans[ci]; + + // Check if any of the neighbours already have a valid region set. + unsigned short ar = 0; + for (int dir = 0; dir < 4; ++dir) + { + // 8 connected + if (rcGetCon(cs, dir) != RC_NOT_CONNECTED) + { + const int ax = cx + rcGetDirOffsetX(dir); + const int ay = cy + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir); + if (chf.areas[ai] != area) + continue; + unsigned short nr = srcReg[ai]; + if (nr & RC_BORDER_REG) // Do not take borders into account. + continue; + if (nr != 0 && nr != r) + { + ar = nr; + break; + } + + const rcCompactSpan& as = chf.spans[ai]; + + const int dir2 = (dir+1) & 0x3; + if (rcGetCon(as, dir2) != RC_NOT_CONNECTED) + { + const int ax2 = ax + rcGetDirOffsetX(dir2); + const int ay2 = ay + rcGetDirOffsetY(dir2); + const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2); + if (chf.areas[ai2] != area) + continue; + unsigned short nr2 = srcReg[ai2]; + if (nr2 != 0 && nr2 != r) + { + ar = nr2; + break; + } + } + } + } + if (ar != 0) + { + srcReg[ci] = 0; + continue; + } + + count++; + + // Expand neighbours. + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(cs, dir) != RC_NOT_CONNECTED) + { + const int ax = cx + rcGetDirOffsetX(dir); + const int ay = cy + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir); + if (chf.areas[ai] != area) + continue; + if (chf.dist[ai] >= lev && srcReg[ai] == 0) + { + srcReg[ai] = r; + srcDist[ai] = 0; + stack.push(ax); + stack.push(ay); + stack.push(ai); + } + } + } + } + + return count > 0; +} + +static unsigned short* expandRegions(int maxIter, unsigned short level, + rcCompactHeightfield& chf, + unsigned short* srcReg, unsigned short* srcDist, + unsigned short* dstReg, unsigned short* dstDist, + rcIntArray& stack, + bool fillStack) +{ + const int w = chf.width; + const int h = chf.height; + + if (fillStack) + { + // Find cells revealed by the raised level. + stack.resize(0); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (chf.dist[i] >= level && srcReg[i] == 0 && chf.areas[i] != RC_NULL_AREA) + { + stack.push(x); + stack.push(y); + stack.push(i); + } + } + } + } + } + else // use cells in the input stack + { + // mark all cells which already have a region + for (int j=0; j 0) + { + int failed = 0; + + memcpy(dstReg, srcReg, sizeof(unsigned short)*chf.spanCount); + memcpy(dstDist, srcDist, sizeof(unsigned short)*chf.spanCount); + + for (int j = 0; j < stack.size(); j += 3) + { + int x = stack[j+0]; + int y = stack[j+1]; + int i = stack[j+2]; + if (i < 0) + { + failed++; + continue; + } + + unsigned short r = srcReg[i]; + unsigned short d2 = 0xffff; + const unsigned char area = chf.areas[i]; + const rcCompactSpan& s = chf.spans[i]; + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) == RC_NOT_CONNECTED) continue; + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + if (chf.areas[ai] != area) continue; + if (srcReg[ai] > 0 && (srcReg[ai] & RC_BORDER_REG) == 0) + { + if ((int)srcDist[ai]+2 < (int)d2) + { + r = srcReg[ai]; + d2 = srcDist[ai]+2; + } + } + } + if (r) + { + stack[j+2] = -1; // mark as used + dstReg[i] = r; + dstDist[i] = d2; + } + else + { + failed++; + } + } + + // rcSwap source and dest. + rcSwap(srcReg, dstReg); + rcSwap(srcDist, dstDist); + + if (failed*3 == stack.size()) + break; + + if (level > 0) + { + ++iter; + if (iter >= maxIter) + break; + } + } + + return srcReg; +} + + + +static void sortCellsByLevel(unsigned short startLevel, + rcCompactHeightfield& chf, + unsigned short* srcReg, + unsigned int nbStacks, rcIntArray* stacks, + unsigned short loglevelsPerStack) // the levels per stack (2 in our case) as a bit shift +{ + const int w = chf.width; + const int h = chf.height; + startLevel = startLevel >> loglevelsPerStack; + + for (unsigned int j=0; j> loglevelsPerStack; + int sId = startLevel - level; + if (sId >= (int)nbStacks) + continue; + if (sId < 0) + sId = 0; + + stacks[sId].push(x); + stacks[sId].push(y); + stacks[sId].push(i); + } + } + } +} + + +static void appendStacks(rcIntArray& srcStack, rcIntArray& dstStack, + unsigned short* srcReg) +{ + for (int j=0; j 1; ) + { + int ni = (i+1) % reg.connections.size(); + if (reg.connections[i] == reg.connections[ni]) + { + // Remove duplicate + for (int j = i; j < reg.connections.size()-1; ++j) + reg.connections[j] = reg.connections[j+1]; + reg.connections.pop(); + } + else + ++i; + } +} + +static void replaceNeighbour(rcRegion& reg, unsigned short oldId, unsigned short newId) +{ + bool neiChanged = false; + for (int i = 0; i < reg.connections.size(); ++i) + { + if (reg.connections[i] == oldId) + { + reg.connections[i] = newId; + neiChanged = true; + } + } + for (int i = 0; i < reg.floors.size(); ++i) + { + if (reg.floors[i] == oldId) + reg.floors[i] = newId; + } + if (neiChanged) + removeAdjacentNeighbours(reg); +} + +static bool canMergeWithRegion(const rcRegion& rega, const rcRegion& regb) +{ + if (rega.areaType != regb.areaType) + return false; + int n = 0; + for (int i = 0; i < rega.connections.size(); ++i) + { + if (rega.connections[i] == regb.id) + n++; + } + if (n > 1) + return false; + for (int i = 0; i < rega.floors.size(); ++i) + { + if (rega.floors[i] == regb.id) + return false; + } + return true; +} + +static void addUniqueFloorRegion(rcRegion& reg, int n) +{ + for (int i = 0; i < reg.floors.size(); ++i) + if (reg.floors[i] == n) + return; + reg.floors.push(n); +} + +static bool mergeRegions(rcRegion& rega, rcRegion& regb) +{ + unsigned short aid = rega.id; + unsigned short bid = regb.id; + + // Duplicate current neighbourhood. + rcIntArray acon; + acon.resize(rega.connections.size()); + for (int i = 0; i < rega.connections.size(); ++i) + acon[i] = rega.connections[i]; + rcIntArray& bcon = regb.connections; + + // Find insertion point on A. + int insa = -1; + for (int i = 0; i < acon.size(); ++i) + { + if (acon[i] == bid) + { + insa = i; + break; + } + } + if (insa == -1) + return false; + + // Find insertion point on B. + int insb = -1; + for (int i = 0; i < bcon.size(); ++i) + { + if (bcon[i] == aid) + { + insb = i; + break; + } + } + if (insb == -1) + return false; + + // Merge neighbours. + rega.connections.resize(0); + for (int i = 0, ni = acon.size(); i < ni-1; ++i) + rega.connections.push(acon[(insa+1+i) % ni]); + + for (int i = 0, ni = bcon.size(); i < ni-1; ++i) + rega.connections.push(bcon[(insb+1+i) % ni]); + + removeAdjacentNeighbours(rega); + + for (int j = 0; j < regb.floors.size(); ++j) + addUniqueFloorRegion(rega, regb.floors[j]); + rega.spanCount += regb.spanCount; + regb.spanCount = 0; + regb.connections.resize(0); + + return true; +} + +static bool isRegionConnectedToBorder(const rcRegion& reg) +{ + // Region is connected to border if + // one of the neighbours is null id. + for (int i = 0; i < reg.connections.size(); ++i) + { + if (reg.connections[i] == 0) + return true; + } + return false; +} + +static bool isSolidEdge(rcCompactHeightfield& chf, unsigned short* srcReg, + int x, int y, int i, int dir) +{ + const rcCompactSpan& s = chf.spans[i]; + unsigned short r = 0; + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir); + r = srcReg[ai]; + } + if (r == srcReg[i]) + return false; + return true; +} + +static void walkContour(int x, int y, int i, int dir, + rcCompactHeightfield& chf, + unsigned short* srcReg, + rcIntArray& cont) +{ + int startDir = dir; + int starti = i; + + const rcCompactSpan& ss = chf.spans[i]; + unsigned short curReg = 0; + if (rcGetCon(ss, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(ss, dir); + curReg = srcReg[ai]; + } + cont.push(curReg); + + int iter = 0; + while (++iter < 40000) + { + const rcCompactSpan& s = chf.spans[i]; + + if (isSolidEdge(chf, srcReg, x, y, i, dir)) + { + // Choose the edge corner + unsigned short r = 0; + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir); + r = srcReg[ai]; + } + if (r != curReg) + { + curReg = r; + cont.push(curReg); + } + + dir = (dir+1) & 0x3; // Rotate CW + } + else + { + int ni = -1; + const int nx = x + rcGetDirOffsetX(dir); + const int ny = y + rcGetDirOffsetY(dir); + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const rcCompactCell& nc = chf.cells[nx+ny*chf.width]; + ni = (int)nc.index + rcGetCon(s, dir); + } + if (ni == -1) + { + // Should not happen. + return; + } + x = nx; + y = ny; + i = ni; + dir = (dir+3) & 0x3; // Rotate CCW + } + + if (starti == i && startDir == dir) + { + break; + } + } + + // Remove adjacent duplicates. + if (cont.size() > 1) + { + for (int j = 0; j < cont.size(); ) + { + int nj = (j+1) % cont.size(); + if (cont[j] == cont[nj]) + { + for (int k = j; k < cont.size()-1; ++k) + cont[k] = cont[k+1]; + cont.pop(); + } + else + ++j; + } + } +} + + +static bool mergeAndFilterRegions(rcContext* ctx, int minRegionArea, int mergeRegionSize, + unsigned short& maxRegionId, + rcCompactHeightfield& chf, + unsigned short* srcReg, rcIntArray& overlaps) +{ + const int w = chf.width; + const int h = chf.height; + + const int nreg = maxRegionId+1; + rcRegion* regions = (rcRegion*)rcAlloc(sizeof(rcRegion)*nreg, RC_ALLOC_TEMP); + if (!regions) + { + ctx->log(RC_LOG_ERROR, "mergeAndFilterRegions: Out of memory 'regions' (%d).", nreg); + return false; + } + + // Construct regions + for (int i = 0; i < nreg; ++i) + new(®ions[i]) rcRegion((unsigned short)i); + + // Find edge of a region and find connections around the contour. + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + unsigned short r = srcReg[i]; + if (r == 0 || r >= nreg) + continue; + + rcRegion& reg = regions[r]; + reg.spanCount++; + + // Update floors. + for (int j = (int)c.index; j < ni; ++j) + { + if (i == j) continue; + unsigned short floorId = srcReg[j]; + if (floorId == 0 || floorId >= nreg) + continue; + if (floorId == r) + reg.overlap = true; + addUniqueFloorRegion(reg, floorId); + } + + // Have found contour + if (reg.connections.size() > 0) + continue; + + reg.areaType = chf.areas[i]; + + // Check if this cell is next to a border. + int ndir = -1; + for (int dir = 0; dir < 4; ++dir) + { + if (isSolidEdge(chf, srcReg, x, y, i, dir)) + { + ndir = dir; + break; + } + } + + if (ndir != -1) + { + // The cell is at border. + // Walk around the contour to find all the neighbours. + walkContour(x, y, i, ndir, chf, srcReg, reg.connections); + } + } + } + } + + // Remove too small regions. + rcIntArray stack(32); + rcIntArray trace(32); + for (int i = 0; i < nreg; ++i) + { + rcRegion& reg = regions[i]; + if (reg.id == 0 || (reg.id & RC_BORDER_REG)) + continue; + if (reg.spanCount == 0) + continue; + if (reg.visited) + continue; + + // Count the total size of all the connected regions. + // Also keep track of the regions connects to a tile border. + bool connectsToBorder = false; + int spanCount = 0; + stack.resize(0); + trace.resize(0); + + reg.visited = true; + stack.push(i); + + while (stack.size()) + { + // Pop + int ri = stack.pop(); + + rcRegion& creg = regions[ri]; + + spanCount += creg.spanCount; + trace.push(ri); + + for (int j = 0; j < creg.connections.size(); ++j) + { + if (creg.connections[j] & RC_BORDER_REG) + { + connectsToBorder = true; + continue; + } + rcRegion& neireg = regions[creg.connections[j]]; + if (neireg.visited) + continue; + if (neireg.id == 0 || (neireg.id & RC_BORDER_REG)) + continue; + // Visit + stack.push(neireg.id); + neireg.visited = true; + } + } + + // If the accumulated regions size is too small, remove it. + // Do not remove areas which connect to tile borders + // as their size cannot be estimated correctly and removing them + // can potentially remove necessary areas. + if (spanCount < minRegionArea && !connectsToBorder) + { + // Kill all visited regions. + for (int j = 0; j < trace.size(); ++j) + { + regions[trace[j]].spanCount = 0; + regions[trace[j]].id = 0; + } + } + } + + // Merge too small regions to neighbour regions. + int mergeCount = 0 ; + do + { + mergeCount = 0; + for (int i = 0; i < nreg; ++i) + { + rcRegion& reg = regions[i]; + if (reg.id == 0 || (reg.id & RC_BORDER_REG)) + continue; + if (reg.overlap) + continue; + if (reg.spanCount == 0) + continue; + + // Check to see if the region should be merged. + if (reg.spanCount > mergeRegionSize && isRegionConnectedToBorder(reg)) + continue; + + // Small region with more than 1 connection. + // Or region which is not connected to a border at all. + // Find smallest neighbour region that connects to this one. + int smallest = 0xfffffff; + unsigned short mergeId = reg.id; + for (int j = 0; j < reg.connections.size(); ++j) + { + if (reg.connections[j] & RC_BORDER_REG) continue; + rcRegion& mreg = regions[reg.connections[j]]; + if (mreg.id == 0 || (mreg.id & RC_BORDER_REG) || mreg.overlap) continue; + if (mreg.spanCount < smallest && + canMergeWithRegion(reg, mreg) && + canMergeWithRegion(mreg, reg)) + { + smallest = mreg.spanCount; + mergeId = mreg.id; + } + } + // Found new id. + if (mergeId != reg.id) + { + unsigned short oldId = reg.id; + rcRegion& target = regions[mergeId]; + + // Merge neighbours. + if (mergeRegions(target, reg)) + { + // Fixup regions pointing to current region. + for (int j = 0; j < nreg; ++j) + { + if (regions[j].id == 0 || (regions[j].id & RC_BORDER_REG)) continue; + // If another region was already merged into current region + // change the nid of the previous region too. + if (regions[j].id == oldId) + regions[j].id = mergeId; + // Replace the current region with the new one if the + // current regions is neighbour. + replaceNeighbour(regions[j], oldId, mergeId); + } + mergeCount++; + } + } + } + } + while (mergeCount > 0); + + // Compress region Ids. + for (int i = 0; i < nreg; ++i) + { + regions[i].remap = false; + if (regions[i].id == 0) continue; // Skip nil regions. + if (regions[i].id & RC_BORDER_REG) continue; // Skip external regions. + regions[i].remap = true; + } + + unsigned short regIdGen = 0; + for (int i = 0; i < nreg; ++i) + { + if (!regions[i].remap) + continue; + unsigned short oldId = regions[i].id; + unsigned short newId = ++regIdGen; + for (int j = i; j < nreg; ++j) + { + if (regions[j].id == oldId) + { + regions[j].id = newId; + regions[j].remap = false; + } + } + } + maxRegionId = regIdGen; + + // Remap regions. + for (int i = 0; i < chf.spanCount; ++i) + { + if ((srcReg[i] & RC_BORDER_REG) == 0) + srcReg[i] = regions[srcReg[i]].id; + } + + // Return regions that we found to be overlapping. + for (int i = 0; i < nreg; ++i) + if (regions[i].overlap) + overlaps.push(regions[i].id); + + for (int i = 0; i < nreg; ++i) + regions[i].~rcRegion(); + rcFree(regions); + + + return true; +} + + +static void addUniqueConnection(rcRegion& reg, int n) +{ + for (int i = 0; i < reg.connections.size(); ++i) + if (reg.connections[i] == n) + return; + reg.connections.push(n); +} + +static bool mergeAndFilterLayerRegions(rcContext* ctx, int minRegionArea, + unsigned short& maxRegionId, + rcCompactHeightfield& chf, + unsigned short* srcReg, rcIntArray& /*overlaps*/) +{ + const int w = chf.width; + const int h = chf.height; + + const int nreg = maxRegionId+1; + rcRegion* regions = (rcRegion*)rcAlloc(sizeof(rcRegion)*nreg, RC_ALLOC_TEMP); + if (!regions) + { + ctx->log(RC_LOG_ERROR, "mergeAndFilterLayerRegions: Out of memory 'regions' (%d).", nreg); + return false; + } + + // Construct regions + for (int i = 0; i < nreg; ++i) + new(®ions[i]) rcRegion((unsigned short)i); + + // Find region neighbours and overlapping regions. + rcIntArray lregs(32); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + lregs.resize(0); + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + const unsigned short ri = srcReg[i]; + if (ri == 0 || ri >= nreg) continue; + rcRegion& reg = regions[ri]; + + reg.spanCount++; + + reg.ymin = rcMin(reg.ymin, s.y); + reg.ymax = rcMax(reg.ymax, s.y); + + // Collect all region layers. + lregs.push(ri); + + // Update neighbours + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(s, dir) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(dir); + const int ay = y + rcGetDirOffsetY(dir); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir); + const unsigned short rai = srcReg[ai]; + if (rai > 0 && rai < nreg && rai != ri) + addUniqueConnection(reg, rai); + if (rai & RC_BORDER_REG) + reg.connectsToBorder = true; + } + } + + } + + // Update overlapping regions. + for (int i = 0; i < lregs.size()-1; ++i) + { + for (int j = i+1; j < lregs.size(); ++j) + { + if (lregs[i] != lregs[j]) + { + rcRegion& ri = regions[lregs[i]]; + rcRegion& rj = regions[lregs[j]]; + addUniqueFloorRegion(ri, lregs[j]); + addUniqueFloorRegion(rj, lregs[i]); + } + } + } + + } + } + + // Create 2D layers from regions. + unsigned short layerId = 1; + + for (int i = 0; i < nreg; ++i) + regions[i].id = 0; + + // Merge montone regions to create non-overlapping areas. + rcIntArray stack(32); + for (int i = 1; i < nreg; ++i) + { + rcRegion& root = regions[i]; + // Skip already visited. + if (root.id != 0) + continue; + + // Start search. + root.id = layerId; + + stack.resize(0); + stack.push(i); + + while (stack.size() > 0) + { + // Pop front + rcRegion& reg = regions[stack[0]]; + for (int j = 0; j < stack.size()-1; ++j) + stack[j] = stack[j+1]; + stack.resize(stack.size()-1); + + const int ncons = (int)reg.connections.size(); + for (int j = 0; j < ncons; ++j) + { + const int nei = reg.connections[j]; + rcRegion& regn = regions[nei]; + // Skip already visited. + if (regn.id != 0) + continue; + // Skip if the neighbour is overlapping root region. + bool overlap = false; + for (int k = 0; k < root.floors.size(); k++) + { + if (root.floors[k] == nei) + { + overlap = true; + break; + } + } + if (overlap) + continue; + + // Deepen + stack.push(nei); + + // Mark layer id + regn.id = layerId; + // Merge current layers to root. + for (int k = 0; k < regn.floors.size(); ++k) + addUniqueFloorRegion(root, regn.floors[k]); + root.ymin = rcMin(root.ymin, regn.ymin); + root.ymax = rcMax(root.ymax, regn.ymax); + root.spanCount += regn.spanCount; + regn.spanCount = 0; + root.connectsToBorder = root.connectsToBorder || regn.connectsToBorder; + } + } + + layerId++; + } + + // Remove small regions + for (int i = 0; i < nreg; ++i) + { + if (regions[i].spanCount > 0 && regions[i].spanCount < minRegionArea && !regions[i].connectsToBorder) + { + unsigned short reg = regions[i].id; + for (int j = 0; j < nreg; ++j) + if (regions[j].id == reg) + regions[j].id = 0; + } + } + + // Compress region Ids. + for (int i = 0; i < nreg; ++i) + { + regions[i].remap = false; + if (regions[i].id == 0) continue; // Skip nil regions. + if (regions[i].id & RC_BORDER_REG) continue; // Skip external regions. + regions[i].remap = true; + } + + unsigned short regIdGen = 0; + for (int i = 0; i < nreg; ++i) + { + if (!regions[i].remap) + continue; + unsigned short oldId = regions[i].id; + unsigned short newId = ++regIdGen; + for (int j = i; j < nreg; ++j) + { + if (regions[j].id == oldId) + { + regions[j].id = newId; + regions[j].remap = false; + } + } + } + maxRegionId = regIdGen; + + // Remap regions. + for (int i = 0; i < chf.spanCount; ++i) + { + if ((srcReg[i] & RC_BORDER_REG) == 0) + srcReg[i] = regions[srcReg[i]].id; + } + + for (int i = 0; i < nreg; ++i) + regions[i].~rcRegion(); + rcFree(regions); + + return true; +} + + + +/// @par +/// +/// This is usually the second to the last step in creating a fully built +/// compact heightfield. This step is required before regions are built +/// using #rcBuildRegions or #rcBuildRegionsMonotone. +/// +/// After this step, the distance data is available via the rcCompactHeightfield::maxDistance +/// and rcCompactHeightfield::dist fields. +/// +/// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone +bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_DISTANCEFIELD); + + if (chf.dist) + { + rcFree(chf.dist); + chf.dist = 0; + } + + unsigned short* src = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_TEMP); + if (!src) + { + ctx->log(RC_LOG_ERROR, "rcBuildDistanceField: Out of memory 'src' (%d).", chf.spanCount); + return false; + } + unsigned short* dst = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_TEMP); + if (!dst) + { + ctx->log(RC_LOG_ERROR, "rcBuildDistanceField: Out of memory 'dst' (%d).", chf.spanCount); + rcFree(src); + return false; + } + + unsigned short maxDist = 0; + + { + rcScopedTimer timerDist(ctx, RC_TIMER_BUILD_DISTANCEFIELD_DIST); + + calculateDistanceField(chf, src, maxDist); + chf.maxDistance = maxDist; + } + + { + rcScopedTimer timerBlur(ctx, RC_TIMER_BUILD_DISTANCEFIELD_BLUR); + + // Blur + if (boxBlur(chf, 1, src, dst) != src) + rcSwap(src, dst); + + // Store distance. + chf.dist = src; + } + + rcFree(dst); + + return true; +} + +static void paintRectRegion(int minx, int maxx, int miny, int maxy, unsigned short regId, + rcCompactHeightfield& chf, unsigned short* srcReg) +{ + const int w = chf.width; + for (int y = miny; y < maxy; ++y) + { + for (int x = minx; x < maxx; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (chf.areas[i] != RC_NULL_AREA) + srcReg[i] = regId; + } + } + } +} + + +static const unsigned short RC_NULL_NEI = 0xffff; + +struct rcSweepSpan +{ + unsigned short rid; // row id + unsigned short id; // region id + unsigned short ns; // number samples + unsigned short nei; // neighbour id +}; + +/// @par +/// +/// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour. +/// Contours will form simple polygons. +/// +/// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be +/// re-assigned to the zero (null) region. +/// +/// Partitioning can result in smaller than necessary regions. @p mergeRegionArea helps +/// reduce unecessarily small regions. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// The region data will be available via the rcCompactHeightfield::maxRegions +/// and rcCompactSpan::reg fields. +/// +/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. +/// +/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig +bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int minRegionArea, const int mergeRegionArea) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_REGIONS); + + const int w = chf.width; + const int h = chf.height; + unsigned short id = 1; + + rcScopedDelete srcReg((unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_TEMP)); + if (!srcReg) + { + ctx->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'src' (%d).", chf.spanCount); + return false; + } + memset(srcReg,0,sizeof(unsigned short)*chf.spanCount); + + const int nsweeps = rcMax(chf.width,chf.height); + rcScopedDelete sweeps((rcSweepSpan*)rcAlloc(sizeof(rcSweepSpan)*nsweeps, RC_ALLOC_TEMP)); + if (!sweeps) + { + ctx->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'sweeps' (%d).", nsweeps); + return false; + } + + + // Mark border regions. + if (borderSize > 0) + { + // Make sure border will not overflow. + const int bw = rcMin(w, borderSize); + const int bh = rcMin(h, borderSize); + // Paint regions + paintRectRegion(0, bw, 0, h, id|RC_BORDER_REG, chf, srcReg); id++; + paintRectRegion(w-bw, w, 0, h, id|RC_BORDER_REG, chf, srcReg); id++; + paintRectRegion(0, w, 0, bh, id|RC_BORDER_REG, chf, srcReg); id++; + paintRectRegion(0, w, h-bh, h, id|RC_BORDER_REG, chf, srcReg); id++; + + chf.borderSize = borderSize; + } + + rcIntArray prev(256); + + // Sweep one line at a time. + for (int y = borderSize; y < h-borderSize; ++y) + { + // Collect spans from this row. + prev.resize(id+1); + memset(&prev[0],0,sizeof(int)*id); + unsigned short rid = 1; + + for (int x = borderSize; x < w-borderSize; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + if (chf.areas[i] == RC_NULL_AREA) continue; + + // -x + unsigned short previd = 0; + if (rcGetCon(s, 0) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(0); + const int ay = y + rcGetDirOffsetY(0); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0); + if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) + previd = srcReg[ai]; + } + + if (!previd) + { + previd = rid++; + sweeps[previd].rid = previd; + sweeps[previd].ns = 0; + sweeps[previd].nei = 0; + } + + // -y + if (rcGetCon(s,3) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(3); + const int ay = y + rcGetDirOffsetY(3); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3); + if (srcReg[ai] && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) + { + unsigned short nr = srcReg[ai]; + if (!sweeps[previd].nei || sweeps[previd].nei == nr) + { + sweeps[previd].nei = nr; + sweeps[previd].ns++; + prev[nr]++; + } + else + { + sweeps[previd].nei = RC_NULL_NEI; + } + } + } + + srcReg[i] = previd; + } + } + + // Create unique ID. + for (int i = 1; i < rid; ++i) + { + if (sweeps[i].nei != RC_NULL_NEI && sweeps[i].nei != 0 && + prev[sweeps[i].nei] == (int)sweeps[i].ns) + { + sweeps[i].id = sweeps[i].nei; + } + else + { + sweeps[i].id = id++; + } + } + + // Remap IDs + for (int x = borderSize; x < w-borderSize; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (srcReg[i] > 0 && srcReg[i] < rid) + srcReg[i] = sweeps[srcReg[i]].id; + } + } + } + + + { + rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER); + + // Merge regions and filter out small regions. + rcIntArray overlaps; + chf.maxRegions = id; + if (!mergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg, overlaps)) + return false; + + // Monotone partitioning does not generate overlapping regions. + } + + // Store the result out. + for (int i = 0; i < chf.spanCount; ++i) + chf.spans[i].reg = srcReg[i]; + + return true; +} + +/// @par +/// +/// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour. +/// Contours will form simple polygons. +/// +/// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be +/// re-assigned to the zero (null) region. +/// +/// Watershed partitioning can result in smaller than necessary regions, especially in diagonal corridors. +/// @p mergeRegionArea helps reduce unecessarily small regions. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// The region data will be available via the rcCompactHeightfield::maxRegions +/// and rcCompactSpan::reg fields. +/// +/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. +/// +/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig +bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int minRegionArea, const int mergeRegionArea) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_REGIONS); + + const int w = chf.width; + const int h = chf.height; + + rcScopedDelete buf((unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*4, RC_ALLOC_TEMP)); + if (!buf) + { + ctx->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4); + return false; + } + + ctx->startTimer(RC_TIMER_BUILD_REGIONS_WATERSHED); + + const int LOG_NB_STACKS = 3; + const int NB_STACKS = 1 << LOG_NB_STACKS; + rcIntArray lvlStacks[NB_STACKS]; + for (int i=0; i 0) + { + // Make sure border will not overflow. + const int bw = rcMin(w, borderSize); + const int bh = rcMin(h, borderSize); + + // Paint regions + paintRectRegion(0, bw, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; + paintRectRegion(w-bw, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; + paintRectRegion(0, w, 0, bh, regionId|RC_BORDER_REG, chf, srcReg); regionId++; + paintRectRegion(0, w, h-bh, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; + + chf.borderSize = borderSize; + } + + int sId = -1; + while (level > 0) + { + level = level >= 2 ? level-2 : 0; + sId = (sId+1) & (NB_STACKS-1); + +// ctx->startTimer(RC_TIMER_DIVIDE_TO_LEVELS); + + if (sId == 0) + sortCellsByLevel(level, chf, srcReg, NB_STACKS, lvlStacks, 1); + else + appendStacks(lvlStacks[sId-1], lvlStacks[sId], srcReg); // copy left overs from last level + +// ctx->stopTimer(RC_TIMER_DIVIDE_TO_LEVELS); + + { + rcScopedTimer timerExpand(ctx, RC_TIMER_BUILD_REGIONS_EXPAND); + + // Expand current regions until no empty connected cells found. + if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, lvlStacks[sId], false) != srcReg) + { + rcSwap(srcReg, dstReg); + rcSwap(srcDist, dstDist); + } + } + + { + rcScopedTimer timerFloor(ctx, RC_TIMER_BUILD_REGIONS_FLOOD); + + // Mark new regions with IDs. + for (int j = 0; j= 0 && srcReg[i] == 0) + { + if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack)) + { + if (regionId == 0xFFFF) + { + ctx->log(RC_LOG_ERROR, "rcBuildRegions: Region ID overflow"); + return false; + } + + regionId++; + } + } + } + } + } + + // Expand current regions until no empty connected cells found. + if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack, true) != srcReg) + { + rcSwap(srcReg, dstReg); + rcSwap(srcDist, dstDist); + } + + ctx->stopTimer(RC_TIMER_BUILD_REGIONS_WATERSHED); + + { + rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER); + + // Merge regions and filter out smalle regions. + rcIntArray overlaps; + chf.maxRegions = regionId; + if (!mergeAndFilterRegions(ctx, minRegionArea, mergeRegionArea, chf.maxRegions, chf, srcReg, overlaps)) + return false; + + // If overlapping regions were found during merging, split those regions. + if (overlaps.size() > 0) + { + ctx->log(RC_LOG_ERROR, "rcBuildRegions: %d overlapping regions.", overlaps.size()); + } + } + + // Write the result out. + for (int i = 0; i < chf.spanCount; ++i) + chf.spans[i].reg = srcReg[i]; + + return true; +} + + +bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf, + const int borderSize, const int minRegionArea) +{ + rcAssert(ctx); + + rcScopedTimer timer(ctx, RC_TIMER_BUILD_REGIONS); + + const int w = chf.width; + const int h = chf.height; + unsigned short id = 1; + + rcScopedDelete srcReg((unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_TEMP)); + if (!srcReg) + { + ctx->log(RC_LOG_ERROR, "rcBuildLayerRegions: Out of memory 'src' (%d).", chf.spanCount); + return false; + } + memset(srcReg,0,sizeof(unsigned short)*chf.spanCount); + + const int nsweeps = rcMax(chf.width,chf.height); + rcScopedDelete sweeps((rcSweepSpan*)rcAlloc(sizeof(rcSweepSpan)*nsweeps, RC_ALLOC_TEMP)); + if (!sweeps) + { + ctx->log(RC_LOG_ERROR, "rcBuildLayerRegions: Out of memory 'sweeps' (%d).", nsweeps); + return false; + } + + + // Mark border regions. + if (borderSize > 0) + { + // Make sure border will not overflow. + const int bw = rcMin(w, borderSize); + const int bh = rcMin(h, borderSize); + // Paint regions + paintRectRegion(0, bw, 0, h, id|RC_BORDER_REG, chf, srcReg); id++; + paintRectRegion(w-bw, w, 0, h, id|RC_BORDER_REG, chf, srcReg); id++; + paintRectRegion(0, w, 0, bh, id|RC_BORDER_REG, chf, srcReg); id++; + paintRectRegion(0, w, h-bh, h, id|RC_BORDER_REG, chf, srcReg); id++; + + chf.borderSize = borderSize; + } + + rcIntArray prev(256); + + // Sweep one line at a time. + for (int y = borderSize; y < h-borderSize; ++y) + { + // Collect spans from this row. + prev.resize(id+1); + memset(&prev[0],0,sizeof(int)*id); + unsigned short rid = 1; + + for (int x = borderSize; x < w-borderSize; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + if (chf.areas[i] == RC_NULL_AREA) continue; + + // -x + unsigned short previd = 0; + if (rcGetCon(s, 0) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(0); + const int ay = y + rcGetDirOffsetY(0); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0); + if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) + previd = srcReg[ai]; + } + + if (!previd) + { + previd = rid++; + sweeps[previd].rid = previd; + sweeps[previd].ns = 0; + sweeps[previd].nei = 0; + } + + // -y + if (rcGetCon(s,3) != RC_NOT_CONNECTED) + { + const int ax = x + rcGetDirOffsetX(3); + const int ay = y + rcGetDirOffsetY(3); + const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3); + if (srcReg[ai] && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) + { + unsigned short nr = srcReg[ai]; + if (!sweeps[previd].nei || sweeps[previd].nei == nr) + { + sweeps[previd].nei = nr; + sweeps[previd].ns++; + prev[nr]++; + } + else + { + sweeps[previd].nei = RC_NULL_NEI; + } + } + } + + srcReg[i] = previd; + } + } + + // Create unique ID. + for (int i = 1; i < rid; ++i) + { + if (sweeps[i].nei != RC_NULL_NEI && sweeps[i].nei != 0 && + prev[sweeps[i].nei] == (int)sweeps[i].ns) + { + sweeps[i].id = sweeps[i].nei; + } + else + { + sweeps[i].id = id++; + } + } + + // Remap IDs + for (int x = borderSize; x < w-borderSize; ++x) + { + const rcCompactCell& c = chf.cells[x+y*w]; + + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + if (srcReg[i] > 0 && srcReg[i] < rid) + srcReg[i] = sweeps[srcReg[i]].id; + } + } + } + + + { + rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER); + + // Merge monotone regions to layers and remove small regions. + rcIntArray overlaps; + chf.maxRegions = id; + if (!mergeAndFilterLayerRegions(ctx, minRegionArea, chf.maxRegions, chf, srcReg, overlaps)) + return false; + } + + + // Store the result out. + for (int i = 0; i < chf.spanCount; ++i) + chf.spans[i].reg = srcReg[i]; + + return true; +} diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index b40c77a0f..83c980086 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -36,7 +36,7 @@ DatabaseMySQL::DatabaseMySQL(std::string user, std::string pass, std::string hos database = mysql_init(nullptr); if (database) { - my_bool r = 1; + char r = 1; mysql_options(database, MYSQL_OPT_RECONNECT, &r); if (!mysql_real_connect(database, host.c_str(), user.c_str(), pass.c_str(), name.c_str(), atoi(port.c_str()), nullptr, 0)) { diff --git a/luabind/CMakeLists.txt b/luabind/CMakeLists.txt deleted file mode 100644 index 5efdf562f..000000000 --- a/luabind/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) - -SET(lb_sources - src/class.cpp - src/class_info.cpp - src/class_registry.cpp - src/class_rep.cpp - src/create_class.cpp - src/error.cpp - src/exception_handler.cpp - src/function.cpp - src/inheritance.cpp - src/link_compatibility.cpp - src/object_rep.cpp - src/open.cpp - src/pcall.cpp - src/scope.cpp - src/stack_content_by_name.cpp - src/weak_ref.cpp - src/wrapper_base.cpp -) - -SET(lb_headers - -) - -ADD_LIBRARY(luabind ${lb_sources} ${lb_headers}) - - -IF(UNIX) - ADD_DEFINITIONS(-fPIC) - set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS -Wno-deprecated-declarations) -ENDIF(UNIX) - -IF(MSVC) - set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS " /W0 " ) -ENDIF(MSVC) - -SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/luabind/luabind/adopt_policy.hpp b/luabind/luabind/adopt_policy.hpp deleted file mode 100644 index 5e81b948b..000000000 --- a/luabind/luabind/adopt_policy.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_ADOPT_POLICY_HPP_INCLUDED -#define LUABIND_ADOPT_POLICY_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - template - void adjust_backref_ownership(T* ptr, mpl::true_) - { - if (wrap_base* p = dynamic_cast(ptr)) - { - wrapped_self_t& wrapper = wrap_access::ref(*p); - wrapper.get(wrapper.state()); - wrapper.m_strong_ref.set(wrapper.state()); - } - } - - inline void adjust_backref_ownership(void*, mpl::false_) - {} - - template - struct adopt_pointer : pointer_converter - { - typedef adopt_pointer type; - - int const consumed_args(...) - { - return 1; - } - - template - T* apply(lua_State* L, by_pointer, int index) - { - T* ptr = pointer_converter::apply( - L, LUABIND_DECORATE_TYPE(T*), index); - - object_rep* obj = static_cast( - lua_touserdata(L, index)); - obj->release(); - - adjust_backref_ownership(ptr, boost::is_polymorphic()); - - return ptr; - } - - template - int match(lua_State* L, by_pointer, int index) - { - return pointer_converter::match( - L, LUABIND_DECORATE_TYPE(T*), index); - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template<> - struct adopt_pointer - { - typedef adopt_pointer type; - - template - void apply(lua_State* L, T* ptr) - { - if (ptr == 0) - { - lua_pushnil(L); - return; - } - - // if there is a back_reference, then the - // ownership will be removed from the - // back reference and put on the lua stack. - if (luabind::move_back_reference(L, ptr)) - return; - - make_instance(L, std::auto_ptr(ptr)); - } - }; - - template -// struct adopt_policy : converter_policy_tag - struct adopt_policy : conversion_policy - { -// BOOST_STATIC_CONSTANT(int, index = N); - - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_pointers {}; - - template - struct apply - { - typedef luabind::detail::is_nonconst_pointer is_nonconst_p; - typedef typename boost::mpl::if_, only_accepts_nonconst_pointers>::type type; - }; - }; - -}} - -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - adopt(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } -} - -#endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE - diff --git a/luabind/luabind/back_reference.hpp b/luabind/luabind/back_reference.hpp deleted file mode 100644 index 5027618fb..000000000 --- a/luabind/luabind/back_reference.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_BACK_REFERENCE_040510_HPP -#define LUABIND_BACK_REFERENCE_040510_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace luabind { - -namespace detail -{ - namespace mpl = boost::mpl; - - template - wrap_base const* get_back_reference_aux0(T const* p, mpl::true_) - { - return dynamic_cast(p); - } - - template - wrap_base const* get_back_reference_aux0(T const*, mpl::false_) - { - return 0; - } - - template - wrap_base const* get_back_reference_aux1(T const* p) - { - return get_back_reference_aux0(p, boost::is_polymorphic()); - } - - template - wrap_base const* get_back_reference_aux2(T const& x, mpl::true_) - { - return get_back_reference_aux1(get_pointer(x)); - } - - template - wrap_base const* get_back_reference_aux2(T const& x, mpl::false_) - { - return get_back_reference_aux1(&x); - } - - template - wrap_base const* get_back_reference(T const& x) - { - return detail::get_back_reference_aux2( - x - , has_get_pointer() - ); - } - -} // namespace detail - -template -bool get_back_reference(lua_State* L, T const& x) -{ -#ifndef LUABIND_NO_RTTI - if (wrap_base const* w = detail::get_back_reference(x)) - { - detail::wrap_access::ref(*w).get(L); - return true; - } -#endif - return false; -} - -template -bool move_back_reference(lua_State* L, T const& x) -{ -#ifndef LUABIND_NO_RTTI - if (wrap_base* w = const_cast(detail::get_back_reference(x))) - { - assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); - detail::wrap_access::ref(*w).get(L); - detail::wrap_access::ref(*w).m_strong_ref.reset(); - return true; - } -#endif - return false; -} - -} // namespace luabind - -#endif // LUABIND_BACK_REFERENCE_040510_HPP - diff --git a/luabind/luabind/back_reference_fwd.hpp b/luabind/luabind/back_reference_fwd.hpp deleted file mode 100644 index ffe141dba..000000000 --- a/luabind/luabind/back_reference_fwd.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_BACK_REFERENCE_FWD_040510_HPP -#define LUABIND_BACK_REFERENCE_FWD_040510_HPP - -namespace luabind { - -template -bool get_back_reference(lua_State* L, T const& x); - -template -bool move_back_reference(lua_State* L, T const& x); - -} // namespace luabind - -#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP - diff --git a/luabind/luabind/class.hpp b/luabind/luabind/class.hpp deleted file mode 100644 index 10fb8e03d..000000000 --- a/luabind/luabind/class.hpp +++ /dev/null @@ -1,879 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CLASS_HPP_INCLUDED -#define LUABIND_CLASS_HPP_INCLUDED - -/* - ISSUES: - ------------------------------------------------------ - - * solved for member functions, not application operator * - if we have a base class that defines a function a derived class must be able to - override that function (not just overload). Right now we just add the other overload - to the overloads list and will probably get an ambiguity. If we want to support this - each method_rep must include a vector of type_info pointers for each parameter. - Operators do not have this problem, since operators always have to have - it's own type as one of the arguments, no ambiguity can occur. Application - operator, on the other hand, would have this problem. - Properties cannot be overloaded, so they should always be overridden. - If this is to work for application operator, we really need to specify if an application - operator is const or not. - - If one class registers two functions with the same name and the same - signature, there's currently no error. The last registered function will - be the one that's used. - How do we know which class registered the function? If the function was - defined by the base class, it is a legal operation, to override it. - we cannot look at the pointer offset, since it always will be zero for one of the bases. - - - - TODO: - ------------------------------------------------------ - - finish smart pointer support - * the adopt policy should not be able to adopt pointers to held_types. This - must be prohibited. - * name_of_type must recognize holder_types and not return "custom" - - document custom policies, custom converters - - store the instance object for policies. - - support the __concat metamethod. This is a bit tricky, since it cannot be - treated as a normal operator. It is a binary operator but we want to use the - __tostring implementation for both arguments. - -*/ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// to remove the 'this' used in initialization list-warning -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4355) -#endif - -namespace boost -{ - - template class shared_ptr; - -} // namespace boost - -namespace luabind -{ - namespace detail - { - struct unspecified {}; - - template struct operator_; - - struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {}; - } - - template - struct class_; - - // TODO: this function will only be invoked if the user hasn't defined a correct overload - // maybe we should have a static assert in here? - inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr* - get_const_holder(...) - { - return 0; - } - - template - boost::shared_ptr* get_const_holder(boost::shared_ptr*) - { - return 0; - } - - template < - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( - LUABIND_MAX_BASES, class A, detail::null_type) - > - struct bases - {}; - - typedef bases no_bases; - - namespace detail - { - template - struct is_bases - : mpl::false_ - {}; - - template - struct is_bases > - : mpl::true_ - {}; - - template - struct is_unspecified - : mpl::apply1 - {}; - - template - struct is_unspecified - : mpl::true_ - {}; - - template - struct is_unspecified_mfn - { - template - struct apply - : is_unspecified - {}; - }; - - template - struct get_predicate - { - typedef mpl::protect > type; - }; - - template - struct result_or_default - { - typedef Result type; - }; - - template - struct result_or_default - { - typedef Default type; - }; - - template - struct extract_parameter - { - typedef typename get_predicate::type pred; - typedef typename boost::mpl::find_if::type iterator; - typedef typename result_or_default< - typename iterator::type, DefaultValue - >::type type; - }; - - // prints the types of the values on the stack, in the - // range [start_index, lua_gettop()] - - LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - - struct LUABIND_API create_class - { - static int stage1(lua_State* L); - static int stage2(lua_State* L); - }; - - } // detail - - namespace detail { - - template - struct static_scope - { - static_scope(T& self_) : self(self_) - { - } - - T& operator[](scope s) const - { - self.add_inner_scope(s); - return self; - } - - private: - template void operator,(U const&) const; - void operator=(static_scope const&); - - T& self; - }; - - struct class_registration; - - struct LUABIND_API class_base : scope - { - public: - class_base(char const* name); - - struct base_desc - { - type_id type; - int ptr_offset; - }; - - void init( - type_id const& type, class_id id - , type_id const& wrapped_type, class_id wrapper_id); - - void add_base(type_id const& base, cast_function cast); - - void add_member(registration* member); - void add_default_member(registration* member); - - const char* name() const; - - void add_static_constant(const char* name, int val); - void add_inner_scope(scope& s); - - void add_cast(class_id src, class_id target, cast_function cast); - - private: - class_registration* m_registration; - }; - -// MSVC complains about member being sensitive to alignment (C4121) -// when F is a pointer to member of a class with virtual bases. -# ifdef BOOST_MSVC -# pragma pack(push) -# pragma pack(16) -# endif - - template - struct memfun_registration : registration - { - memfun_registration(char const* name, F f, Policies const& policies) - : name(name) - , f(f) - , policies(policies) - {} - - void register_(lua_State* L) const - { - object fn = make_function( - L, f, deduce_signature(f, (Class*)0), policies); - - add_overload( - object(from_stack(L, -1)) - , name - , fn - ); - } - - char const* name; - F f; - Policies policies; - }; - -# ifdef BOOST_MSVC -# pragma pack(pop) -# endif - - template - struct default_pointer - { - typedef P type; - }; - - template - struct default_pointer - { - typedef std::auto_ptr type; - }; - - template - struct constructor_registration : registration - { - constructor_registration(Policies const& policies) - : policies(policies) - {} - - void register_(lua_State* L) const - { - typedef typename default_pointer::type pointer; - - object fn = make_function( - L - , construct(), Signature() - , policies - ); - - add_overload( - object(from_stack(L, -1)) - , "__init" - , fn - ); - } - - Policies policies; - }; - - template - struct reference_result - : mpl::if_< - mpl::or_, is_primitive > - , T - , typename boost::add_reference::type - > - {}; - - template - struct inject_dependency_policy - : mpl::if_< - is_primitive - , Policies - , policy_cons, Policies> - > - {}; - - template < - class Class - , class Get, class GetPolicies - , class Set = null_type, class SetPolicies = null_type - > - struct property_registration : registration - { - property_registration( - char const* name - , Get const& get - , GetPolicies const& get_policies - , Set const& set = Set() - , SetPolicies const& set_policies = SetPolicies() - ) - : name(name) - , get(get) - , get_policies(get_policies) - , set(set) - , set_policies(set_policies) - {} - - void register_(lua_State* L) const - { - object context(from_stack(L, -1)); - register_aux( - L - , context - , make_get(L, get, boost::is_member_object_pointer()) - , set - ); - } - - template - object make_get(lua_State* L, F const& f, mpl::false_) const - { - return make_function( - L, f, deduce_signature(f, (Class*)0), get_policies); - } - - template - object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const - { - typedef typename reference_result::type result_type; - typedef typename inject_dependency_policy< - D, GetPolicies>::type policies; - - return make_function( - L - , access_member_ptr(mem_ptr) - , mpl::vector2() - , policies() - ); - } - - template - object make_set(lua_State* L, F const& f, mpl::false_) const - { - return make_function( - L, f, deduce_signature(f, (Class*)0), set_policies); - } - - template - object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const - { - return make_function( - L - , access_member_ptr(mem_ptr) - , mpl::vector3() - , set_policies - ); - } - - template - void register_aux( - lua_State* L, object const& context - , object const& get_, S const&) const - { - context[name] = property( - get_ - , make_set(L, set, boost::is_member_object_pointer()) - ); - } - - void register_aux( - lua_State*, object const& context - , object const& get_, null_type) const - { - context[name] = property(get_); - } - - char const* name; - Get get; - GetPolicies get_policies; - Set set; - SetPolicies set_policies; - }; - - } // namespace detail - - // registers a class in the lua environment - template - struct class_: detail::class_base - { - typedef class_ self_t; - - private: - - template - class_(const class_&); - - public: - - typedef boost::mpl::vector4 parameters_type; - - // WrappedType MUST inherit from T - typedef typename detail::extract_parameter< - parameters_type - , boost::is_base_and_derived - , detail::null_type - >::type WrappedType; - - typedef typename detail::extract_parameter< - parameters_type - , boost::mpl::not_< - boost::mpl::or_< - detail::is_bases - , boost::is_base_and_derived - , boost::is_base_and_derived - > - > - , detail::null_type - >::type HeldType; - - template - void add_downcast(Src*, Target*, boost::mpl::true_) - { - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::dynamic_cast_::execute - ); - } - - template - void add_downcast(Src*, Target*, boost::mpl::false_) - {} - - // this function generates conversion information - // in the given class_rep structure. It will be able - // to implicitly cast to the given template type - template - void gen_base_info(detail::type_) - { - add_base(typeid(To), detail::static_cast_::execute); - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::static_cast_::execute - ); - - add_downcast((To*)0, (T*)0, boost::is_polymorphic()); - } - - void gen_base_info(detail::type_) - {} - -#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_()); - - template - void generate_baseclass_list(detail::type_ >) - { - BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _) - } - -#undef LUABIND_GEN_BASE_INFO - - class_(const char* name): class_base(name), scope(*this) - { -#ifndef NDEBUG - detail::check_link_compatibility(); -#endif - init(); - } - - template - class_& def(const char* name, F f) - { - return this->virtual_def( - name, f, detail::null_type() - , detail::null_type(), boost::mpl::true_()); - } - - // virtual functions - template - class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies) - { - return this->virtual_def( - name, fn, default_or_policies, detail::null_type() - , LUABIND_MSVC_TYPENAME detail::is_policy_cons::type()); - } - - template - class_& def(char const* name, F fn - , Default default_, Policies const& policies) - { - return this->virtual_def( - name, fn, default_ - , policies, boost::mpl::false_()); - } - - template - class_& def(constructor sig) - { - return this->def_constructor(&sig, detail::null_type()); - } - - template - class_& def(constructor sig, const Policies& policies) - { - return this->def_constructor(&sig, policies); - } - - template - class_& property(const char* name, Getter g) - { - this->add_member( - new detail::property_registration( - name, g, detail::null_type())); - return *this; - } - - template - class_& property(const char* name, Getter g, MaybeSetter s) - { - return property_impl( - name, g, s - , boost::mpl::bool_::value>() - ); - } - - template - class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies) - { - typedef detail::property_registration< - T, Getter, GetPolicies, Setter, detail::null_type - > registration_type; - - this->add_member( - new registration_type(name, g, get_policies, s)); - return *this; - } - - template - class_& property( - const char* name - , Getter g, Setter s - , GetPolicies const& get_policies - , SetPolicies const& set_policies) - { - typedef detail::property_registration< - T, Getter, GetPolicies, Setter, SetPolicies - > registration_type; - - this->add_member( - new registration_type(name, g, get_policies, s, set_policies)); - return *this; - } - - template - class_& def_readonly(const char* name, D C::*mem_ptr) - { - typedef detail::property_registration - registration_type; - - this->add_member( - new registration_type(name, mem_ptr, detail::null_type())); - return *this; - } - - template - class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies) - { - typedef detail::property_registration - registration_type; - - this->add_member( - new registration_type(name, mem_ptr, policies)); - return *this; - } - - template - class_& def_readwrite(const char* name, D C::*mem_ptr) - { - typedef detail::property_registration< - T, D C::*, detail::null_type, D C::* - > registration_type; - - this->add_member( - new registration_type( - name, mem_ptr, detail::null_type(), mem_ptr)); - return *this; - } - - template - class_& def_readwrite( - const char* name, D C::*mem_ptr, GetPolicies const& get_policies) - { - typedef detail::property_registration< - T, D C::*, GetPolicies, D C::* - > registration_type; - - this->add_member( - new registration_type( - name, mem_ptr, get_policies, mem_ptr)); - return *this; - } - - template - class_& def_readwrite( - const char* name - , D C::*mem_ptr - , GetPolicies const& get_policies - , SetPolicies const& set_policies - ) - { - typedef detail::property_registration< - T, D C::*, GetPolicies, D C::*, SetPolicies - > registration_type; - - this->add_member( - new registration_type( - name, mem_ptr, get_policies, mem_ptr, set_policies)); - return *this; - } - - template - class_& def(detail::operator_, Policies const& policies) - { - return this->def( - Derived::name() - , &Derived::template apply::execute - , policies - ); - } - - template - class_& def(detail::operator_) - { - return this->def( - Derived::name() - , &Derived::template apply::execute - ); - } - - detail::enum_maker enum_(const char*) - { - return detail::enum_maker(*this); - } - - detail::static_scope scope; - - private: - void operator=(class_ const&); - - void add_wrapper_cast(detail::null_type*) - {} - - template - void add_wrapper_cast(U*) - { - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::static_cast_::execute - ); - - add_downcast((T*)0, (U*)0, boost::is_polymorphic()); - } - - void init() - { - typedef typename detail::extract_parameter< - parameters_type - , boost::mpl::or_< - detail::is_bases - , boost::is_base_and_derived - > - , no_bases - >::type bases_t; - - typedef typename - boost::mpl::if_ - , bases_t - , bases - >::type Base; - - class_base::init( - typeid(T) - , detail::registered_class::id - , typeid(WrappedType) - , detail::registered_class::id - ); - - add_wrapper_cast((WrappedType*)0); - - generate_baseclass_list(detail::type_()); - } - - template - class_& property_impl(const char* name, - Getter g, - GetPolicies policies, - boost::mpl::bool_) - { - this->add_member( - new detail::property_registration( - name, g, policies)); - return *this; - } - - template - class_& property_impl(const char* name, - Getter g, - Setter s, - boost::mpl::bool_) - { - typedef detail::property_registration< - T, Getter, detail::null_type, Setter, detail::null_type - > registration_type; - - this->add_member( - new registration_type(name, g, detail::null_type(), s)); - return *this; - } - - // these handle default implementation of virtual functions - template - class_& virtual_def(char const* name, F const& fn - , Policies const&, detail::null_type, boost::mpl::true_) - { - this->add_member( - new detail::memfun_registration( - name, fn, Policies())); - return *this; - } - - template - class_& virtual_def(char const* name, F const& fn - , Default const& default_, Policies const&, boost::mpl::false_) - { - this->add_member( - new detail::memfun_registration( - name, fn, Policies())); - - this->add_default_member( - new detail::memfun_registration( - name, default_, Policies())); - - return *this; - } - - template - class_& def_constructor(Signature*, Policies const&) - { - typedef typename Signature::signature signature; - - typedef typename boost::mpl::if_< - boost::is_same - , T - , WrappedType - >::type construct_type; - - this->add_member( - new detail::constructor_registration< - construct_type, HeldType, signature, Policies>( - Policies())); - - this->add_default_member( - new detail::constructor_registration< - construct_type, HeldType, signature, Policies>( - Policies())); - - return *this; - } - }; - -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif // LUABIND_CLASS_HPP_INCLUDED - diff --git a/luabind/luabind/class_info.hpp b/luabind/luabind/class_info.hpp deleted file mode 100644 index a4f18a8cc..000000000 --- a/luabind/luabind/class_info.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CLASS_INFO_HPP_INCLUDED -#define LUABIND_CLASS_INFO_HPP_INCLUDED - -#include -#include -#include -#include - -namespace luabind -{ - struct LUABIND_API class_info - { - std::string name; - object methods; - object attributes; - }; - - LUABIND_API class_info get_class_info(argument const&); - - // returns a table of bound class names - LUABIND_API object get_class_names(lua_State* L); - - LUABIND_API void bind_class_info(lua_State*); -} - -#endif - diff --git a/luabind/luabind/config.hpp b/luabind/luabind/config.hpp deleted file mode 100644 index e8eea875c..000000000 --- a/luabind/luabind/config.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CONFIG_HPP_INCLUDED -#define LUABIND_CONFIG_HPP_INCLUDED - -#include - -#ifdef BOOST_MSVC - #define LUABIND_ANONYMOUS_FIX static -#else - #define LUABIND_ANONYMOUS_FIX -#endif - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) - -#define for if (false) {} else for - -#include - -namespace std -{ - using ::strlen; - using ::strcmp; - using ::type_info; -} - -#endif - - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1300) - #define LUABIND_MSVC_TYPENAME -#else - #define LUABIND_MSVC_TYPENAME typename -#endif - -// the maximum number of arguments of functions that's -// registered. Must at least be 2 -#ifndef LUABIND_MAX_ARITY - #define LUABIND_MAX_ARITY 10 -#elif LUABIND_MAX_ARITY <= 1 - #undef LUABIND_MAX_ARITY - #define LUABIND_MAX_ARITY 2 -#endif - -// the maximum number of classes one class -// can derive from -// max bases must at least be 1 -#ifndef LUABIND_MAX_BASES - #define LUABIND_MAX_BASES 4 -#elif LUABIND_MAX_BASES <= 0 - #undef LUABIND_MAX_BASES - #define LUABIND_MAX_BASES 1 -#endif - -// LUABIND_NO_ERROR_CHECKING -// define this to remove all error checks -// this will improve performance and memory -// footprint. -// if it is defined matchers will only be called on -// overloaded functions, functions that's -// not overloaded will be called directly. The -// parameters on the lua stack are assumed -// to match those of the function. -// exceptions will still be catched when there's -// no error checking. - -// LUABIND_NOT_THREADSAFE -// this define will make luabind non-thread safe. That is, -// it will rely on a static variable. You can still have -// multiple lua states and use coroutines, but only -// one of your real threads may run lua code. - -// LUABIND_NO_EXCEPTIONS -// this define will disable all usage of try, catch and throw in -// luabind. This will in many cases disable runtime-errors, such -// as invalid casts, when calling lua-functions that fails or -// returns values that cannot be converted by the given policy. -// Luabind requires that no function called directly or indirectly -// by luabind throws an exception (throwing exceptions through -// C code has undefined behavior, lua is written in C). - -#ifdef LUABIND_DYNAMIC_LINK -# ifdef BOOST_WINDOWS -# ifdef LUABIND_BUILDING -# define LUABIND_API __declspec(dllexport) -# else -# define LUABIND_API __declspec(dllimport) -# endif -# else -# if defined(_GNUC_) && _GNUC_ >=4 -# define LUABIND_API __attribute__ ((visibility("default"))) -# endif -# endif -#endif - -#ifndef LUABIND_API -# define LUABIND_API -#endif - -namespace luabind { - -LUABIND_API void disable_super_deprecation(); - -} // namespace luabind - -#endif // LUABIND_CONFIG_HPP_INCLUDED - diff --git a/luabind/luabind/container_policy.hpp b/luabind/luabind/container_policy.hpp deleted file mode 100644 index 68ad0a90f..000000000 --- a/luabind/luabind/container_policy.hpp +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED -#define LUABIND_CONTAINER_POLICY_HPP_INCLUDED - -#include -#include -#include - -namespace luabind { namespace detail { - - namespace mpl = boost::mpl; - - template - struct container_converter_lua_to_cpp - { - int const consumed_args(...) - { - return 1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - typedef typename T::value_type value_type; - - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - T container; - - lua_pushnil(L); - while (lua_next(L, index)) - { - container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1)); - lua_pop(L, 1); // pop value - } - - return container; - } - - template - T apply(lua_State* L, by_value, int index) - { - return apply(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if (lua_istable(L, index)) return 0; else return -1; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct container_converter_cpp_to_lua - { - template - void apply(lua_State* L, const T& container) - { - typedef typename T::value_type value_type; - - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - lua_newtable(L); - - int index = 1; - - for (typename T::const_iterator i = container.begin(); i != container.end(); ++i) - { - converter.apply(L, *i); - lua_rawseti(L, -2, index); - ++index; - } - } - }; - - template -// struct container_policy : converter_policy_tag - struct container_policy : conversion_policy - { -// BOOST_STATIC_CONSTANT(int, index = N); - - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_pointers {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , container_converter_lua_to_cpp - , container_converter_cpp_to_lua - >::type type; - }; - }; - -}} - -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - container(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - container(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } -} - -#endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED diff --git a/luabind/luabind/copy_policy.hpp b/luabind/luabind/copy_policy.hpp deleted file mode 100644 index 1a18b729b..000000000 --- a/luabind/luabind/copy_policy.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_COPY_POLICY_081021_HPP -# define LUABIND_COPY_POLICY_081021_HPP - -# include - -namespace luabind { - -namespace detail -{ - - struct copy_converter - { - template - void apply(lua_State* L, T const& x) - { - value_converter().apply(L, x); - } - - template - void apply(lua_State* L, T* x) - { - if (!x) - lua_pushnil(L); - else - apply(L, *x); - } - }; - - template - struct copy_policy : conversion_policy - { - static void precall(lua_State*, index_map const&) - {} - - static void postcall(lua_State*, index_map const&) - {} - - template - struct apply - { - typedef copy_converter type; - }; - }; - -} // namespace detail - -template -detail::policy_cons, detail::null_type> -copy(LUABIND_PLACEHOLDER_ARG(N)) -{ - return detail::policy_cons, detail::null_type>(); -} - -} // namespace luabind - -#endif // LUABIND_COPY_POLICY_081021_HPP - diff --git a/luabind/luabind/dependency_policy.hpp b/luabind/luabind/dependency_policy.hpp deleted file mode 100644 index cafa49aa1..000000000 --- a/luabind/luabind/dependency_policy.hpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED -#define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED - -#include -#include - -namespace luabind { namespace detail -{ - // makes A dependent on B, meaning B will outlive A. - // internally A stores a reference to B - template - struct dependency_policy - { - static void postcall(lua_State* L, const index_map& indices) - { - int nurse_index = indices[A]; - int patient = indices[B]; - - object_rep* nurse = static_cast(lua_touserdata(L, nurse_index)); - - // If the nurse isn't an object_rep, just make this a nop. - if (nurse == 0) - return; - - nurse->add_dependency(L, patient); - } - }; - -}} - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) - -namespace luabind -{ - // most absurd workaround of all time? - namespace detail - { - template - struct size_char_array - { - char storage[N + 2]; - }; - - template - size_char_array deduce_size(LUABIND_PLACEHOLDER_ARG(N)); - - template - struct get_index_workaround - { - static T t; - BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2); - }; - } - - template - detail::policy_cons::value - , detail::get_index_workaround::value>, detail::null_type> dependency(A,B) - { - return detail::policy_cons::value, detail::get_index_workaround::value> - , detail::null_type>(); - } - - template - detail::policy_cons::value>, detail::null_type> - return_internal_reference(A) - { - return detail::policy_cons::value>, detail::null_type>(); - } -} - -#else - -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B)) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - return_internal_reference(LUABIND_PLACEHOLDER_ARG(A)) - { - return detail::policy_cons, detail::null_type>(); - } -} - -#endif - -#endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED - diff --git a/luabind/luabind/detail/calc_arity.hpp b/luabind/luabind/detail/calc_arity.hpp deleted file mode 100644 index c2e0aad91..000000000 --- a/luabind/luabind/detail/calc_arity.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#if !BOOST_PP_IS_ITERATING - -# include - -#ifndef LUABIND_CALC_ARITY_HPP_INCLUDED -#define LUABIND_CALC_ARITY_HPP_INCLUDED - -#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy::type p##n; -#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg - -namespace luabind { namespace detail -{ - template struct calc_arity; - - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() -}} - -#undef LUABIND_CALC_ARITY -#undef LUABIND_FIND_CONV - - -#endif // LUABIND_CALC_ARITY_HPP_INCLUDED - -#else // BOOST_PP_ITERATE - - template<> - struct calc_arity - { - template - static int apply(constructor, Policies*) - { - BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _) - return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _); - } - }; - -#endif - diff --git a/luabind/luabind/detail/call.hpp b/luabind/luabind/detail/call.hpp deleted file mode 100644 index cd9402ef3..000000000 --- a/luabind/luabind/detail/call.hpp +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if !BOOST_PP_IS_ITERATING - -# ifndef LUABIND_CALL2_080911_HPP -# define LUABIND_CALL2_080911_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include -# include - -namespace luabind { namespace detail { - -struct invoke_context; - -struct LUABIND_API function_object -{ - function_object(lua_CFunction entry) - : entry(entry) - , next(0) - {} - - virtual ~function_object() - {} - - virtual int call( - lua_State* L, invoke_context& ctx) const = 0; - virtual void format_signature(lua_State* L, char const* function) const = 0; - - lua_CFunction entry; - std::string name; - function_object* next; - object keepalive; -}; - -struct LUABIND_API invoke_context -{ - invoke_context() - : best_score((std::numeric_limits::max)()) - , candidate_index(0) - {} - - operator bool() const - { - return candidate_index == 1; - } - - void format_error(lua_State* L, function_object const* overloads) const; - - int best_score; - function_object const* candidates[10]; - int candidate_index; -}; - -template -inline int invoke0( - lua_State* L, function_object const& self, invoke_context& ctx - , F const& f, Signature, Policies const& policies, IsVoid, mpl::true_) -{ - return invoke_member( - L, self, ctx, f, Signature(), policies - , mpl::long_::value - 1>(), IsVoid() - ); -} - -template -inline int invoke0( - lua_State* L, function_object const& self, invoke_context& ctx, - F const& f, Signature, Policies const& policies, IsVoid, mpl::false_) -{ - return invoke_normal( - L, self, ctx, f, Signature(), policies - , mpl::long_::value - 1>(), IsVoid() - ); -} - -template -inline int invoke( - lua_State* L, function_object const& self, invoke_context& ctx - , F const& f, Signature, Policies const& policies) -{ - return invoke0( - L, self, ctx, f, Signature(), policies - , boost::is_void::type>() - , boost::is_member_function_pointer() - ); -} - -inline int maybe_yield_aux(lua_State*, int results, mpl::false_) -{ - return results; -} - -inline int maybe_yield_aux(lua_State* L, int results, mpl::true_) -{ - return lua_yield(L, results); -} - -template -int maybe_yield(lua_State* L, int results, Policies*) -{ - return maybe_yield_aux( - L, results, mpl::bool_::value>()); -} - -inline int sum_scores(int const* first, int const* last) -{ - int result = 0; - - for (; first != last; ++first) - { - if (*first < 0) - return *first; - result += *first; - } - - return result; -} - -# define LUABIND_INVOKE_NEXT_ITER(n) \ - typename mpl::next< \ - BOOST_PP_IF( \ - n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \ - >::type - -# define LUABIND_INVOKE_NEXT_INDEX(n) \ - BOOST_PP_IF( \ - n \ - , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \ - BOOST_PP_CAT(c,BOOST_PP_DEC(n)).consumed_args() \ - , 1 \ - ) - -# define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args() - -# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \ - typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \ - typedef typename mpl::deref::type \ - BOOST_PP_CAT(a,n); \ - typedef typename find_conversion_policy::type \ - BOOST_PP_CAT(p,n); \ - typename mpl::apply_wrap2< \ - BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \ - int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n); - -# define LUABIND_INVOKE_COMPUTE_SCORE(n) \ - , BOOST_PP_CAT(c,n).match( \ - L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)) - -# define LUABIND_INVOKE_ARG(z, n, base) \ - BOOST_PP_CAT(c,base(n)).apply( \ - L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n))) - -# define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \ - BOOST_PP_CAT(c,n).converter_postcall( \ - L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)); - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# define LUABIND_INVOKE_VOID -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef LUABIND_INVOKE_VOID -# define LUABIND_INVOKE_MEMBER -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# define LUABIND_INVOKE_VOID -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail - -# endif // LUABIND_CALL2_080911_HPP - -#else // BOOST_PP_IS_ITERATING - -# ifdef LUABIND_INVOKE_MEMBER -# define N BOOST_PP_INC(BOOST_PP_ITERATION()) -# else -# define N BOOST_PP_ITERATION() -# endif - -template -inline int -# ifdef LUABIND_INVOKE_MEMBER -invoke_member -# else -invoke_normal -# endif -( - lua_State* L, function_object const& self, invoke_context& ctx - , F const& f, Signature, Policies const&, mpl::long_ -# ifdef LUABIND_INVOKE_VOID - , mpl::true_ -# else - , mpl::false_ -# endif -) -{ - typedef typename mpl::begin::type first; -# ifndef LUABIND_INVOKE_VOID - typedef typename mpl::deref::type result_type; - typedef typename find_conversion_policy<0, Policies>::type result_policy; - typename mpl::apply_wrap2< - result_policy, result_type, cpp_to_lua>::type result_converter; -# endif - -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - - int const arity = 0 -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_ARITY(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - ; - - int const arguments = lua_gettop(L); - - int score = -1; - - if (arity == arguments) - { - int const scores[] = { - 0 -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_SCORE(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - }; - - score = sum_scores(scores + 1, scores + 1 + N); - } - - if (score >= 0 && score < ctx.best_score) - { - ctx.best_score = score; - ctx.candidates[0] = &self; - ctx.candidate_index = 1; - } - else if (score == ctx.best_score) - { - ctx.candidates[ctx.candidate_index++] = &self; - } - - int results = 0; - - if (self.next) - { - results = self.next->call(L, ctx); - } - - if (score == ctx.best_score && ctx.candidate_index == 1) - { -# ifndef LUABIND_INVOKE_VOID - result_converter.apply( - L, -# endif -# ifdef LUABIND_INVOKE_MEMBER - (c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)( - BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC) - ) -# else -# define LUABIND_INVOKE_IDENTITY(x) x - f( - BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY) - ) -# undef LUABIND_INVOKE_IDENTITY -# endif -# ifndef LUABIND_INVOKE_VOID - ) -# endif - ; - -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - - results = maybe_yield(L, lua_gettop(L) - arguments, (Policies*)0); - - int const indices[] = { - arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index) - }; - - policy_list_postcall::apply(L, indices); - } - - return results; -} - -# undef N - -#endif - diff --git a/luabind/luabind/detail/call_function.hpp b/luabind/luabind/detail/call_function.hpp deleted file mode 100644 index e3ac2b761..000000000 --- a/luabind/luabind/detail/call_function.hpp +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#if !BOOST_PP_IS_ITERATING - -#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED -#define LUABIND_CALL_FUNCTION_HPP_INCLUDED - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace luabind -{ - namespace detail - { - - // if the proxy_function_caller returns non-void - template - class proxy_function_caller - { -// friend class luabind::object; - public: - - typedef int(*function_t)(lua_State*, int, int); - - proxy_function_caller( - lua_State* L - , int params - , function_t fun - , const Tuple args) - : m_state(L) - , m_params(params) - , m_fun(fun) - , m_args(args) - , m_called(false) - { - } - - proxy_function_caller(const proxy_function_caller& rhs) - : m_state(rhs.m_state) - , m_params(rhs.m_params) - , m_fun(rhs.m_fun) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_function_caller() - { - if (m_called) return; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - push_args_from_tuple<1>::apply(L, m_args); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); - -#endif - } - - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - operator Ret() - { - typename mpl::apply_wrap2::type converter; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - push_args_from_tuple<1>::apply(L, m_args); - if (m_fun(L, boost::tuples::length::value, 1)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); - -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - template - Ret operator[](const Policies& p) - { - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (m_fun(L, boost::tuples::length::value, 1)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); - -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - private: - - lua_State* m_state; - int m_params; - function_t m_fun; - Tuple m_args; - mutable bool m_called; - - }; - - // if the proxy_member_caller returns void - template - class proxy_function_void_caller - { - friend class luabind::object; - public: - - typedef int(*function_t)(lua_State*, int, int); - - proxy_function_void_caller( - lua_State* L - , int params - , function_t fun - , const Tuple args) - : m_state(L) - , m_params(params) - , m_fun(fun) - , m_args(args) - , m_called(false) - { - } - - proxy_function_void_caller(const proxy_function_void_caller& rhs) - : m_state(rhs.m_state) - , m_params(rhs.m_params) - , m_fun(rhs.m_fun) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_function_void_caller() - { - if (m_called) return; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - push_args_from_tuple<1>::apply(L, m_args); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - template - void operator[](const Policies& p) - { - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - private: - - lua_State* m_state; - int m_params; - function_t m_fun; - Tuple m_args; - mutable bool m_called; - - }; - - } - - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() - -} - -#endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED - -#else -#if BOOST_PP_ITERATION_FLAGS() == 1 - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - assert(name && "luabind::call_function() expects a function name"); - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - lua_getglobal(L, name); - - return proxy_type(L, 1, &detail::pcall, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - call_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - obj.push(obj.interpreter()); - return proxy_type(obj.interpreter(), 1, &detail::pcall, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - resume_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - assert(name && "luabind::resume_function() expects a function name"); - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - lua_getglobal(L, name); - - return proxy_type(L, 1, &detail::resume_impl, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - resume_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - obj.push(obj.interpreter()); - return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - resume(lua_State* L BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - return proxy_type(L, 0, &detail::resume_impl, args); - } - - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#endif -#endif - diff --git a/luabind/luabind/detail/call_member.hpp b/luabind/luabind/detail/call_member.hpp deleted file mode 100644 index e63555bc6..000000000 --- a/luabind/luabind/detail/call_member.hpp +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#if !BOOST_PP_IS_ITERATING - -#ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED -#define LUABIND_CALL_MEMBER_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include // TODO: REMOVE DEPENDENCY - -#include - -#include -#include -#include - -#include - -namespace luabind -{ - namespace detail - { - - namespace mpl = boost::mpl; - - // if the proxy_member_caller returns non-void - template - class proxy_member_caller - { -// friend class luabind::object; - public: - - proxy_member_caller(lua_State* L_, const Tuple args) - : L(L_) - , m_args(args) - , m_called(false) - { - } - - proxy_member_caller(const proxy_member_caller& rhs) - : L(rhs.L) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_member_caller() - { - if (m_called) return; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - push_args_from_tuple<1>::apply(L, m_args); - if (pcall(L, boost::tuples::length::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - operator Ret() - { - typename mpl::apply_wrap2::type converter; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - push_args_from_tuple<1>::apply(L, m_args); - if (pcall(L, boost::tuples::length::value + 1, 1)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - template - Ret operator[](const Policies& p) - { - typedef typename find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (pcall(L, boost::tuples::length::value + 1, 1)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - private: - - lua_State* L; - Tuple m_args; - mutable bool m_called; - - }; - - // if the proxy_member_caller returns void - template - class proxy_member_void_caller - { - friend class luabind::object; - public: - - proxy_member_void_caller(lua_State* L_, const Tuple args) - : L(L_) - , m_args(args) - , m_called(false) - { - } - - proxy_member_void_caller(const proxy_member_void_caller& rhs) - : L(rhs.L) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_member_void_caller() - { - if (m_called) return; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - push_args_from_tuple<1>::apply(L, m_args); - if (pcall(L, boost::tuples::length::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - template - void operator[](const Policies& p) - { - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (pcall(L, boost::tuples::length::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - private: - lua_State* L; - Tuple m_args; - mutable bool m_called; - - }; - - } // detail - - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() - -} - -#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED - -#else -#if BOOST_PP_ITERATION_FLAGS() == 1 - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - template - typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type - call_member(object const& obj, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - - typedef typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type proxy_type; - - // this will be cleaned up by the proxy object - // once the call has been made - - // get the function - obj.push(obj.interpreter()); - lua_pushstring(obj.interpreter(), name); - lua_gettable(obj.interpreter(), -2); - // duplicate the self-object - lua_pushvalue(obj.interpreter(), -2); - // remove the bottom self-object - lua_remove(obj.interpreter(), -3); - - // now the function and self objects - // are on the stack. These will both - // be popped by pcall - return proxy_type(obj.interpreter(), args); - } - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#endif -#endif - diff --git a/luabind/luabind/detail/call_operator_iterate.hpp b/luabind/luabind/detail/call_operator_iterate.hpp deleted file mode 100644 index c6f95a10c..000000000 --- a/luabind/luabind/detail/call_operator_iterate.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#define N BOOST_PP_ITERATION() - -#define LUABIND_UNWRAP_PARAMETER(z, n, _) \ - typename detail::unwrap_parameter_type::type \ - BOOST_PP_CAT(_, n) - -template -struct BOOST_PP_CAT(call_operator, N) - : detail::operator_< - BOOST_PP_CAT(call_operator, N)< - Self BOOST_PP_ENUM_TRAILING_PARAMS(N, A) - > - > -{ - BOOST_PP_CAT(call_operator, N)(int) {} - - template - struct apply - { - static void execute( - lua_State* L - , typename detail::unwrap_parameter_type::type self - BOOST_PP_ENUM_TRAILING(N, LUABIND_UNWRAP_PARAMETER, _) - ) - { - using namespace detail; - operator_result( - L -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - , self(BOOST_PP_ENUM_PARAMS(N, _)) -#else - , (self(BOOST_PP_ENUM_PARAMS(N, _)), detail::operator_void_return()) -#endif - , (Policies*)0 - ); - } - }; - - static char const* name() { return "__call"; } -}; - -#undef LUABIND_UNWRAP_PARAMETER -#undef N - diff --git a/luabind/luabind/detail/class_cache.hpp b/luabind/luabind/detail/class_cache.hpp deleted file mode 100644 index f49687c30..000000000 --- a/luabind/luabind/detail/class_cache.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin - -// 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. - -#ifndef CLASS_CACHE_040218_HPP -#define CLASS_CACHE_040218_HPP - -#include -#include -#include - -namespace luabind { namespace detail { - -#ifdef LUABIND_NOT_THREADSAFE - - class class_rep; - - template - struct class_cache_impl - { - static lua_State* state; - static class_rep* class_; - }; - - template - lua_State* class_cache_impl::state = 0; - - template - class_rep* class_cache_impl::class_ = 0; - - template - struct class_cache - : class_cache_impl< - typename boost::add_reference< - typename boost::add_const< - T - >::type - >::type - > - { - }; - - template - class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) - { - if (class_cache::state != L) - { - class_cache::state = L; - - class_registry* registry = class_registry::get_registry(L); - class_cache::class_ = registry->find_class(typeid(T)); - } - - return class_cache::class_; - } - -#else - - template - class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) - { - class_registry* registry = class_registry::get_registry(L); - return registry->find_class(typeid(T)); - } - -#endif - -}} // namespace luabind::detail - -#endif // CLASS_CACHE_040218_HPP - diff --git a/luabind/luabind/detail/class_registry.hpp b/luabind/luabind/detail/class_registry.hpp deleted file mode 100644 index 12ed03cfe..000000000 --- a/luabind/luabind/detail/class_registry.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CLASS_REGISTRY_HPP_INCLUDED -#define LUABIND_CLASS_REGISTRY_HPP_INCLUDED - -#include - -#include -#include -#include - -namespace luabind { namespace detail -{ - class class_rep; - - struct LUABIND_API class_registry - { - class_registry(lua_State* L); - - static class_registry* get_registry(lua_State* L); - - int cpp_instance() const { return m_instance_metatable; } - int cpp_class() const { return m_cpp_class_metatable; } - - int lua_instance() const { return m_instance_metatable; } - int lua_class() const { return m_lua_class_metatable; } - int lua_function() const { return m_lua_function_metatable; } - - void add_class(type_id const& info, class_rep* crep); - - class_rep* find_class(type_id const& info) const; - - std::map const& get_classes() const - { - return m_classes; - } - - private: - - std::map m_classes; - - // this is a lua reference that points to the lua table - // that is to be used as meta table for all C++ class - // instances. It is a kind of v-table. - int m_instance_metatable; - - // this is a lua reference to the metatable to be used - // for all classes defined in C++. - int m_cpp_class_metatable; - - // this is a lua reference to the metatable to be used - // for all classes defined in lua - int m_lua_class_metatable; - - // this metatable only contains a destructor - // for luabind::Detail::free_functions::function_rep - int m_lua_function_metatable; - - }; - -}} - -#endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED - diff --git a/luabind/luabind/detail/class_rep.hpp b/luabind/luabind/detail/class_rep.hpp deleted file mode 100644 index aa5e866d3..000000000 --- a/luabind/luabind/detail/class_rep.hpp +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CLASS_REP_HPP_INCLUDED -#define LUABIND_CLASS_REP_HPP_INCLUDED - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - - LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - - struct class_registration; - - struct conversion_storage; - - // This function is used as a tag to identify "properties". - LUABIND_API int property_tag(lua_State*); - - // this is class-specific information, poor man's vtable - // this is allocated statically (removed by the compiler) - // a pointer to this structure is stored in the lua tables' - // metatable with the name __classrep - // it is used when matching parameters to function calls - // to determine possible implicit casts - // it is also used when finding the best match for overloaded - // methods - - class cast_graph; - class class_id_map; - - class LUABIND_API class_rep - { - friend struct class_registration; - friend int super_callback(lua_State*); -//TODO: avoid the lua-prefix - friend int lua_class_gettable(lua_State*); - friend int lua_class_settable(lua_State*); - friend int static_class_gettable(lua_State*); - public: - - enum class_type - { - cpp_class = 0, - lua_class = 1 - }; - - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(type_id const& type - , const char* name - , lua_State* L - ); - - // used when creating a lua class - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(lua_State* L, const char* name); - - ~class_rep(); - - std::pair allocate(lua_State* L) const; - - // this is called as metamethod __call on the class_rep. - static int constructor_dispatcher(lua_State* L); - - struct base_info - { - int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) - class_rep* base; - }; - - void add_base_class(const base_info& binfo); - - const std::vector& bases() const throw() { return m_bases; } - - void set_type(type_id const& t) { m_type = t; } - type_id const& type() const throw() { return m_type; } - - const char* name() const throw() { return m_name; } - - // the lua reference to the metatable for this class' instances - int metatable_ref() const throw() { return m_instance_metatable; } - - void get_table(lua_State* L) const { m_table.push(L); } - void get_default_table(lua_State* L) const { m_default_table.push(L); } - - class_type get_class_type() const { return m_class_type; } - - void add_static_constant(const char* name, int val); - - static int super_callback(lua_State* L); - - static int lua_settable_dispatcher(lua_State* L); - - // called from the metamethod for __index - // obj is the object pointer - static int static_class_gettable(lua_State* L); - - bool has_operator_in_lua(lua_State*, int id); - - cast_graph const& casts() const - { - return *m_casts; - } - - class_id_map const& classes() const - { - return *m_classes; - } - - private: - - void cache_operators(lua_State*); - - // this is a pointer to the type_info structure for - // this type - // warning: this may be a problem when using dll:s, since - // typeid() may actually return different pointers for the same - // type. - type_id m_type; - - // a list of info for every class this class derives from - // the information stored here is sufficient to do - // type casts to the base classes - std::vector m_bases; - - // the class' name (as given when registered to lua with class_) - const char* m_name; - - // a reference to this structure itself. Since this struct - // is kept inside lua (to let lua collect it when lua_close() - // is called) we need to lock it to prevent collection. - // the actual reference is not currently used. - detail::lua_reference m_self_ref; - - // this should always be used when accessing - // members in instances of a class. - // this table contains c closures for all - // member functions in this class, they - // may point to both static and virtual functions - handle m_table; - - // this table contains default implementations of the - // virtual functions in m_table. - handle m_default_table; - - // the type of this class.. determines if it's written in c++ or lua - class_type m_class_type; - - // this is a lua reference that points to the lua table - // that is to be used as meta table for all instances - // of this class. - int m_instance_metatable; - - std::map m_static_constants; - - // the first time an operator is invoked - // we check the associated lua table - // and cache the result - int m_operator_cache; - - cast_graph* m_casts; - class_id_map* m_classes; - }; - - bool is_class_rep(lua_State* L, int index); - -}} - -//#include - -#endif // LUABIND_CLASS_REP_HPP_INCLUDED diff --git a/luabind/luabind/detail/compute_score.hpp b/luabind/luabind/detail/compute_score.hpp deleted file mode 100644 index c9a7e9ea1..000000000 --- a/luabind/luabind/detail/compute_score.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_COMPUTE_RANK_081006_HPP -# define LUABIND_COMPUTE_RANK_081006_HPP - -# include -# include -# include -# include -# include -# include - -namespace luabind { namespace detail { - -namespace mpl = boost::mpl; - -template -int compute_score_aux( - lua_State*L, int index, Idx, Iter, End end, Policies const& policies) -{ - typedef typename Iter::type arg_type; - typedef typename find_conversion_policy::type - conversion_policy; - typedef typename mpl::apply_wrap2< - conversion_policy, arg_type, lua_to_cpp>::type converter; - - int score = converter::match(L, LUABIND_DECORATE_TYPE(arg_type), index); - - if (score < 0) - return score; - - if (conversion_policy::has_arg) - ++index; - - int next = compute_score_aux( - L - , index - , typename mpl::next::type() - , typename mpl::next::type() - , end - , policies - ); - - if (next < 0) - return next; - - return score + next; -} - -template -int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&) -{ - return 0; -} - -template -int compute_score(lua_State* L, Signature, Policies const& policies) -{ - return compute_score_aux( - L - , 1 - , mpl::int_<1>() - , typename mpl::next::type>::type() - , typename mpl::end::type() - , policies - ); -} - -}} // namespace luabind::detail - -#endif // LUABIND_COMPUTE_RANK_081006_HPP diff --git a/luabind/luabind/detail/constructor.hpp b/luabind/luabind/detail/constructor.hpp deleted file mode 100644 index 1cbceb789..000000000 --- a/luabind/luabind/detail/constructor.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if !BOOST_PP_IS_ITERATING - -# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP - -# include -# include -# include -# include - -# include -# include -# include -# include - -namespace luabind { namespace detail { - -inline void inject_backref(lua_State*, void*, void*) -{} - -template -void inject_backref(lua_State* L, T* p, wrap_base*) -{ - weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p)); -} - -template -struct construct_aux; - -template -struct construct - : construct_aux::value - 2, T, Pointer, Signature> -{}; - -template -struct construct_aux<0, T, Pointer, Signature> -{ - typedef pointer_holder holder_type; - - void operator()(argument const& self_) const - { - object_rep* self = touserdata(self_); - class_rep* cls = self->crep(); - - std::auto_ptr instance(new T); - inject_backref(self_.interpreter(), instance.get(), instance.get()); - - void* naked_ptr = instance.get(); - Pointer ptr(instance.release()); - - void* storage = self->allocate(sizeof(holder_type)); - - self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); - } -}; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (1, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail - -# endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP - -#else // !BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() - -template -struct construct_aux -{ - typedef typename mpl::begin::type first; - typedef typename mpl::next::type iter0; - -# define BOOST_PP_LOCAL_MACRO(n) \ - typedef typename mpl::next< \ - BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \ - typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n)); - -# define BOOST_PP_LOCAL_LIMITS (1,N) -# include BOOST_PP_LOCAL_ITERATE() - - typedef pointer_holder holder_type; - - void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const - { - object_rep* self = touserdata(self_); - class_rep* cls = self->crep(); - - std::auto_ptr instance(new T(BOOST_PP_ENUM_PARAMS(N,_))); - inject_backref(self_.interpreter(), instance.get(), instance.get()); - - void* naked_ptr = instance.get(); - Pointer ptr(instance.release()); - - void* storage = self->allocate(sizeof(holder_type)); - - self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); - } -}; - -# undef N - -#endif - diff --git a/luabind/luabind/detail/conversion_storage.hpp b/luabind/luabind/detail/conversion_storage.hpp deleted file mode 100644 index 153112d62..000000000 --- a/luabind/luabind/detail/conversion_storage.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_CONVERSION_STORAGE_080930_HPP -# define LUABIND_CONVERSION_STORAGE_080930_HPP - -# include -# include - -namespace luabind { namespace detail { - -typedef void(*destruction_function)(void*); - -// This is used by the converters in policy.hpp, and -// class_rep::convert_to as temporary storage when constructing -// holders. - -struct conversion_storage -{ - conversion_storage() - : destructor(0) - {} - - ~conversion_storage() - { - if (destructor) - destructor(&data); - } - - // Unfortunately the converters currently doesn't have access to - // the actual type being converted when this is instantiated, so - // we have to guess a max size. - boost::aligned_storage<128> data; - destruction_function destructor; -}; - -}} // namespace luabind::detail - -#endif // LUABIND_CONVERSION_STORAGE_080930_HPP - diff --git a/luabind/luabind/detail/convert_to_lua.hpp b/luabind/luabind/detail/convert_to_lua.hpp deleted file mode 100644 index f5aa89aea..000000000 --- a/luabind/luabind/detail/convert_to_lua.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED -#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED - -#include -#include -#include - -#include - -namespace luabind { namespace detail -{ - template - struct unwrap_ref - { - template - static const T& get(const T& r) { return r; } - - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct unwrap_ref - { - template - static T& get(const boost::reference_wrapper& r) { return r.get(); } - - template - struct apply - { - typedef typename T::type& type; - }; - }; - - namespace mpl = boost::mpl; - - template - void convert_to_lua(lua_State* L, const T& v) - { - typedef typename mpl::apply_wrap1< - unwrap_ref::value> - , T - >::type value_type; - - typename mpl::apply_wrap2::type converter; - - converter.apply(L, unwrap_ref::value>::get(v)); - } - - template - void convert_to_lua_p(lua_State* L, const T& v, const Policies&) - { - typedef typename mpl::apply_wrap1< - unwrap_ref::value> - , T - >::type value_type; - - typedef typename find_conversion_policy::type converter_policy; - typename mpl::apply_wrap2::type converter; - - converter.apply(L, unwrap_ref::value>::get(v)); - } -}} - -#endif - diff --git a/luabind/luabind/detail/debug.hpp b/luabind/luabind/detail/debug.hpp deleted file mode 100644 index ef13bc886..000000000 --- a/luabind/luabind/detail/debug.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_DEBUG_HPP_INCLUDED -#define LUABIND_DEBUG_HPP_INCLUDED - -#ifndef NDEBUG - -#include -#include - -namespace luabind { namespace detail -{ - struct stack_checker_type - { - stack_checker_type(lua_State* L) - : m_L(L) - , m_stack(lua_gettop(m_L)) - {} - - ~stack_checker_type() - { - assert(m_stack == lua_gettop(m_L)); - } - - lua_State* m_L; - int m_stack; - }; - -}} -#define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) -#else -#define LUABIND_CHECK_STACK(L) do {} while (0) -#endif - -#endif // LUABIND_DEBUG_HPP_INCLUDED diff --git a/luabind/luabind/detail/decorate_type.hpp b/luabind/luabind/detail/decorate_type.hpp deleted file mode 100644 index bb144c463..000000000 --- a/luabind/luabind/detail/decorate_type.hpp +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_DECORATE_TYPE_HPP_INCLUDED -#define LUABIND_DECORATE_TYPE_HPP_INCLUDED - -#include -#include - -namespace luabind { namespace detail -{ - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct decorated_type - { - static by_value t; - static inline by_value& get() { return /*by_value()*/t; } - }; - - template - by_value decorated_type::t; - - template - struct decorated_type - { - static by_pointer t; - static inline by_pointer& get() { return /*by_pointer()*/t; } - }; - - template - by_pointer decorated_type::t; - - template - struct decorated_type - { - static by_const_pointer t; - static inline by_const_pointer get() { return /*by_const_pointer()*/t; } - }; - - template - by_const_pointer decorated_type::t; - - template - struct decorated_type - { - static by_const_pointer t; - static inline by_const_pointer& get() { return /*by_const_pointer()*/t; } - }; - - template - by_const_pointer decorated_type::t; - - template - struct decorated_type - { - static by_reference t; - static inline by_reference& get() { return /*by_reference()*/t; } - }; - - template - by_reference decorated_type::t; - - template - struct decorated_type - { - static by_const_reference t; - static inline by_const_reference& get() { return /*by_const_reference()*/t; } - }; - - template - by_const_reference decorated_type::t; - - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get() - -#else - -#include - - namespace - { - LUABIND_ANONYMOUS_FIX char decorated_type_array[64]; - } - - template - struct decorated_type_cref_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_const_reference get(const U&) - { - return by_const_reference(); - } - static T data() { return reinterpret_cast(decorated_type_array); } -#else - - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_const_reference get(void(*f)(const U&)) - { return by_const_reference(); } -#endif - }; - - template - struct decorated_type_ref_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_reference get(U&) - { - return by_reference(); - } - static T data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_reference get(void(*)(U&)) - { return by_reference(); } -#endif - }; - - template - struct decorated_type_cptr_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_const_pointer get(const U*) - { - return by_const_pointer(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_const_pointer get(void(*)(const U*)) - { return by_const_pointer(); } -#endif - }; - - template - struct decorated_type_ptr_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_pointer get(U*) - { - return by_pointer(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_pointer get(void(*)(U*)) - { return by_pointer(); } -#endif - }; - - template - struct decorated_type_value_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_value get(U&) - { - return by_value(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T&) - { return (void(*)(T&))0; } - - template - static by_value get(void(*)(U&)) - { return by_value(); } -#endif - }; - - template<> - struct decorated_type_value_impl - { - static by_value get(int) - { - return by_value(); - } - static int data() { return 0; } - }; - - template - struct decorated_type_array_impl - { - template - static by_pointer get(U*) - { - return by_pointer(); - } - - template - static by_pointer get(void(*)(U)) - { return by_pointer(); } - - static T& data() { return reinterpret_cast(decorated_type_array); } - }; - - template - struct decorated_type -// : boost::mpl::if_ -// , decorated_type_array_impl - : boost::mpl::if_ - , decorated_type_cref_impl - , typename boost::mpl::if_ - , decorated_type_ref_impl - , typename boost::mpl::if_ - , decorated_type_ptr_impl - , typename boost::mpl::if_ - , decorated_type_cptr_impl - , decorated_type_value_impl - >::type - >::type - >::type - >::type -// >::type - { - }; - -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) -#else -// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get((void(*)(type))0) - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) - //#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(type()) -#endif - -#endif - -}} - -#endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED diff --git a/luabind/luabind/detail/deduce_signature.hpp b/luabind/luabind/detail/deduce_signature.hpp deleted file mode 100644 index e47e22f4e..000000000 --- a/luabind/luabind/detail/deduce_signature.hpp +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if !BOOST_PP_IS_ITERATING - -# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP -# define LUABIND_DEDUCE_SIGNATURE_080911_HPP - -# include - -# if LUABIND_MAX_ARITY <= 8 -# include -# else -# include -# endif -# include -# include -# include - -namespace luabind { namespace detail { - -namespace mpl = boost::mpl; - -template -mpl::vector1 deduce_signature(R(*)(), ...) -{ - return mpl::vector1(); -} - -template -mpl::vector2 deduce_signature(R(T::*)()) -{ - return mpl::vector2(); -} - -template -mpl::vector2::type&> -deduce_signature(R(T::*)(), Wrapped*) -{ - return mpl::vector2::type&>(); -} - -template -mpl::vector2 deduce_signature(R(T::*)() const) -{ - return mpl::vector2(); -} - -template -mpl::vector2::type const&> -deduce_signature(R(T::*)() const, Wrapped*) -{ - return mpl::vector2::type const&>(); -} - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (1, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail - -# endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP - -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define NPLUS1 BOOST_PP_INC(N) - -template -BOOST_PP_CAT(mpl::vector,NPLUS1) -deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS1)(); -} - -# define NPLUS2 BOOST_PP_INC(NPLUS1) - -template -BOOST_PP_CAT(mpl::vector,NPLUS2) -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A))) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2)< - R, typename most_derived::type&, BOOST_PP_ENUM_PARAMS(N,A) -> -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)< - R,typename most_derived::type&,BOOST_PP_ENUM_PARAMS(N,A)>(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2) -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2)< - R, typename most_derived::type const&, BOOST_PP_ENUM_PARAMS(N,A) -> -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)< - R,typename most_derived::type const&,BOOST_PP_ENUM_PARAMS(N,A)>(); -} - -# undef NPLUS2 -# undef NPLUS1 -# undef N - -#endif // BOOST_PP_IS_ITERATING - diff --git a/luabind/luabind/detail/enum_maker.hpp b/luabind/luabind/detail/enum_maker.hpp deleted file mode 100644 index fadbe3e52..000000000 --- a/luabind/luabind/detail/enum_maker.hpp +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_ENUM_MAKER_HPP_INCLUDED -#define LUABIND_ENUM_MAKER_HPP_INCLUDED - -#include -#include - -#include -#include - -namespace luabind -{ - struct value; - - struct value_vector : public std::vector - { - // a bug in intel's compiler forces us to declare these constructors explicitly. - value_vector(); - virtual ~value_vector(); - value_vector(const value_vector& v); - value_vector& operator,(const value& rhs); - }; - - struct value - { - friend class std::vector; - template - value(const char* name, T v) - : name_(name) - , val_(v) - {} - - const char* name_; - int val_; - - value_vector operator,(const value& rhs) const - { - value_vector v; - - v.push_back(*this); - v.push_back(rhs); - - return v; - } - - private: - - value() {} - }; - - inline value_vector::value_vector() - : std::vector() - { - } - - inline value_vector::~value_vector() {} - - inline value_vector::value_vector(const value_vector& rhs) - : std::vector(rhs) - { - } - - inline value_vector& value_vector::operator,(const value& rhs) - { - push_back(rhs); - return *this; - } - - namespace detail - { - template - struct enum_maker - { - explicit enum_maker(From& from): from_(from) {} - - From& operator[](const value& val) - { - from_.add_static_constant(val.name_, val.val_); - return from_; - } - - From& operator[](const value_vector& values) - { - for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i) - { - from_.add_static_constant(i->name_, i->val_); - } - - return from_; - } - - From& from_; - - private: - void operator=(enum_maker const&); // C4512, assignment operator could not be generated - template void operator,(T const&) const; - }; - } -} - -#endif // LUABIND_ENUM_MAKER_HPP_INCLUDED diff --git a/luabind/luabind/detail/format_signature.hpp b/luabind/luabind/detail/format_signature.hpp deleted file mode 100644 index ec56b6196..000000000 --- a/luabind/luabind/detail/format_signature.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP -# define LUABIND_FORMAT_SIGNATURE_081014_HPP - -# include -# include -# include - -# include -# include -# include - -namespace luabind { namespace adl { - - class object; - class argument; - template - struct table; -} // namespace adl - -using adl::object; -using adl::argument; -using adl::table; - -} // namespace luabind - -namespace luabind { namespace detail { - -LUABIND_API std::string get_class_name(lua_State* L, type_id const& i); - -template -struct type_to_string -{ - static void get(lua_State* L) - { - lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); - } -}; - -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "*"); - lua_concat(L, 2); - } -}; - -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "&"); - lua_concat(L, 2); - } -}; - -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, " const"); - lua_concat(L, 2); - } -}; - -# define LUABIND_TYPE_TO_STRING(x) \ - template <> \ - struct type_to_string \ - { \ - static void get(lua_State* L) \ - { \ - lua_pushstring(L, #x); \ - } \ - }; - -# define LUABIND_INTEGRAL_TYPE_TO_STRING(x) \ - LUABIND_TYPE_TO_STRING(x) \ - LUABIND_TYPE_TO_STRING(unsigned x) - -LUABIND_INTEGRAL_TYPE_TO_STRING(char) -LUABIND_INTEGRAL_TYPE_TO_STRING(short) -LUABIND_INTEGRAL_TYPE_TO_STRING(int) -LUABIND_INTEGRAL_TYPE_TO_STRING(long) - -LUABIND_TYPE_TO_STRING(void) -LUABIND_TYPE_TO_STRING(bool) -LUABIND_TYPE_TO_STRING(std::string) -LUABIND_TYPE_TO_STRING(lua_State) - -LUABIND_TYPE_TO_STRING(luabind::object) -LUABIND_TYPE_TO_STRING(luabind::argument) - -# undef LUABIND_INTEGRAL_TYPE_TO_STRING -# undef LUABIND_TYPE_TO_STRING - -template -struct type_to_string > -{ - static void get(lua_State* L) - { - lua_pushstring(L, "table"); - } -}; - -template -void format_signature_aux(lua_State*, bool, End, End) -{} - -template -void format_signature_aux(lua_State* L, bool first, Iter, End end) -{ - if (!first) - lua_pushstring(L, ","); - type_to_string::get(L); - format_signature_aux(L, false, typename mpl::next::type(), end); -} - -template -void format_signature(lua_State* L, char const* function, Signature) -{ - typedef typename mpl::begin::type first; - - type_to_string::get(L); - - lua_pushstring(L, " "); - lua_pushstring(L, function); - - lua_pushstring(L, "("); - format_signature_aux( - L - , true - , typename mpl::next::type() - , typename mpl::end::type() - ); - lua_pushstring(L, ")"); - - lua_concat(L, static_cast(mpl::size()) * 2 + 2); -} - -}} // namespace luabind::detail - -#endif // LUABIND_FORMAT_SIGNATURE_081014_HPP - diff --git a/luabind/luabind/detail/garbage_collector.hpp b/luabind/luabind/detail/garbage_collector.hpp deleted file mode 100644 index c0d68aa36..000000000 --- a/luabind/luabind/detail/garbage_collector.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED -#define LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED - -#include - -namespace luabind { namespace detail -{ - // function that is used as __gc metafunction on several objects - template - inline int garbage_collector(lua_State* L) - { - T* obj = static_cast(lua_touserdata(L, -1)); - obj->~T(); - return 0; - } - - template - struct garbage_collector_s - { - static int apply(lua_State* L) - { - T* obj = static_cast(lua_touserdata(L, -1)); - obj->~T(); - return 0; - } - }; - -}} - -#endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED diff --git a/luabind/luabind/detail/has_get_pointer.hpp b/luabind/luabind/detail/has_get_pointer.hpp deleted file mode 100644 index 8a001ddda..000000000 --- a/luabind/luabind/detail/has_get_pointer.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin - -// 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. - -#ifndef LUABIND_HAS_GET_POINTER_051022_HPP -# define LUABIND_HAS_GET_POINTER_051022_HPP - -# include - -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -# include -# endif - -namespace luabind { namespace detail { - -namespace has_get_pointer_ -{ - - struct any - { - template any(T const&); - }; - - struct no_overload_tag - {}; - - typedef char (&yes)[1]; - typedef char (&no)[2]; - - no_overload_tag operator,(no_overload_tag, int); - -// -// On compilers with ADL, we need these generic overloads in this -// namespace as well as in luabind::. Otherwise get_pointer(any) -// will be found before them. -// -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP - - template - T* get_pointer(T const volatile*); - - template - T* get_pointer(std::auto_ptr const&); - -# endif - -// -// On compilers that doesn't support ADL, the overload below has to -// live in luabind::. -// -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -}} // namespace detail::has_get_pointer_ -# endif - -detail::has_get_pointer_::no_overload_tag - get_pointer(detail::has_get_pointer_::any); - -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -namespace detail { namespace has_get_pointer_ -{ -# endif - - template - yes check(T const&); - no check(no_overload_tag); - - template - struct impl - { - static typename boost::add_reference::type x; - - BOOST_STATIC_CONSTANT(bool, - value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1 - ); - - typedef boost::mpl::bool_ type; - }; - -} // namespace has_get_pointer_ - -template -struct has_get_pointer - : has_get_pointer_::impl::type -{}; - -}} // namespace luabind::detail - -#endif // LUABIND_HAS_GET_POINTER_051022_HPP - diff --git a/luabind/luabind/detail/inheritance.hpp b/luabind/luabind/detail/inheritance.hpp deleted file mode 100644 index a7afe0156..000000000 --- a/luabind/luabind/detail/inheritance.hpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright Daniel Wallin 2009. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_INHERITANCE_090217_HPP -# define LUABIND_INHERITANCE_090217_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace luabind { namespace detail { - -typedef void*(*cast_function)(void*); -typedef std::size_t class_id; - -class_id const unknown_class = (std::numeric_limits::max)(); - -class class_rep; - -class LUABIND_API cast_graph -{ -public: - cast_graph(); - ~cast_graph(); - - // `src` and `p` here describe the *most derived* object. This means that - // for a polymorphic type, the pointer must be cast with - // dynamic_cast before being passed in here, and `src` has to - // match typeid(*p). - std::pair cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const; - void insert(class_id src, class_id target, cast_function cast); - -private: - class impl; - boost::scoped_ptr m_impl; -}; - -// Maps a type_id to a class_id. Note that this actually partitions the -// id-space into two, using one half for "local" ids; ids that are used only as -// keys into the conversion cache. This is needed because we need a unique key -// even for types that hasn't been registered explicitly. -class LUABIND_API class_id_map -{ -public: - class_id_map(); - - class_id get(type_id const& type) const; - class_id get_local(type_id const& type); - void put(class_id id, type_id const& type); - -private: - typedef std::map map_type; - map_type m_classes; - class_id m_local_id; - - static class_id const local_id_base; -}; - -inline class_id_map::class_id_map() - : m_local_id(local_id_base) -{} - -inline class_id class_id_map::get(type_id const& type) const -{ - map_type::const_iterator i = m_classes.find(type); - if (i == m_classes.end() || i->second >= local_id_base) - return unknown_class; - return i->second; -} - -inline class_id class_id_map::get_local(type_id const& type) -{ - std::pair result = m_classes.insert( - std::make_pair(type, 0)); - - if (result.second) - result.first->second = m_local_id++; - - assert(m_local_id >= local_id_base); - - return result.first->second; -} - -inline void class_id_map::put(class_id id, type_id const& type) -{ - assert(id < local_id_base); - - std::pair result = m_classes.insert( - std::make_pair(type, 0)); - - assert( - result.second - || result.first->second == id - || result.first->second >= local_id_base - ); - - result.first->second = id; -} - -class class_map -{ -public: - class_rep* get(class_id id) const; - void put(class_id id, class_rep* cls); - -private: - std::vector m_classes; -}; - -inline class_rep* class_map::get(class_id id) const -{ - if (id >= m_classes.size()) - return 0; - return m_classes[id]; -} - -inline void class_map::put(class_id id, class_rep* cls) -{ - if (id >= m_classes.size()) - m_classes.resize(id + 1); - m_classes[id] = cls; -} - -template -struct static_cast_ -{ - static void* execute(void* p) - { - return static_cast(static_cast(p)); - } -}; - -template -struct dynamic_cast_ -{ - static void* execute(void* p) - { - return dynamic_cast(static_cast(p)); - } -}; - -// Thread safe class_id allocation. -LUABIND_API class_id allocate_class_id(type_id const& cls); - -template -struct registered_class -{ - static class_id const id; -}; - -template -class_id const registered_class::id = allocate_class_id(typeid(T)); - -template -struct registered_class - : registered_class -{}; - -}} // namespace luabind::detail - -#endif // LUABIND_INHERITANCE_090217_HPP diff --git a/luabind/luabind/detail/instance_holder.hpp b/luabind/luabind/detail/instance_holder.hpp deleted file mode 100644 index 456e13e6b..000000000 --- a/luabind/luabind/detail/instance_holder.hpp +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_INSTANCE_HOLDER_081024_HPP -# define LUABIND_INSTANCE_HOLDER_081024_HPP - -# include -# include // TODO -# include -# include -# include -# include - -namespace luabind { namespace detail { - -class instance_holder -{ -public: - instance_holder(class_rep* cls, bool pointee_const) - : m_cls(cls) - , m_pointee_const(pointee_const) - {} - - virtual ~instance_holder() - {} - - virtual std::pair get(class_id target) const = 0; - - virtual void release() = 0; - - class_rep* get_class() const - { - return m_cls; - } - - bool pointee_const() const - { - return m_pointee_const; - } - -private: - class_rep* m_cls; - bool m_pointee_const; -}; - -namespace mpl = boost::mpl; - -inline mpl::false_ check_const_pointer(void*) -{ - return mpl::false_(); -} - -inline mpl::true_ check_const_pointer(void const*) -{ - return mpl::true_(); -} - -template -void release_ownership(std::auto_ptr& p) -{ - p.release(); -} - -template -void release_ownership(P const&) -{ - throw std::runtime_error( - "luabind: smart pointer does not allow ownership transfer"); -} - -template -class_id static_class_id(T*) -{ - return registered_class::id; -} - -template -class pointer_holder : public instance_holder -{ -public: - pointer_holder( - P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls - ) - : instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0)) - , p(p) - , weak(0) - , dynamic_id(dynamic_id) - , dynamic_ptr(dynamic_ptr) - {} - - std::pair get(class_id target) const - { - if (target == registered_class

::id) - return std::pair(&this->p, 0); - - void* naked_ptr = const_cast(static_cast( - weak ? weak : get_pointer(p))); - - if (!naked_ptr) - return std::pair((void*)0, 0); - - return get_class()->casts().cast( - naked_ptr - , static_class_id(false ? get_pointer(p) : 0) - , target - , dynamic_id - , dynamic_ptr - ); - } - - void release() - { - weak = const_cast(static_cast( - get_pointer(p))); - release_ownership(p); - } - -private: - mutable P p; - // weak will hold a possibly stale pointer to the object owned - // by p once p has released it's owership. This is a workaround - // to make adopt() work with virtual function wrapper classes. - void* weak; - class_id dynamic_id; - void* dynamic_ptr; -}; - -}} // namespace luabind::detail - -#endif // LUABIND_INSTANCE_HOLDER_081024_HPP diff --git a/luabind/luabind/detail/is_indirect_const.hpp b/luabind/luabind/detail/is_indirect_const.hpp deleted file mode 100644 index b6c1282fb..000000000 --- a/luabind/luabind/detail/is_indirect_const.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef IS_INDIRECT_CONST_040211_HPP -#define IS_INDIRECT_CONST_040211_HPP - -#include -#include -#include - -namespace luabind { - - namespace detail { - - template - typename boost::is_const::type - is_indirect_const_check(T(*)(), int); - - template - typename boost::is_const::type - is_indirect_const_check(T*(*)(), long); - - template - typename boost::is_const::type - is_indirect_const_check(T&(*)(), long); - - yes_t to_yes_no(boost::mpl::true_); - no_t to_yes_no(boost::mpl::false_); - - } // namespace detail - - // returns true for: - // T = U* is_const - // T = U& is_const - // T = U is_const - template - struct is_indirect_const - { - BOOST_STATIC_CONSTANT(int, value = ( - sizeof( - detail::to_yes_no( - detail::is_indirect_const_check((T(*)())0, 0L) - )) - == sizeof(detail::yes_t) - )); - }; - -} // namespace luabind - -#endif // IS_INDIRECT_CONST_040211_HPP - diff --git a/luabind/luabind/detail/link_compatibility.hpp b/luabind/luabind/detail/link_compatibility.hpp deleted file mode 100644 index 6f0006afa..000000000 --- a/luabind/luabind/detail/link_compatibility.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_LINK_COMPATIBILITY_HPP_INCLUDED -#define LUABIND_LINK_COMPATIBILITY_HPP_INCLUDED - -#include - -namespace luabind { namespace detail -{ - -#ifdef LUABIND_NOT_THREADSAFE - LUABIND_API void not_threadsafe_defined_conflict(); -#else - LUABIND_API void not_threadsafe_not_defined_conflict(); -#endif - -#ifdef LUABIND_NO_ERROR_CHECKING - LUABIND_API void no_error_checking_defined_conflict(); -#else - LUABIND_API void no_error_checking_not_defined_conflict(); -#endif - - inline void check_link_compatibility() - { - #ifdef LUABIND_NOT_THREADSAFE - not_threadsafe_defined_conflict(); - #else - not_threadsafe_not_defined_conflict(); - #endif - - #ifdef LUABIND_NO_ERROR_CHECKING - no_error_checking_defined_conflict(); - #else - no_error_checking_not_defined_conflict(); - #endif - } - -}} - -#endif diff --git a/luabind/luabind/detail/make_instance.hpp b/luabind/luabind/detail/make_instance.hpp deleted file mode 100644 index 3150cf048..000000000 --- a/luabind/luabind/detail/make_instance.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright Daniel Wallin 2009. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP -# define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP - -# include -# include -# include - -namespace luabind { namespace detail { - -template -std::pair get_dynamic_class_aux( - lua_State* L, T const* p, mpl::true_) -{ - lua_pushliteral(L, "__luabind_class_id_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - - class_id_map& class_ids = *static_cast( - lua_touserdata(L, -1)); - - lua_pop(L, 1); - - return std::make_pair( - class_ids.get_local(typeid(*p)) - , dynamic_cast(const_cast(p)) - ); -} - -template -std::pair get_dynamic_class_aux( - lua_State*, T const* p, mpl::false_) -{ - return std::make_pair(registered_class::id, (void*)p); -} - -template -std::pair get_dynamic_class(lua_State* L, T* p) -{ - return get_dynamic_class_aux(L, p, boost::is_polymorphic()); -} - -template -class_rep* get_pointee_class(class_map const& classes, T*) -{ - return classes.get(registered_class::id); -} - -template -class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id) -{ - lua_pushliteral(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - - class_map const& classes = *static_cast( - lua_touserdata(L, -1)); - - lua_pop(L, 1); - - class_rep* cls = classes.get(dynamic_id); - - if (!cls) - cls = get_pointee_class(classes, get_pointer(p)); - - return cls; -} - -// Create an appropriate instance holder for the given pointer like object. -template -void make_instance(lua_State* L, P p) -{ - std::pair dynamic = get_dynamic_class(L, get_pointer(p)); - - class_rep* cls = get_pointee_class(L, p, dynamic.first); - - if (!cls) - { - throw std::runtime_error("Trying to use unregistered class"); - } - - object_rep* instance = push_new_instance(L, cls); - - typedef pointer_holder

holder_type; - - void* storage = instance->allocate(sizeof(holder_type)); - - try - { - new (storage) holder_type(p, dynamic.first, dynamic.second, cls); - } - catch (...) - { - instance->deallocate(storage); - lua_pop(L, 1); - throw; - } - - instance->set_instance(static_cast(storage)); -} - -}} // namespace luabind::detail - -#endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP diff --git a/luabind/luabind/detail/most_derived.hpp b/luabind/luabind/detail/most_derived.hpp deleted file mode 100644 index 4dd9d9159..000000000 --- a/luabind/luabind/detail/most_derived.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef MOST_DERIVED_051018_HPP -# define MOST_DERIVED_051018_HPP - -# include -# include - -namespace luabind { namespace detail { - -template -struct most_derived -{ - typedef typename boost::mpl::if_< - boost::is_base_and_derived - , WrappedClass - , Class - >::type type; -}; - -}} // namespace luabind::detail - -#endif // MOST_DERIVED_051018_HPP - diff --git a/luabind/luabind/detail/object_call.hpp b/luabind/luabind/detail/object_call.hpp deleted file mode 100644 index 46ab0d958..000000000 --- a/luabind/luabind/detail/object_call.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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. - -#if !BOOST_PP_IS_ITERATING -# error Do not include object_call.hpp directly! -#endif - -#include -#include -#include - -#define N BOOST_PP_ITERATION() - -template -call_proxy< - Derived - , boost::tuples::tuple< - BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) - > -> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) -{ - typedef boost::tuples::tuple< - BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) - > arguments; - - return call_proxy( - derived() - , arguments(BOOST_PP_ENUM_PARAMS(N, &a)) - ); -} - -#undef N - diff --git a/luabind/luabind/detail/object_funs.hpp b/luabind/luabind/detail/object_funs.hpp deleted file mode 100644 index 2600238d9..000000000 --- a/luabind/luabind/detail/object_funs.hpp +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_OBJECT_PROXY_HPP_INCLUDED -#define LUABIND_OBJECT_PROXY_HPP_INCLUDED - -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace luabind -{ - - namespace detail - { - - namespace mpl = boost::mpl; - - template - inline T object_cast_impl(const Obj& obj, const Policies&) - { - if (obj.lua_state() == 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(0, typeid(T)); -#else - lua_State* L = obj.lua_state(); - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(T)); - - assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - LUABIND_CHECK_STACK(obj.lua_state()); - - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - obj.pushvalue(); - - lua_State* L = obj.lua_state(); - detail::stack_pop p(L, 1); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(T)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(T)); - - assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - - return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1); - } - - template - boost::optional object_cast_nothrow_impl(const Obj& obj, const Policies&) - { - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - if (obj.lua_state() == 0) return boost::optional(); - LUABIND_CHECK_STACK(obj.lua_state()); - - obj.pushvalue(); - - lua_State* L = obj.lua_state(); - detail::stack_pop p(L, 1); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) - return boost::optional(); -#endif - - return boost::optional(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1)); - } - } - - template - T object_cast(const object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_raw_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_raw_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_array_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_array_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_array_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - - - inline object get_globals(lua_State* L) - { - lua_pushvalue(L, LUA_GLOBALSINDEX); - detail::lua_reference ref; - ref.set(L); - return object(L, ref, true/*object::reference()*/); - } - - inline object get_registry(lua_State* L) - { - lua_pushvalue(L, LUA_REGISTRYINDEX); - detail::lua_reference ref; - ref.set(L); - return object(L, ref, true/*object::reference()*/); - } - - inline object newtable(lua_State* L) - { - lua_newtable(L); - detail::lua_reference ref; - ref.set(L); - return object(L, ref, true/*object::reference()*/); - } -} - -/* - -struct A -{ -}; - -object f = class_(); - -A* ptr = object_cast(f(), adopt(_1)); - -delete ptr; - -*/ - -#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED diff --git a/luabind/luabind/detail/object_rep.hpp b/luabind/luabind/detail/object_rep.hpp deleted file mode 100644 index 93b3e39d6..000000000 --- a/luabind/luabind/detail/object_rep.hpp +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_OBJECT_REP_HPP_INCLUDED -#define LUABIND_OBJECT_REP_HPP_INCLUDED - -#include -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - class class_rep; - - void finalize(lua_State* L, class_rep* crep); - - // this class is allocated inside lua for each pointer. - // it contains the actual c++ object-pointer. - // it also tells if it is const or not. - class LUABIND_API object_rep - { - public: - object_rep(instance_holder* instance, class_rep* crep); - ~object_rep(); - - const class_rep* crep() const { return m_classrep; } - class_rep* crep() { return m_classrep; } - - void set_instance(instance_holder* instance) { m_instance = instance; } - - void add_dependency(lua_State* L, int index); - void release_dependency_refs(lua_State* L); - - std::pair get_instance(class_id target) const - { - if (m_instance == 0) - return std::pair((void*)0, -1); - return m_instance->get(target); - } - - bool is_const() const - { - return m_instance && m_instance->pointee_const(); - } - - void release() - { - if (m_instance) - m_instance->release(); - } - - void* allocate(std::size_t size) - { - if (size <= 32) - return &m_instance_buffer; - return std::malloc(size); - } - - void deallocate(void* storage) - { - if (storage == &m_instance_buffer) - return; - std::free(storage); - } - - private: - - object_rep(object_rep const&) - {} - - void operator=(object_rep const&) - {} - - instance_holder* m_instance; - boost::aligned_storage<32> m_instance_buffer; - class_rep* m_classrep; // the class information about this object's type - std::size_t m_dependency_cnt; // counts dependencies - }; - - template - struct delete_s - { - static void apply(void* ptr) - { - delete static_cast(ptr); - } - }; - - template - struct destruct_only_s - { - static void apply(void* ptr) - { - // Removes unreferenced formal parameter warning on VC7. - (void)ptr; -#ifndef NDEBUG - int completeness_check[sizeof(T)]; - (void)completeness_check; -#endif - static_cast(ptr)->~T(); - } - }; - - LUABIND_API object_rep* get_instance(lua_State* L, int index); - LUABIND_API void push_instance_metatable(lua_State* L); - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); - -}} - -#endif // LUABIND_OBJECT_REP_HPP_INCLUDED - diff --git a/luabind/luabind/detail/open.hpp b/luabind/luabind/detail/open.hpp deleted file mode 100644 index a30faeef8..000000000 --- a/luabind/luabind/detail/open.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_OPEN_HPP_INCLUDED -#define LUABIND_OPEN_HPP_INCLUDED - -#include - -namespace luabind -{ - namespace detail - { - LUABIND_API void add_operator_to_metatable(lua_State* L, int op_index); - LUABIND_API int create_cpp_class_metatable(lua_State* L); - LUABIND_API int create_cpp_instance_metatable(lua_State* L); - LUABIND_API int create_lua_class_metatable(lua_State* L); - LUABIND_API int create_lua_instance_metatable(lua_State* L); - LUABIND_API int create_lua_function_metatable(lua_State* L); - } - - LUABIND_API void open(lua_State* L); -} - -#endif // LUABIND_OPEN_HPP_INCLUDED - diff --git a/luabind/luabind/detail/operator_id.hpp b/luabind/luabind/detail/operator_id.hpp deleted file mode 100644 index ed64ba6d5..000000000 --- a/luabind/luabind/detail/operator_id.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_OPERATOR_ID_HPP_INCLUDED -#define LUABIND_OPERATOR_ID_HPP_INCLUDED - -#include - -namespace luabind { namespace detail { - - enum operator_id - { - op_add = 0, - op_sub, - op_mul, - op_div, - op_pow, - op_lt, - op_le, - op_eq, - op_call, - op_unm, - op_tostring, - op_concat, - op_len, - - number_of_operators - }; - - inline const char* get_operator_name(int i) - { - static const char* a[number_of_operators] = { - "__add", "__sub", "__mul", "__div", "__pow", - "__lt", "__le", "__eq", "__call", "__unm", - "__tostring", "__concat", "__len" }; - return a[i]; - } - - inline const char* get_operator_symbol(int i) - { - static const char* a[number_of_operators] = { - "+", "-", "*", "/", "^", "<", - "<=", "==", "()", "- (unary)", - "tostring", "..", "#" }; - return a[i]; - } - - inline bool is_unary(int i) - { - // the reason why unary minus is not considered a unary operator here is - // that it always is given two parameters, where the second parameter always - // is nil. - return i == op_tostring; - } - - -}} - -#endif // LUABIND_OPERATOR_ID_HPP_INCLUDED diff --git a/luabind/luabind/detail/other.hpp b/luabind/luabind/detail/other.hpp deleted file mode 100644 index 679058c9e..000000000 --- a/luabind/luabind/detail/other.hpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_OTHER_HPP_INCLUDED -#define LUABIND_OTHER_HPP_INCLUDED - -// header derived from source code found in Boost.Python - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include - -namespace luabind -{ - template - struct other - { - typedef T type; - }; -} - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace luabind { namespace detail -{ - template - class unwrap_other - { - public: - typedef T type; - }; - - template - class unwrap_other > - { - public: - typedef T type; - }; -}} // namespace luabind::detail - -# else // no partial specialization - -#include - -namespace luabind { namespace detail -{ - typedef char (&yes_other_t)[1]; - typedef char (&no_other_t)[2]; - - no_other_t is_other_test(...); - - template - yes_other_t is_other_test(type_< other >); - - template - struct other_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct other_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; - - template - class is_other - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_other_test(type_())) - == sizeof(detail::yes_other_t))); - }; - - template - class unwrap_other - : public detail::other_unwrapper< - is_other::value - >::template apply - {}; - -}} // namespace luabind::detail -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -#endif // LUABIND_OTHER_HPP_INCLUDED diff --git a/luabind/luabind/detail/pcall.hpp b/luabind/luabind/detail/pcall.hpp deleted file mode 100644 index f0d72b162..000000000 --- a/luabind/luabind/detail/pcall.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_PCALL_HPP_INCLUDED -#define LUABIND_PCALL_HPP_INCLUDED - -#include - -struct lua_State; - -namespace luabind { namespace detail -{ - LUABIND_API int pcall(lua_State *L, int nargs, int nresults); - LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); -}} - -#endif diff --git a/luabind/luabind/detail/pointee_sizeof.hpp b/luabind/luabind/detail/pointee_sizeof.hpp deleted file mode 100644 index 3875c09dd..000000000 --- a/luabind/luabind/detail/pointee_sizeof.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef POINTEE_SIZEOF_040211_HPP -#define POINTEE_SIZEOF_040211_HPP - -#include - -namespace luabind { - - namespace detail { - - template T& deref_type(T(*)(), int); - template T& deref_type(T*(*)(), long); - - } // namespace detail - - // returns the indirect sizeof U, as in - // sizeof(T*) = sizeof(T) - // sizeof(T&) = sizeof(T) - // sizeof(T) = sizeof(T) - template - struct pointee_sizeof - { - BOOST_STATIC_CONSTANT(int, value = ( - sizeof(detail::deref_type((T(*)())0), 0L) - )); - - typedef boost::mpl::int_ type; - }; - -} // namespace luabind - -#endif // POINTEE_SIZEOF_040211_HPP - diff --git a/luabind/luabind/detail/pointee_typeid.hpp b/luabind/luabind/detail/pointee_typeid.hpp deleted file mode 100644 index ab4113711..000000000 --- a/luabind/luabind/detail/pointee_typeid.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin - -// 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. - -#ifndef POINTEE_TYPEID_040211_HPP -#define POINTEE_TYPEID_040211_HPP - -#include -#include - -namespace luabind { namespace detail { - - template - type_id pointee_typeid(T*) - { - return typeid(T); - } - -}} // namespace luabind::detail - -#endif // POINTEE_TYPEID_040211_HPP - diff --git a/luabind/luabind/detail/policy.hpp b/luabind/luabind/detail/policy.hpp deleted file mode 100644 index 79577c9a4..000000000 --- a/luabind/luabind/detail/policy.hpp +++ /dev/null @@ -1,1022 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_POLICY_HPP_INCLUDED -#define LUABIND_POLICY_HPP_INCLUDED - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -namespace luabind -{ - namespace detail - { - struct conversion_policy_base {}; - } - - template - struct conversion_policy : detail::conversion_policy_base - { - BOOST_STATIC_CONSTANT(int, index = N); - BOOST_STATIC_CONSTANT(bool, has_arg = HasArg); - }; - - class index_map - { - public: - index_map(const int* m): m_map(m) {} - - int operator[](int index) const - { - return m_map[index]; - } - - private: - const int* m_map; - }; - -// template class functor; - class weak_ref; -} - -namespace luabind { namespace detail -{ - template - struct policy_cons - { - typedef H head; - typedef T tail; - - template - policy_cons > operator,(policy_cons) - { - return policy_cons >(); - } - - template - policy_cons > operator+(policy_cons) - { - return policy_cons >(); - } - - template - policy_cons > operator|(policy_cons) - { - return policy_cons >(); - } - }; - - struct indirection_layer - { - template - indirection_layer(const T&); - }; - - yes_t is_policy_cons_test(const null_type&); - template - yes_t is_policy_cons_test(const policy_cons&); - no_t is_policy_cons_test(...); - - template - struct is_policy_cons - { - static const T& t; - - BOOST_STATIC_CONSTANT(bool, value = - sizeof(is_policy_cons_test(t)) == sizeof(yes_t)); - - typedef boost::mpl::bool_ type; - }; - - template - struct is_string_literal - { - static no_t helper(indirection_layer); - static yes_t helper(const char*); - }; - - template<> - struct is_string_literal - { - static no_t helper(indirection_layer); - }; - - - namespace mpl = boost::mpl; - - template - void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone) - { - if (get_pointer(x)) - { - make_instance(L, x); - } - else - { - lua_pushnil(L); - } - } - - template - void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_) - { - std::auto_ptr ptr(new T(x)); - make_instance(L, ptr); - } - - template - void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_) - { - make_instance(L, &x); - } - - template - void make_pointee_instance(lua_State* L, T& x, Clone) - { - make_pointee_instance(L, x, has_get_pointer(), Clone()); - } - -// ********** pointer converter *********** - - struct pointer_converter - { - typedef pointer_converter type; - typedef mpl::false_ is_native; - - pointer_converter() - : result(0) - {} - - void* result; - - int const consumed_args(...) - { - return 1; - } - - template - void apply(lua_State* L, T* ptr) - { - if (ptr == 0) - { - lua_pushnil(L); - return; - } - - if (luabind::get_back_reference(L, ptr)) - return; - - make_instance(L, ptr); - } - - template - T* apply(lua_State*, by_pointer, int) - { - return static_cast(result); - } - - template - int match(lua_State* L, by_pointer, int index) - { - if (lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - if (obj->is_const()) - return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_pointer, int) - {} - }; - -// ******* value converter ******* - - struct value_converter - { - typedef value_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - value_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, T x) - { - if (luabind::get_back_reference(L, x)) - return; - - make_pointee_instance(L, x, mpl::true_()); - } - - template - T apply(lua_State*, by_value, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_value, int index) - { - // special case if we get nil in, try to match the holder type - if (lua_isnil(L, index)) - return -1; - - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******* const pointer converter ******* - - struct const_pointer_converter - { - typedef const_pointer_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - const_pointer_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, const T* ptr) - { - if (ptr == 0) - { - lua_pushnil(L); - return; - } - - if (luabind::get_back_reference(L, ptr)) - return; - - make_instance(L, ptr); - } - - template - T const* apply(lua_State*, by_const_pointer, int) - { - return static_cast(result); - } - - template - int match(lua_State* L, by_const_pointer, int index) - { - if (lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match - std::pair s = obj->get_instance(registered_class::id); - if (s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******* reference converter ******* - - struct ref_converter : pointer_converter - { - typedef ref_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - void apply(lua_State* L, T& ref) - { - if (luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, mpl::false_()); - } - - template - T& apply(lua_State* L, by_reference, int index) - { - assert(!lua_isnil(L, index)); - return *pointer_converter::apply(L, by_pointer(), index); - } - - template - int match(lua_State* L, by_reference, int index) - { - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - if (obj->is_const()) - return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******** const reference converter ********* - - struct const_ref_converter - { - typedef const_ref_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - const_ref_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, T const& ref) - { - if (luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, mpl::false_()); - } - - template - T const& apply(lua_State*, by_const_reference, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_const_reference, int index) - { - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match - - std::pair s = obj->get_instance(registered_class::id); - if (s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_const_reference, int) - { - } - }; - - // ****** enum converter ******** - - struct enum_converter - { - typedef enum_converter type; - typedef mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - void apply(lua_State* L, int val) - { - lua_pushnumber(L, val); - } - - template - T apply(lua_State* L, by_value, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_value, int index) - { - if (lua_isnumber(L, index)) return 0; else return -1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if (lua_isnumber(L, index)) return 0; else return -1; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct value_wrapper_converter - { - typedef value_wrapper_converter type; - typedef mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - return T(from_stack(L, index)); - } - - template - T apply(lua_State* L, by_value, int index) - { - return apply(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - return value_wrapper_traits::check(L, index) - ? (std::numeric_limits::max)() / LUABIND_MAX_ARITY - : -1; - } - - template - static int match(lua_State* L, by_value, int index) - { - return match(L, by_const_reference(), index); - } - - void converter_postcall(...) {} - - template - void apply(lua_State* interpreter, T const& value_wrapper) - { - value_wrapper_traits::unwrap(interpreter, value_wrapper); - } - }; - - template - struct default_converter_generator - : mpl::eval_if< - is_value_wrapper_arg - , value_wrapper_converter - , mpl::eval_if< - boost::is_enum::type> - , enum_converter - , mpl::eval_if< - is_nonconst_pointer - , pointer_converter - , mpl::eval_if< - is_const_pointer - , const_pointer_converter - , mpl::eval_if< - is_nonconst_reference - , ref_converter - , mpl::eval_if< - is_const_reference - , const_ref_converter - , value_converter - > - > - > - > - > - > - {}; - -} // namespace detail - -// *********** default_policy ***************** - -template -struct default_converter - : detail::default_converter_generator::type -{}; - -template > -struct native_converter_base -{ - typedef boost::mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - void converter_postcall(lua_State*, U const&, int) - {} - - int match(lua_State* L, detail::by_value, int index) - { - return derived().compute_score(L, index); - } - - int match(lua_State* L, detail::by_value, int index) - { - return derived().compute_score(L, index); - } - - int match(lua_State* L, detail::by_const_reference, int index) - { - return derived().compute_score(L, index); - } - - T apply(lua_State* L, detail::by_value, int index) - { - return derived().from(L, index); - } - - T apply(lua_State* L, detail::by_value, int index) - { - return derived().from(L, index); - } - - T apply(lua_State* L, detail::by_const_reference, int index) - { - return derived().from(L, index); - } - - void apply(lua_State* L, T const& value) - { - derived().to(L, value); - } - - Derived& derived() - { - return static_cast(*this); - } -}; - -template -lua_Integer as_lua_integer(T v) -{ - return static_cast(v); -} - -template -lua_Number as_lua_number(T v) -{ - return static_cast(v); -} - -# define LUABIND_NUMBER_CONVERTER(type, kind) \ - template <> \ -struct default_converter \ - : native_converter_base \ -{ \ - int compute_score(lua_State* L, int index) \ - { \ - return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \ - }; \ - \ - type from(lua_State* L, int index) \ - { \ - return static_cast(BOOST_PP_CAT(lua_to, kind)(L, index)); \ - } \ - \ - void to(lua_State* L, type const& value) \ - { \ - BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \ - } \ -}; \ -\ -template <> \ -struct default_converter \ - : default_converter \ -{}; \ -\ -template <> \ -struct default_converter \ - : default_converter \ -{}; - -LUABIND_NUMBER_CONVERTER(char, integer) -LUABIND_NUMBER_CONVERTER(signed char, integer) -LUABIND_NUMBER_CONVERTER(unsigned char, integer) -LUABIND_NUMBER_CONVERTER(signed short, integer) -LUABIND_NUMBER_CONVERTER(unsigned short, integer) -LUABIND_NUMBER_CONVERTER(signed int, integer) - -LUABIND_NUMBER_CONVERTER(unsigned int, number) -LUABIND_NUMBER_CONVERTER(unsigned long, number) - -LUABIND_NUMBER_CONVERTER(signed long, integer) -LUABIND_NUMBER_CONVERTER(float, number) -LUABIND_NUMBER_CONVERTER(double, number) -LUABIND_NUMBER_CONVERTER(long double, number) - -# undef LUABIND_NUMBER_CONVERTER - -template <> -struct default_converter - : native_converter_base -{ - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1; - } - - bool from(lua_State* L, int index) - { - return lua_toboolean(L, index) == 1; - } - - void to(lua_State* L, bool value) - { - lua_pushboolean(L, value); - } -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : native_converter_base -{ - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TSTRING ? 0 : -1; - } - - std::string from(lua_State* L, int index) - { - return std::string(lua_tostring(L, index), lua_strlen(L, index)); - } - - void to(lua_State* L, std::string const& value) - { - lua_pushlstring(L, value.data(), value.size()); - } -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter -{ - typedef boost::mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - static int match(lua_State* L, U, int index) - { - int type = lua_type(L, index); - return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1; - } - - template - char const* apply(lua_State* L, U, int index) - { - return lua_tostring(L, index); - } - - void apply(lua_State* L, char const* str) - { - lua_pushstring(L, str); - } - - template - void converter_postcall(lua_State*, U, int) - {} -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template -struct default_converter - : default_converter -{}; - -template -struct default_converter - : default_converter -{}; - -template <> -struct default_converter -{ - int const consumed_args(...) - { - return 0; - } - - template - lua_State* apply(lua_State* L, U, int) - { - return L; - } - - template - static int match(lua_State*, U, int) - { - return 0; - } - - template - void converter_postcall(lua_State*, U, int) {} -}; - -namespace detail -{ - - struct default_policy : converter_policy_tag - { - BOOST_STATIC_CONSTANT(bool, has_arg = true); - - template - static void precall(lua_State*, T, int) {} - - template - struct apply - { - typedef default_converter type; - }; - }; - - template - struct is_primitive - : default_converter::is_native - {}; - -// ============== new policy system ================= - - template struct find_conversion_policy; - - template - struct find_conversion_impl - { - template - struct apply - { - typedef typename find_conversion_policy::type type; - }; - }; - - template<> - struct find_conversion_impl - { - template - struct apply - { - typedef typename Policies::head head; - typedef typename Policies::tail tail; - - BOOST_STATIC_CONSTANT(bool, found = (N == head::index)); - - typedef typename - boost::mpl::if_c::type - >::type type; - }; - }; - - template - struct find_conversion_impl2 - { - template - struct apply - : find_conversion_impl< - boost::is_base_and_derived::value - >::template apply - { - }; - }; - - template<> - struct find_conversion_impl2 - { - template - struct apply - { - typedef default_policy type; - }; - }; - - template - struct find_conversion_policy : find_conversion_impl2::template apply - { - }; - - template - struct policy_list_postcall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, const index_map& i) - { - head::postcall(L, i); - policy_list_postcall::apply(L, i); - } - }; - - template<> - struct policy_list_postcall - { - static void apply(lua_State*, const index_map&) {} - }; - -// ================================================== - -// ************** precall and postcall on policy_cons ********************* - - - template - struct policy_precall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, int index) - { - head::precall(L, index); - policy_precall::apply(L, index); - } - }; - - template<> - struct policy_precall - { - static void apply(lua_State*, int) {} - }; - - template - struct policy_postcall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, int index) - { - head::postcall(L, index); - policy_postcall::apply(L, index); - } - }; - - template<> - struct policy_postcall - { - static void apply(lua_State*, int) {} - }; - -}} // namespace luabind::detail - - -namespace luabind { namespace -{ -#if defined(__GNUC__) && ( \ - (BOOST_VERSION < 103500) \ - || (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \ - || (__GNUC__ * 100 + __GNUC_MINOR__ < 400)) - static inline boost::arg<0> return_value() - { - return boost::arg<0>(); - } - - static inline boost::arg<0> result() - { - return boost::arg<0>(); - } -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg(*)() -#elif defined(BOOST_MSVC) || defined(__MWERKS__) \ - || (BOOST_VERSION >= 103900 && defined(__GNUC__) \ - && (__GNUC__ * 100 + __GNUC_MINOR__ == 400)) - static boost::arg<0> return_value; - static boost::arg<0> result; -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg -#else - boost::arg<0> return_value; - boost::arg<0> result; -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg -#endif -}} - -#endif // LUABIND_POLICY_HPP_INCLUDED - diff --git a/luabind/luabind/detail/primitives.hpp b/luabind/luabind/detail/primitives.hpp deleted file mode 100644 index 04ce17b87..000000000 --- a/luabind/luabind/detail/primitives.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_PRIMITIVES_HPP_INCLUDED -#define LUABIND_PRIMITIVES_HPP_INCLUDED - -#include -#include - -#include -#include - -namespace luabind { namespace detail -{ - template - struct identity - { - typedef T type; - }; - - template - struct type_ {}; - - struct null_type {}; - -/* typedef char yes_t; - typedef double no_t;*/ - - struct lua_to_cpp {}; - struct cpp_to_lua {}; - - template struct by_value {}; - template struct by_reference {}; - template struct by_const_reference {}; - template struct by_pointer {}; - template struct by_const_pointer {}; - - struct converter_policy_tag {}; - - struct ltstr - { - bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } - }; - - template - struct aligned - { - char storage[N]; - }; - - // returns the offset added to a Derived* when cast to a Base* - // TODO: return ptrdiff - template - int ptr_offset(type_, type_) - { - aligned obj; - Derived* ptr = reinterpret_cast(&obj); - - return int(static_cast(static_cast(static_cast(ptr))) - - static_cast(static_cast(ptr))); - } - -}} - -#endif // LUABIND_PRIMITIVES_HPP_INCLUDED diff --git a/luabind/luabind/detail/property.hpp b/luabind/luabind/detail/property.hpp deleted file mode 100644 index 2c30ce000..000000000 --- a/luabind/luabind/detail/property.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_PROPERTY_081020_HPP -# define LUABIND_PROPERTY_081020_HPP - -namespace luabind { namespace detail { - -template -struct access_member_ptr -{ - access_member_ptr(T Class::* mem_ptr) - : mem_ptr(mem_ptr) - {} - - Result operator()(Class const& x) const - { - return const_cast(x).*mem_ptr; - } - - void operator()(Class& x, T const& value) const - { - x.*mem_ptr = value; - } - - T Class::* mem_ptr; -}; - -}} // namespace luabind::detail - -#endif // LUABIND_PROPERTY_081020_HPP - diff --git a/luabind/luabind/detail/ref.hpp b/luabind/luabind/detail/ref.hpp deleted file mode 100644 index 3edbfebfb..000000000 --- a/luabind/luabind/detail/ref.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_REF_HPP_INCLUDED -#define LUABIND_REF_HPP_INCLUDED - -#include -#include - -#include -#include - -namespace luabind -{ - -namespace detail -{ - - struct lua_reference - { - lua_reference(lua_State* L_ = 0) - : L(L_) - , m_ref(LUA_NOREF) - {} - lua_reference(lua_reference const& r) - : L(r.L) - , m_ref(LUA_NOREF) - { - if (!r.is_valid()) return; - r.get(L); - set(L); - } - ~lua_reference() { reset(); } - - lua_State* state() const { return L; } - - void operator=(lua_reference const& r) - { - // TODO: self assignment problems - reset(); - if (!r.is_valid()) return; - r.get(r.state()); - set(r.state()); - } - - bool is_valid() const - { return m_ref != LUA_NOREF; } - - void set(lua_State* L_) - { - reset(); - L = L_; - m_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - - void replace(lua_State* L_) - { - lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); - } - - // L may not be the same pointer as - // was used when creating this reference - // since it may be a thread that shares - // the same globals table. - void get(lua_State* L_) const - { - assert(m_ref != LUA_NOREF); - assert(L_); - lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); - } - - void reset() - { - if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); - m_ref = LUA_NOREF; - } - - void swap(lua_reference& r) - { - assert(r.L == L); - std::swap(r.m_ref, m_ref); - } - - private: - lua_State* L; - int m_ref; - }; - -}} - -#endif // LUABIND_REF_HPP_INCLUDED - diff --git a/luabind/luabind/detail/signature_match.hpp b/luabind/luabind/detail/signature_match.hpp deleted file mode 100644 index d76ed6627..000000000 --- a/luabind/luabind/detail/signature_match.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_SIGNATURE_MATCH_HPP_INCLUDED -#define LUABIND_SIGNATURE_MATCH_HPP_INCLUDED - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace luabind -{ - - namespace adl - { - class argument; - } - - template - struct constructor - { - typedef BOOST_PP_CAT( - boost::mpl::vector, BOOST_PP_INC(BOOST_PP_INC(LUABIND_MAX_ARITY)))< - void, argument const&, BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A) - > signature0; - - typedef typename boost::mpl::remove< - signature0, detail::null_type>::type signature; - }; - -} - -#endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED - diff --git a/luabind/luabind/detail/stack_utils.hpp b/luabind/luabind/detail/stack_utils.hpp deleted file mode 100644 index 15f3a7fce..000000000 --- a/luabind/luabind/detail/stack_utils.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_STACK_UTILS_HPP_INCLUDED -#define LUABIND_STACK_UTILS_HPP_INCLUDED - -#include - -namespace luabind { namespace detail -{ - - struct stack_pop - { - stack_pop(lua_State* L, int n) - : m_state(L) - , m_n(n) - { - } - - ~stack_pop() - { - lua_pop(m_state, m_n); - } - - private: - - lua_State* m_state; - int m_n; - }; -}} - -#endif // LUABIND_STACK_UTILS_HPP_INCLUDED - diff --git a/luabind/luabind/detail/typetraits.hpp b/luabind/luabind/detail/typetraits.hpp deleted file mode 100644 index f27934e98..000000000 --- a/luabind/luabind/detail/typetraits.hpp +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_TYPETRAITS_HPP_INCLUDED -#define LUABIND_TYPETRAITS_HPP_INCLUDED - -#include -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct is_const_type - { - typedef typename boost::mpl::if_ - , yes_t - , no_t - >::type type; - }; - - template - struct is_const_reference_helper - { - template - struct apply - { - enum - { - value = false - }; - }; - }; - - template - typename is_const_type::type is_const_reference_tester(T&); - no_t is_const_reference_tester(...); - - template<> - struct is_const_reference_helper - { - template - struct apply - { - static T getT(); - - enum - { - value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t) - }; - }; - }; - - template - struct is_const_reference - : is_const_reference_helper::value>::template apply - { - typedef boost::mpl::bool_ type; - }; - -#else - - template - struct is_const_reference - { - enum { value = false }; - typedef boost::mpl::bool_ type; - }; - - template - struct is_const_reference - { - enum { value = true }; - typedef boost::mpl::bool_ type; - }; - -#endif - - - template - struct is_nonconst_reference - { - enum - { - value = boost::is_reference::value && !is_const_reference::value - }; - typedef boost::mpl::bool_ type; - }; - - template - yes_t is_const_pointer_helper(void(*)(const A*)); - no_t is_const_pointer_helper(...); - - template - struct is_const_pointer - { - enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) }; - typedef boost::mpl::bool_ type; - }; - - template - yes_t is_nonconst_pointer_helper(void(*)(A*)); - no_t is_nonconst_pointer_helper(...); - - template - struct is_nonconst_pointer - { - enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer::value }; - typedef boost::mpl::bool_ type; - }; -/* - template - struct is_constructable_from_helper - { - static yes_t check(const T&); - static no_t check(...); - }; - - template - struct is_constructable_from - { - static From getFrom(); - - enum - { - value = sizeof(is_constructable_from_helper::check(getFrom())) == sizeof(yes_t) - }; - }; - - template - struct is_const_member_function_helper - { - static no_t test(...); - template - static yes_t test(R(T::*)() const); - template - static yes_t test(R(T::*)(A1) const); - template - static yes_t test(R(T::*)(A1,A2) const); - template - static yes_t test(R(T::*)(A1,A2,A3) const); - }; - - template - struct is_const_member_function - { - static U getU(); - - enum - { - value = sizeof(is_const_member_function_helper::test(getU())) == sizeof(yes_t) - }; - }; -*/ - - template - struct max_c - { - enum { value = (v1>v2)?v1:v2 }; - }; - -}} - -#endif // LUABIND_TYPETRAITS_HPP_INCLUDED - diff --git a/luabind/luabind/detail/yes_no.hpp b/luabind/luabind/detail/yes_no.hpp deleted file mode 100644 index 931847c60..000000000 --- a/luabind/luabind/detail/yes_no.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin - -// 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. - -#ifndef YES_NO_040211_HPP -#define YES_NO_040211_HPP - -namespace luabind { namespace detail { - - typedef char(&yes_t)[1]; - typedef char(&no_t)[2]; - -}} // namespace luabind::detail - -#endif // YES_NO_040211_HPP - diff --git a/luabind/luabind/discard_result_policy.hpp b/luabind/luabind/discard_result_policy.hpp deleted file mode 100644 index 149a7b1bc..000000000 --- a/luabind/luabind/discard_result_policy.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED -#define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED - -#include -#include - -namespace luabind { namespace detail -{ - struct discard_converter - { - template - void apply(lua_State*, T) {} - }; - - struct discard_result_policy : conversion_policy<0> - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct can_only_convert_from_cpp_to_lua {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , discard_converter - , can_only_convert_from_cpp_to_lua - >::type type; - }; - }; - -}} - -namespace luabind -{ - detail::policy_cons< - detail::discard_result_policy, detail::null_type> const discard_result = {}; - - namespace detail - { - inline void ignore_unused_discard_result() - { - (void)discard_result; - } - } -} - -#endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED - diff --git a/luabind/luabind/error.hpp b/luabind/luabind/error.hpp deleted file mode 100644 index b282a411a..000000000 --- a/luabind/luabind/error.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_ERROR_HPP_INCLUDED -#define LUABIND_ERROR_HPP_INCLUDED - -#include -#include -#include -#include - -struct lua_State; - -namespace luabind -{ - -#ifndef LUABIND_NO_EXCEPTIONS - - // this exception usually means that the lua function you called - // from C++ failed with an error code. You will have to - // read the error code from the top of the lua stack - // the reason why this exception class doesn't contain - // the message itself is that std::string's copy constructor - // may throw, if the copy constructor of an exception that is - // being thrown throws another exception, terminate will be called - // and the entire application is killed. - class LUABIND_API error : public std::exception - { - public: - explicit error(lua_State* L): m_L(L) {} - lua_State* state() const throw() { return m_L; } - virtual const char* what() const throw() - { - return "lua runtime error"; - } - private: - lua_State* m_L; - }; - - // if an object_cast<>() fails, this is thrown - // it is also thrown if the return value of - // a lua function cannot be converted - class LUABIND_API cast_failed : public std::exception - { - public: - cast_failed(lua_State* L, type_id const& i): m_L(L), m_info(i) {} - lua_State* state() const throw() { return m_L; } - type_id info() const throw() { return m_info; } - virtual const char* what() const throw() { return "unable to make cast"; } - private: - lua_State* m_L; - type_id m_info; - }; - -#else - - typedef void(*error_callback_fun)(lua_State*); - typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); - - LUABIND_API void set_error_callback(error_callback_fun e); - LUABIND_API void set_cast_failed_callback(cast_failed_callback_fun c); - LUABIND_API error_callback_fun get_error_callback(); - LUABIND_API cast_failed_callback_fun get_cast_failed_callback(); - -#endif - - typedef int(*pcall_callback_fun)(lua_State*); - LUABIND_API void set_pcall_callback(pcall_callback_fun e); - LUABIND_API pcall_callback_fun get_pcall_callback(); - -} - -#endif // LUABIND_ERROR_HPP_INCLUDED - diff --git a/luabind/luabind/exception_handler.hpp b/luabind/luabind/exception_handler.hpp deleted file mode 100644 index 0048563af..000000000 --- a/luabind/luabind/exception_handler.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright Daniel Wallin 2005. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_EXCEPTION_HANDLER_050601_HPP -# define LUABIND_EXCEPTION_HANDLER_050601_HPP - -# include -# include -# include -# include - -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -# include -# include -# endif - -namespace luabind { - -# ifndef LUABIND_NO_EXCEPTIONS - -namespace detail -{ - - struct LUABIND_API exception_handler_base - { - exception_handler_base() - : next(0) - {} - - virtual ~exception_handler_base() {} - virtual void handle(lua_State*) const = 0; - - void try_next(lua_State*) const; - - exception_handler_base* next; - }; - - namespace mpl = boost::mpl; - - template - struct exception_handler : exception_handler_base - { -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - typedef typename mpl::if_< - boost::is_pointer, E, E const& - >::type argument; -# else - typedef E const& argument; -# endif - - exception_handler(Handler handler) - : handler(handler) - {} - - void handle(lua_State* L) const - { - try - { - try_next(L); - } - catch (argument e) - { - handler(L, e); - } - } - - Handler handler; - }; - - LUABIND_API void handle_exception_aux(lua_State* L); - LUABIND_API void register_exception_handler(exception_handler_base*); - -} // namespace detail - -# endif - -template -void register_exception_handler(Handler handler, boost::type* = 0) -{ -# ifndef LUABIND_NO_EXCEPTIONS - detail::register_exception_handler( - new detail::exception_handler(handler) - ); -# endif -} - -template -boost::optional handle_exceptions(lua_State* L, F fn, boost::type* = 0) -{ -# ifndef LUABIND_NO_EXCEPTIONS - try - { - return fn(); - } - catch (...) - { - detail::handle_exception_aux(L); - } - - return boost::optional(); -# else - return fn(); -# endif -} - -} // namespace luabind - -#endif // LUABIND_EXCEPTION_HANDLER_050601_HPP - diff --git a/luabind/luabind/from_stack.hpp b/luabind/luabind/from_stack.hpp deleted file mode 100644 index 56bc268d8..000000000 --- a/luabind/luabind/from_stack.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_FROM_STACK_050715_HPP -#define LUABIND_FROM_STACK_050715_HPP - -namespace luabind { - -struct from_stack -{ - from_stack(lua_State* interpreter, int index) - : interpreter(interpreter) - , index(index) - {} - - lua_State* interpreter; - int index; -}; - -} // namespace luabind - -#endif // LUABIND_FROM_STACK_050715_HPP - diff --git a/luabind/luabind/function.hpp b/luabind/luabind/function.hpp deleted file mode 100644 index e156fbfcb..000000000 --- a/luabind/luabind/function.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_FUNCTION2_081014_HPP -# define LUABIND_FUNCTION2_081014_HPP - -# include -# include -# include - -namespace luabind { - -namespace detail -{ - - template - struct function_registration : registration - { - function_registration(char const* name, F f, Policies const& policies) - : name(name) - , f(f) - , policies(policies) - {} - - void register_(lua_State* L) const - { - object fn = make_function(L, f, deduce_signature(f), policies); - - add_overload( - object(from_stack(L, -1)) - , name - , fn - ); - } - - char const* name; - F f; - Policies policies; - }; - - LUABIND_API bool is_luabind_function(lua_State* L, int index); - -} // namespace detail - -template -scope def(char const* name, F f, Policies const& policies) -{ - return scope(std::auto_ptr( - new detail::function_registration(name, f, policies))); -} - -template -scope def(char const* name, F f) -{ - return def(name, f, detail::null_type()); -} - -} // namespace luabind - -#endif // LUABIND_FUNCTION2_081014_HPP - diff --git a/luabind/luabind/get_main_thread.hpp b/luabind/luabind/get_main_thread.hpp deleted file mode 100644 index f94d6e4bc..000000000 --- a/luabind/luabind/get_main_thread.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright Daniel Wallin 2009. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_GET_MAIN_THREAD_090321_HPP -# define LUABIND_GET_MAIN_THREAD_090321_HPP - -# include - -namespace luabind { - -LUABIND_API lua_State* get_main_thread(lua_State* L); - -} // namespace luabind - -#endif // LUABIND_GET_MAIN_THREAD_090321_HPP diff --git a/luabind/luabind/get_pointer.hpp b/luabind/luabind/get_pointer.hpp deleted file mode 100644 index b9aae48a7..000000000 --- a/luabind/luabind/get_pointer.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin - -// 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. - -#ifndef LUABIND_GET_POINTER_051023_HPP -# define LUABIND_GET_POINTER_051023_HPP - -// -// We need these overloads in the luabind namespace. -// - -# include - -namespace luabind { - -using boost::get_pointer; - -} // namespace luabind - -#endif // LUABIND_GET_POINTER_051023_HPP - diff --git a/luabind/luabind/handle.hpp b/luabind/luabind/handle.hpp deleted file mode 100644 index 14adacbae..000000000 --- a/luabind/luabind/handle.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_HANDLE_050420_HPP -#define LUABIND_HANDLE_050420_HPP - -#include -#include - -namespace luabind { - -// A reference to a Lua value. Represents an entry in the -// registry table. -class handle -{ -public: - handle(); - handle(lua_State* interpreter, int stack_index); - handle(lua_State* main, lua_State* interpreter, int stack_index); - handle(handle const& other); - ~handle(); - - handle& operator=(handle const& other); - void swap(handle& other); - - void push(lua_State* interpreter) const; - - lua_State* interpreter() const; - - void replace(lua_State* interpreter, int stack_index); - -private: - lua_State* m_interpreter; - int m_index; -}; - -inline handle::handle() - : m_interpreter(0) - , m_index(LUA_NOREF) -{} - -inline handle::handle(handle const& other) - : m_interpreter(other.m_interpreter) - , m_index(LUA_NOREF) -{ - if (m_interpreter == 0) return; - lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); - m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); -} - -inline handle::handle(lua_State* interpreter, int stack_index) - : m_interpreter(interpreter) - , m_index(LUA_NOREF) -{ - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); -} - -inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index) - : m_interpreter(main) - , m_index(LUA_NOREF) -{ - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); -} - -inline handle::~handle() -{ - if (m_interpreter && m_index != LUA_NOREF) - luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index); -} - -inline handle& handle::operator=(handle const& other) -{ - handle(other).swap(*this); - return *this; -} - -inline void handle::swap(handle& other) -{ - std::swap(m_interpreter, other.m_interpreter); - std::swap(m_index, other.m_index); -} - -inline void handle::push(lua_State* interpreter) const -{ - lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); -} - -inline lua_State* handle::interpreter() const -{ - return m_interpreter; -} - -inline void handle::replace(lua_State* interpreter, int stack_index) -{ - lua_pushvalue(interpreter, stack_index); - lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); -} - -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - static lua_State* interpreter(handle const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, handle const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } -}; - -} // namespace luabind - -#endif // LUABIND_HANDLE_050420_HPP - diff --git a/luabind/luabind/iterator_policy.hpp b/luabind/luabind/iterator_policy.hpp deleted file mode 100644 index b1f827fe3..000000000 --- a/luabind/luabind/iterator_policy.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright Daniel Wallin 2007. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_ITERATOR_POLICY__071111_HPP -# define LUABIND_ITERATOR_POLICY__071111_HPP - -# include -# include -# include - -namespace luabind { namespace detail { - -template -struct iterator -{ - static int next(lua_State* L) - { - iterator* self = static_cast( - lua_touserdata(L, lua_upvalueindex(1))); - - if (self->first != self->last) - { - convert_to_lua(L, *self->first); - ++self->first; - } - else - { - lua_pushnil(L); - } - - return 1; - } - - static int destroy(lua_State* L) - { - iterator* self = static_cast(lua_touserdata(L, 1)); - self->~iterator(); - return 0; - } - - iterator(Iterator first, Iterator last) - : first(first) - , last(last) - {} - - Iterator first; - Iterator last; -}; - -template -int make_range(lua_State* L, Iterator first, Iterator last) -{ - void* storage = lua_newuserdata(L, sizeof(iterator)); - lua_newtable(L); - lua_pushcclosure(L, iterator::destroy, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - lua_pushcclosure(L, iterator::next, 1); - new (storage) iterator(first, last); - return 1; -} - -template -int make_range(lua_State* L, Container& container) -{ - return make_range(L, container.begin(), container.end()); -} - -struct iterator_converter -{ - typedef iterator_converter type; - - template - void apply(lua_State* L, Container& container) - { - make_range(L, container); - } - - template - void apply(lua_State* L, Container const& container) - { - make_range(L, container); - } -}; - -struct iterator_policy : conversion_policy<0> -{ - static void precall(lua_State*, index_map const&) - {} - - static void postcall(lua_State*, index_map const&) - {} - - template - struct apply - { - typedef iterator_converter type; - }; -}; - -}} // namespace luabind::detail - -namespace luabind { namespace { - -LUABIND_ANONYMOUS_FIX detail::policy_cons< - detail::iterator_policy, detail::null_type> return_stl_iterator; - -}} // namespace luabind::unnamed - -#endif // LUABIND_ITERATOR_POLICY__071111_HPP - diff --git a/luabind/luabind/lua502.hpp b/luabind/luabind/lua502.hpp deleted file mode 100644 index 5006128ec..000000000 --- a/luabind/luabind/lua502.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUA_502_HPP -#define LUA_502_HPP - -#if LUA_VERSION_NUM >= 502 - -inline LUA_API int lua_equal(lua_State *L, int idx1, int idx2) -{ - return lua_compare(L, idx1, idx2, LUA_OPEQ); -} - -inline LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2) -{ - return lua_compare(L, idx1, idx2, LUA_OPLT); -} - -#undef lua_strlen -#define lua_strlen lua_rawlen - -#undef lua_getfenv -#define lua_getfenv lua_getuservalue - -#undef lua_setfenv -#define lua_setfenv lua_setuservalue - -#undef lua_open -#define lua_open luaL_newstate - -#else // LUA_VERSION_NUM >= 502 - -#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) - -#endif // LUA_VERSION_NUM >= 502 - -#endif \ No newline at end of file diff --git a/luabind/luabind/lua_include.hpp b/luabind/luabind/lua_include.hpp deleted file mode 100644 index 7327b533e..000000000 --- a/luabind/luabind/lua_include.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUA_INCLUDE_HPP_INCLUDED -#define LUA_INCLUDE_HPP_INCLUDED - -#ifndef LUABIND_CPLUSPLUS_LUA -extern "C" -{ -#endif - - #include "lua.h" - #include "lauxlib.h" - -#ifndef LUABIND_CPLUSPLUS_LUA -} -#endif - -#endif - diff --git a/luabind/luabind/luabind.hpp b/luabind/luabind/luabind.hpp deleted file mode 100644 index 82298484c..000000000 --- a/luabind/luabind/luabind.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_BIND_HPP_INCLUDED -#define LUABIND_BIND_HPP_INCLUDED - -#include -#include -#include -#include - -#endif // LUABIND_BIND_HPP_INCLUDED diff --git a/luabind/luabind/make_function.hpp b/luabind/luabind/make_function.hpp deleted file mode 100644 index a1ac8716b..000000000 --- a/luabind/luabind/make_function.hpp +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_MAKE_FUNCTION_081014_HPP -# define LUABIND_MAKE_FUNCTION_081014_HPP - -# include -# include -# include -# include -# include -# include - -namespace luabind { - -namespace detail -{ -# ifndef LUABIND_NO_EXCEPTIONS - LUABIND_API void handle_exception_aux(lua_State* L); -# endif - -// MSVC complains about member being sensitive to alignment (C4121) -// when F is a pointer to member of a class with virtual bases. -# ifdef BOOST_MSVC -# pragma pack(push) -# pragma pack(16) -# endif - - template - struct function_object_impl : function_object - { - function_object_impl(F f, Policies const& policies) - : function_object(&entry_point) - , f(f) - , policies(policies) - {} - - int call(lua_State* L, invoke_context& ctx) const - { - return invoke(L, *this, ctx, f, Signature(), policies); - } - - void format_signature(lua_State* L, char const* function) const - { - detail::format_signature(L, function, Signature()); - } - - static int entry_point(lua_State* L) - { - function_object_impl const* impl = - *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1)); - - invoke_context ctx; - - int results = 0; - -# ifndef LUABIND_NO_EXCEPTIONS - bool exception_caught = false; - - try - { - results = invoke( - L, *impl, ctx, impl->f, Signature(), impl->policies); - } - catch (...) - { - exception_caught = true; - handle_exception_aux(L); - } - - if (exception_caught) - lua_error(L); -# else - results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies); -# endif - - if (!ctx) - { - ctx.format_error(L, impl); - lua_error(L); - } - - return results; - } - - F f; - Policies policies; - }; - -# ifdef BOOST_MSVC -# pragma pack(pop) -# endif - - LUABIND_API object make_function_aux( - lua_State* L, function_object* impl - ); - - LUABIND_API void add_overload(object const&, char const*, object const&); - -} // namespace detail - -template -object make_function(lua_State* L, F f, Signature, Policies) -{ - return detail::make_function_aux( - L - , new detail::function_object_impl( - f, Policies() - ) - ); -} - -template -object make_function(lua_State* L, F f) -{ - return make_function(L, detail::deduce_signature(f), detail::null_type()); -} - -} // namespace luabind - -#endif // LUABIND_MAKE_FUNCTION_081014_HPP - diff --git a/luabind/luabind/nil.hpp b/luabind/luabind/nil.hpp deleted file mode 100644 index 5f9ba4db1..000000000 --- a/luabind/luabind/nil.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_NIL_HPP -#define LUABIND_NIL_HPP - -#include - -namespace luabind -{ - namespace detail - { - struct nil_type {}; - } - - // defined in class.cpp - extern LUABIND_API detail::nil_type nil; -} - -#endif - diff --git a/luabind/luabind/object.hpp b/luabind/luabind/object.hpp deleted file mode 100644 index 0feb7bd48..000000000 --- a/luabind/luabind/object.hpp +++ /dev/null @@ -1,1412 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_OBJECT_050419_HPP -#define LUABIND_OBJECT_050419_HPP - -#include // detail::push() -#include // detail::push() -#include // value_wrapper_traits specializations -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include // REFACTOR -#include - -#include // iterator - -#include -#include - -namespace luabind { - -namespace detail -{ - namespace mpl = boost::mpl; - - template - void push_aux(lua_State* interpreter, T& value, ConverterGenerator*) - { - typedef typename boost::mpl::if_< - boost::is_reference_wrapper - , BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& - , T - >::type unwrapped_type; - - typename mpl::apply_wrap2< - ConverterGenerator,unwrapped_type,cpp_to_lua - >::type cv; - - cv.apply( - interpreter - , boost::implicit_cast< - BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& - >(value) - ); - } - - template - void push(lua_State* interpreter, T& value, Policies const&) - { - typedef typename find_conversion_policy< - 0 - , Policies - >::type converter_policy; - - push_aux(interpreter, value, (converter_policy*)0); - } - - template - void push(lua_State* interpreter, T& value) - { - push(interpreter, value, null_type()); - } - -} // namespace detail - -namespace adl -{ - namespace mpl = boost::mpl; - - template - class object_interface; - - namespace is_object_interface_aux - { - typedef char (&yes)[1]; - typedef char (&no)[2]; - - template - yes check(object_interface*); - no check(void*); - - template - struct impl - { - BOOST_STATIC_CONSTANT(bool, value = - sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes) - ); - - typedef mpl::bool_ type; - }; - - } // namespace detail - - template - struct is_object_interface - : is_object_interface_aux::impl::type - {}; - - template - struct enable_binary -# ifndef BOOST_NO_SFINAE - : boost::enable_if< - mpl::or_< - is_object_interface - , is_object_interface - > - , R - > - {}; -# else - { - typedef R type; - }; -# endif - - template - int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs - , boost::mpl::true_, boost::mpl::true_) - { - L = value_wrapper_traits::interpreter(lhs); - lua_State* L2 = value_wrapper_traits::interpreter(rhs); - - // you are comparing objects with different interpreters - // that's not allowed. - assert(L == L2 || L == 0 || L2 == 0); - - // if the two objects we compare have different interpreters - // then they - - if (L != L2) return -1; - if (L == 0) return 1; - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const& - , boost::mpl::true_, boost::mpl::false_) - { - L = value_wrapper_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_) - { - L = value_wrapper_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const& y) - { - return binary_interpreter( - L - , x - , y - , is_value_wrapper() - , is_value_wrapper() - ); - } - -#define LUABIND_BINARY_OP_DEF(op, fn) \ - template \ - typename enable_binary::type \ - operator op(LHS const& lhs, RHS const& rhs) \ - { \ - lua_State* L = 0; \ - switch (binary_interpreter(L, lhs, rhs)) \ - { \ - case 1: \ - return true; \ - case -1: \ - return false; \ - } \ -\ - assert(L); \ -\ - detail::stack_pop pop1(L, 1); \ - detail::push(L, lhs); \ - detail::stack_pop pop2(L, 1); \ - detail::push(L, rhs); \ -\ - return fn(L, -1, -2) != 0; \ - } - -LUABIND_BINARY_OP_DEF(==, lua_equal) -LUABIND_BINARY_OP_DEF(<, lua_lessthan) - - template - std::ostream& operator<<(std::ostream& os - , object_interface const& v) - { - using namespace luabind; - lua_State* interpreter = value_wrapper_traits::interpreter( - static_cast(v)); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter - , static_cast(v)); - char const* p = lua_tostring(interpreter, -1); - std::size_t len = lua_strlen(interpreter, -1); - std::copy(p, p + len, std::ostream_iterator(os)); - return os; - } - -#undef LUABIND_BINARY_OP_DEF - - template - typename enable_binary::type - operator>(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs || lhs == rhs); - } - - template - typename enable_binary::type - operator<=(LHS const& lhs, RHS const& rhs) - { - return lhs < rhs || lhs == rhs; - } - - template - typename enable_binary::type - operator>=(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs); - } - - template - typename enable_binary::type - operator!=(LHS const& lhs, RHS const& rhs) - { - return !(lhs == rhs); - } - - template - struct call_proxy; - - template - class index_proxy; - - class object; - - template - class object_interface - { - struct safe_bool_type {}; - public: - ~object_interface() {} - - call_proxy > operator()(); - - template - call_proxy< - Derived - , boost::tuples::tuple - > operator()(A0 const& a0) - { - typedef boost::tuples::tuple arguments; - - return call_proxy( - derived() - , arguments(&a0) - ); - } - - template - call_proxy< - Derived - , boost::tuples::tuple - > operator()(A0 const& a0, A1 const& a1) - { - typedef boost::tuples::tuple arguments; - - return call_proxy( - derived() - , arguments(&a0, &a1) - ); - } - - // The rest of the overloads are PP-generated. - #define BOOST_PP_ITERATION_PARAMS_1 (3, \ - (3, LUABIND_MAX_ARITY, )) - #include BOOST_PP_ITERATE() - - operator safe_bool_type*() const - { - lua_State* L = value_wrapper_traits::interpreter(derived()); - - if (!L) - return 0; - - value_wrapper_traits::unwrap(L, derived()); - detail::stack_pop pop(L, 1); - - return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0; - } - - private: - Derived& derived() - { - return *static_cast(this); - } - - Derived const& derived() const - { - return *static_cast(this); - } - }; - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - struct iterator_proxy_tag; -#endif - - template - class iterator_proxy - : public object_interface > - { - public: -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - typedef iterator_proxy_tag value_wrapper_tag; -#endif - - iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) - : m_interpreter(interpreter) - , m_table_index(lua_gettop(interpreter) + 1) - , m_key_index(m_table_index + 1) - { - table.push(m_interpreter); - key.push(m_interpreter); - } - - iterator_proxy(iterator_proxy const& other) - : m_interpreter(other.m_interpreter) - , m_table_index(other.m_table_index) - , m_key_index(other.m_key_index) - { - other.m_interpreter = 0; - } - - ~iterator_proxy() - { - if (m_interpreter) - lua_pop(m_interpreter, 2); - } - - // this will set the value to nil - iterator_proxy & operator=(luabind::detail::nil_type) - { - lua_pushvalue(m_interpreter, m_key_index); - lua_pushnil(m_interpreter); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - iterator_proxy& operator=(T const& value) - { - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - index_proxy > operator[](Key const& key) - { - return index_proxy >( - *this, m_interpreter, key - ); - } - - // This is non-const to prevent conversion on lvalues. - operator object(); - - lua_State* interpreter() const - { - return m_interpreter; - } - - // TODO: Why is it non-const? - void push(lua_State* interpreter) - { - assert(interpreter == m_interpreter); - lua_pushvalue(m_interpreter, m_key_index); - AccessPolicy::get(m_interpreter, m_table_index); - } - - private: - mutable lua_State* m_interpreter; - int m_table_index; - int m_key_index; - }; - -} // namespace adl - -namespace detail -{ - struct basic_access - { - static void set(lua_State* interpreter, int table) - { - lua_settable(interpreter, table); - } - - static void get(lua_State* interpreter, int table) - { - lua_gettable(interpreter, table); - } - }; - - struct raw_access - { - static void set(lua_State* interpreter, int table) - { - lua_rawset(interpreter, table); - } - - static void get(lua_State* interpreter, int table) - { - lua_rawget(interpreter, table); - } - }; - - template - class basic_iterator - : public boost::iterator_facade< - basic_iterator - , adl::iterator_proxy - , boost::single_pass_traversal_tag - , adl::iterator_proxy - > - { - public: - basic_iterator() - : m_interpreter(0) - {} - - template - explicit basic_iterator(ValueWrapper const& value_wrapper) - : m_interpreter( - value_wrapper_traits::interpreter(value_wrapper) - ) - { - detail::stack_pop pop(m_interpreter, 1); - value_wrapper_traits::unwrap(m_interpreter, value_wrapper); - - lua_pushnil(m_interpreter); - if (lua_next(m_interpreter, -2) != 0) - { - detail::stack_pop pop(m_interpreter, 2); - handle(m_interpreter, -2).swap(m_key); - } - else - { - m_interpreter = 0; - return; - } - - handle(m_interpreter, -1).swap(m_table); - } - - adl::object key() const; - - private: - friend class boost::iterator_core_access; - - void increment() - { - m_table.push(m_interpreter); - m_key.push(m_interpreter); - - detail::stack_pop pop(m_interpreter, 1); - - if (lua_next(m_interpreter, -2) != 0) - { - m_key.replace(m_interpreter, -2); - lua_pop(m_interpreter, 2); - } - else - { - m_interpreter = 0; - handle().swap(m_table); - handle().swap(m_key); - } - } - - bool equal(basic_iterator const& other) const - { - if (m_interpreter == 0 && other.m_interpreter == 0) - return true; - - if (m_interpreter != other.m_interpreter) - return false; - - detail::stack_pop pop(m_interpreter, 2); - m_key.push(m_interpreter); - other.m_key.push(m_interpreter); - return lua_equal(m_interpreter, -2, -1) != 0; - } - - adl::iterator_proxy dereference() const - { - return adl::iterator_proxy(m_interpreter, m_table, m_key); - } - - lua_State* m_interpreter; - handle m_table; - handle m_key; - }; - -// Needed because of some strange ADL issues. -#if BOOST_VERSION < 105700 - -#define LUABIND_OPERATOR_ADL_WKND(op) \ - inline bool operator op( \ - basic_iterator const& x \ - , basic_iterator const& y) \ - { \ - return boost::operator op(x, y); \ - } \ - \ - inline bool operator op( \ - basic_iterator const& x \ - , basic_iterator const& y) \ - { \ - return boost::operator op(x, y); \ - } - - LUABIND_OPERATOR_ADL_WKND(==) - LUABIND_OPERATOR_ADL_WKND(!=) - -#undef LUABIND_OPERATOR_ADL_WKND -#endif - -} // namespace detail - -namespace adl -{ - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - struct index_proxy_tag; -#endif - - template - class index_proxy - : public object_interface > - { - public: -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - typedef index_proxy_tag value_wrapper_tag; -#endif - - typedef index_proxy this_type; - - template - index_proxy(Next const& next, lua_State* interpreter, Key const& key) - : m_interpreter(interpreter) - , m_key_index(lua_gettop(interpreter) + 1) - , m_next(next) - { - detail::push(m_interpreter, key); - } - - index_proxy(index_proxy const& other) - : m_interpreter(other.m_interpreter) - , m_key_index(other.m_key_index) - , m_next(other.m_next) - { - other.m_interpreter = 0; - } - - ~index_proxy() - { - if (m_interpreter) - lua_pop(m_interpreter, 1); - } - - // This is non-const to prevent conversion on lvalues. - operator object(); - - // this will set the value to nil - this_type& operator=(luabind::detail::nil_type) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - lua_pushnil(m_interpreter); - lua_settable(m_interpreter, -3); - return *this; - } - - template - this_type& operator=(T const& value) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - this_type& operator=(this_type const& value) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - template - index_proxy operator[](T const& key) - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* interpreter); - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - struct hidden_type {}; - -// this_type& operator=(index_proxy const&); - - mutable lua_State* m_interpreter; - int m_key_index; - - Next const& m_next; - }; - -} // namespace adl - -typedef detail::basic_iterator iterator; -typedef detail::basic_iterator raw_iterator; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(adl::index_proxy const& proxy) - { - return proxy.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) - { - const_cast&>(proxy).push(interpreter); - } -}; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(Proxy const& p) - { - return p.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, Proxy const& p) - { - // TODO: Why const_cast? - const_cast(p).push(interpreter); - } -}; - -namespace adl -{ - - // An object holds a reference to a Lua value residing - // in the registry. - class object : public object_interface - { - public: - object() - {} - - explicit object(handle const& other) - : m_handle(other) - {} - - explicit object(from_stack const& stack_reference) - : m_handle(stack_reference.interpreter, stack_reference.index) - { - } - - template - object(lua_State* interpreter, T const& value) - { - detail::push(interpreter, value); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - template - object(lua_State* interpreter, T const& value, Policies const&) - { - detail::push(interpreter, value, Policies()); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - void push(lua_State* interpreter) const; - lua_State* interpreter() const; - bool is_valid() const; - - template - index_proxy operator[](T const& key) const - { - return index_proxy( - *this, m_handle.interpreter(), key - ); - } - - void swap(object& other) - { - m_handle.swap(other.m_handle); - } - - private: - handle m_handle; - }; - - inline void object::push(lua_State* interpreter) const - { - m_handle.push(interpreter); - } - - inline lua_State* object::interpreter() const - { - return m_handle.interpreter(); - } - - inline bool object::is_valid() const - { - return m_handle.interpreter() != 0; - } - - class argument : public object_interface - { - public: - argument(from_stack const& stack_reference) - : m_interpreter(stack_reference.interpreter) - , m_index(stack_reference.index) - { - if (m_index < 0) - m_index = lua_gettop(m_interpreter) - m_index + 1; - } - - template - index_proxy operator[](T const& key) const - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* L) const - { - lua_pushvalue(L, m_index); - } - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - lua_State* m_interpreter; - int m_index; - }; - -} // namespace adl - -using adl::object; -using adl::argument; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(adl::call_proxy const& proxy) - { - return value_wrapper_traits::interpreter(*proxy.value_wrapper); - } - - template - static void unwrap(lua_State*, adl::call_proxy const& proxy) - { - object result = const_cast&>(proxy); - result.push(result.interpreter()); - } -}; - -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - static lua_State* interpreter(object const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, object const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } -}; - -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - static lua_State* interpreter(argument const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, argument const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } -}; - -template -inline void adl::index_proxy::push(lua_State* interpreter) -{ - assert(interpreter == m_interpreter); - - value_wrapper_traits::unwrap(m_interpreter, m_next); - - lua_pushvalue(m_interpreter, m_key_index); - lua_gettable(m_interpreter, -2); - lua_remove(m_interpreter, -2); -} - -template -inline adl::index_proxy::operator object() -{ - detail::stack_pop pop(m_interpreter, 1); - push(m_interpreter); - return object(from_stack(m_interpreter, -1)); -} - -template -adl::iterator_proxy::operator object() -{ - lua_pushvalue(m_interpreter, m_key_index); - AccessPolicy::get(m_interpreter, m_table_index); - detail::stack_pop pop(m_interpreter, 1); - return object(from_stack(m_interpreter, -1)); -} - -template -object detail::basic_iterator::key() const -{ - return object(m_key); -} - -namespace detail -{ - - template< - class T - , class ValueWrapper - , class Policies - , class ErrorPolicy - , class ReturnType - > - ReturnType object_cast_aux( - ValueWrapper const& value_wrapper - , T* - , Policies* - , ErrorPolicy* - , ReturnType* - ) - { - lua_State* interpreter = value_wrapper_traits::interpreter( - value_wrapper - ); - -#ifndef LUABIND_NO_ERROR_CHECKING - if (!interpreter) - return ErrorPolicy::handle_error(interpreter, typeid(void)); -#endif - - value_wrapper_traits::unwrap(interpreter, value_wrapper); - - detail::stack_pop pop(interpreter, 1); - - typedef typename detail::find_conversion_policy< - 0 - , Policies - >::type converter_generator; - - typename mpl::apply_wrap2::type cv; - -#ifndef LUABIND_NO_ERROR_CHECKING - if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0) - { - return ErrorPolicy::handle_error(interpreter, typeid(T)); - } -#endif - - return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1); - } - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable:4702) // unreachable code -# endif - - template - struct throw_error_policy - { - static T handle_error(lua_State* interpreter, type_id const& type_info) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(interpreter, type_info); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(interpreter, type_info); - - assert(0 && "object_cast failed. If you want to handle this error use " - "luabind::set_error_callback()"); - std::terminate(); -#endif - return *(typename boost::remove_reference::type*)0; - } - }; - -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif - - template - struct nothrow_error_policy - { - static boost::optional handle_error(lua_State*, type_id const&) - { - return boost::optional(); - } - }; - -} // namespace detail - -template -T object_cast(ValueWrapper const& value_wrapper) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (detail::null_type*)0 - , (detail::throw_error_policy*)0 - , (T*)0 - ); -} - -template -T object_cast(ValueWrapper const& value_wrapper, Policies const&) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (Policies*)0 - , (detail::throw_error_policy*)0 - , (T*)0 - ); -} - -template -boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (detail::null_type*)0 - , (detail::nothrow_error_policy*)0 - , (boost::optional*)0 - ); -} - -template -boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (Policies*)0 - , (detail::nothrow_error_policy*)0 - , (boost::optional*)0 - ); -} - -namespace detail -{ - - template - struct push_args_from_tuple - { - template - inline static void apply(lua_State* L, const boost::tuples::cons& x, const Policies& p) - { - convert_to_lua_p(L, *x.get_head(), p); - push_args_from_tuple::apply(L, x.get_tail(), p); - } - - template - inline static void apply(lua_State* L, const boost::tuples::cons& x) - { - convert_to_lua(L, *x.get_head()); - push_args_from_tuple::apply(L, x.get_tail()); - } - - template - inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {} - - inline static void apply(lua_State*, const boost::tuples::null_type&) {} - }; - -} // namespace detail - -namespace adl -{ - - template - struct call_proxy - { - call_proxy(ValueWrapper& value_wrapper, Arguments arguments) - : value_wrapper(&value_wrapper) - , arguments(arguments) - {} - - call_proxy(call_proxy const& other) - : value_wrapper(other.value_wrapper) - , arguments(other.arguments) - { - other.value_wrapper = 0; - } - - ~call_proxy() - { - if (value_wrapper) - call((detail::null_type*)0); - } - - operator object() - { - return call((detail::null_type*)0); - } - - template - object operator[](Policies const&) - { - return call((Policies*)0); - } - - template - object call(Policies*) - { - lua_State* interpreter = value_wrapper_traits::interpreter( - *value_wrapper - ); - - value_wrapper_traits::unwrap( - interpreter - , *value_wrapper - ); - - value_wrapper = 0; - - detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies()); - - if (detail::pcall(interpreter, boost::tuples::length::value, 1)) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(interpreter); -#else - error_callback_fun e = get_error_callback(); - if (e) e(interpreter); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "if you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - mutable ValueWrapper* value_wrapper; - Arguments arguments; - }; - - template - call_proxy > - object_interface::operator()() - { - return call_proxy >( - derived() - , boost::tuples::tuple<>() - ); - } - - // Simple value_wrapper adaptor with the sole purpose of helping with - // overload resolution. Use this as a function parameter type instead - // of "object" or "argument" to restrict the parameter to Lua tables. - template - struct table : Base - { - table(from_stack const& stack_reference) - : Base(stack_reference) - {} - }; - -} // namespace adl - -using adl::table; - -template -struct value_wrapper_traits > - : value_wrapper_traits -{ - static bool check(lua_State* L, int idx) - { - return value_wrapper_traits::check(L, idx) && - lua_istable(L, idx); - } -}; - -inline object newtable(lua_State* interpreter) -{ - lua_newtable(interpreter); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); -} - -// this could be optimized by returning a proxy -inline object globals(lua_State* interpreter) -{ - lua_pushglobaltable(interpreter); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); -} - -// this could be optimized by returning a proxy -inline object registry(lua_State* interpreter) -{ - lua_pushvalue(interpreter, LUA_REGISTRYINDEX); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); -} - -template -inline object gettable(ValueWrapper const& table, K const& key) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push(interpreter, key); - lua_gettable(interpreter, -2); - return object(from_stack(interpreter, -1)); -} - -template -inline void settable(ValueWrapper const& table, K const& key, T const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - // TODO: Exception safe? - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push(interpreter, key); - detail::push(interpreter, value); - lua_settable(interpreter, -3); -} - -template -inline object rawget(ValueWrapper const& table, K const& key) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push(interpreter, key); - lua_rawget(interpreter, -2); - return object(from_stack(interpreter, -1)); -} - -template -inline void rawset(ValueWrapper const& table, K const& key, T const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - // TODO: Exception safe? - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push(interpreter, key); - detail::push(interpreter, value); - lua_rawset(interpreter, -3); -} - -template -inline int type(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_type(interpreter, -1); -} - -template -inline object getmetatable(ValueWrapper const& obj) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - obj - ); - - value_wrapper_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 2); - lua_getmetatable(interpreter, -1); - return object(from_stack(interpreter, -1)); -} - -template -inline void setmetatable( - ValueWrapper1 const& obj, ValueWrapper2 const& metatable) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - obj - ); - - value_wrapper_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter, metatable); - lua_setmetatable(interpreter, -2); -} - -template -inline lua_CFunction tocfunction(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_tocfunction(interpreter, -1); -} - -template -inline T* touserdata(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return static_cast(lua_touserdata(interpreter, -1)); -} - -template -inline object getupvalue(ValueWrapper const& value, int index) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 2); - lua_getupvalue(interpreter, -1, index); - return object(from_stack(interpreter, -1)); -} - -template -inline void setupvalue( - ValueWrapper1 const& function, int index, ValueWrapper2 const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - function - ); - - value_wrapper_traits::unwrap(interpreter, function); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter, value); - lua_setupvalue(interpreter, -2, index); -} - -template -object property(GetValueWrapper const& get) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - get - ); - - value_wrapper_traits::unwrap(interpreter, get); - lua_pushnil(interpreter); - - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - - return object(from_stack(interpreter, -1)); -} - -template -object property(GetValueWrapper const& get, SetValueWrapper const& set) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - get - ); - - value_wrapper_traits::unwrap(interpreter, get); - value_wrapper_traits::unwrap(interpreter, set); - - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - - return object(from_stack(interpreter, -1)); - -} - - -} // namespace luabind - -#endif // LUABIND_OBJECT_050419_HPP - diff --git a/luabind/luabind/open.hpp b/luabind/luabind/open.hpp deleted file mode 100644 index cca4c7a52..000000000 --- a/luabind/luabind/open.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_OPEN_HPP_INCLUDED -#define LUABIND_OPEN_HPP_INCLUDED - -#include - -namespace luabind { - - LUABIND_API void open(lua_State* L); - -} - -#endif // LUABIND_OPEN_HPP_INCLUDED - diff --git a/luabind/luabind/operator.hpp b/luabind/luabind/operator.hpp deleted file mode 100644 index aeb651c03..000000000 --- a/luabind/luabind/operator.hpp +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef OPERATOR_040729_HPP -#define OPERATOR_040729_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__GNUC__) && __GNUC__ < 3 -# define LUABIND_NO_STRINGSTREAM -#else -# if defined(BOOST_NO_STRINGSTREAM) -# define LUABIND_NO_STRINGSTREAM -# endif -#endif - -#ifdef LUABIND_NO_STRINGSTREAM -#include -#else -#include -#endif - -namespace luabind { namespace detail { - - template struct unwrap_parameter_type; - template struct operator_ {}; - - struct operator_void_return {}; - -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - template - inline T const& operator,(T const& x, operator_void_return) - { - return x; - } -#endif - -}} // namespace luabind - -namespace luabind { namespace operators { - - #define BOOST_PP_ITERATION_PARAMS_1 (3, \ - (0, LUABIND_MAX_ARITY, )) - #include BOOST_PP_ITERATE() - -}} // namespace luabind::operators - -#include - -namespace luabind { - - template - struct self_base - { - operators::call_operator0 operator()() const - { - return 0; - } - -#define BOOST_PP_LOCAL_MACRO(n) \ - template \ - BOOST_PP_CAT(operators::call_operator, n)< \ - Derived \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \ - >\ - operator()( \ - BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \ - ) const \ - { \ - return 0; \ - } - -#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY) -#include BOOST_PP_LOCAL_ITERATE() - - }; - - struct self_type : self_base - { - }; - - struct const_self_type : self_base - { - }; - -namespace detail { - - template - struct unwrap_parameter_type - { - typedef typename boost::mpl::eval_if< - boost::is_same - , boost::mpl::identity - , boost::mpl::eval_if< - boost::is_same - , boost::mpl::identity - , unwrap_other - > - >::type type; - }; - - template - struct binary_operator - : operator_ > - { - binary_operator(int) {} - - template - struct apply - { - typedef typename unwrap_parameter_type::type arg0; - typedef typename unwrap_parameter_type::type arg1; - - static void execute(lua_State* L, arg0 _0, arg1 _1) - { - Derived::template apply::execute( - L, _0, _1); - } - }; - - static char const* name() - { - return Derived::name(); - } - }; - - template - struct unary_operator - : operator_ > - { - unary_operator(int) {} - - template - struct apply - { - typedef typename unwrap_parameter_type::type arg0; - - static void execute(lua_State* L, arg0 _0) - { - Derived::template apply::execute(L, _0); - } - }; - - static char const* name() - { - return Derived::name(); - } - }; - - template - inline void operator_result(lua_State* L, operator_void_return, Policies*) - { - } - - namespace mpl = boost::mpl; - - template - inline void operator_result(lua_State* L, T const& x, Policies*) - { - typedef typename find_conversion_policy< - 0 - , Policies - >::type cv_policy; - - typename mpl::apply_wrap2::type cv; - - cv.apply(L, x); - } - -}} // namespace detail::luabind - -namespace luabind { - -#define LUABIND_BINARY_OPERATOR(name_, op) \ - namespace operators { \ -\ - struct name_ \ - { \ - template \ - struct apply \ - { \ - static void execute(lua_State* L, T0 _0, T1 _1) \ - { \ - detail::operator_result(L, _0 op _1, (Policies*)0); \ - } \ - }; \ -\ - static char const* name() \ - { \ - return "__" # name_; \ - } \ - }; \ -\ - } \ - \ - template \ - detail::binary_operator< \ - operators::name_ \ - , U \ - , T \ - > \ - inline operator op(self_base, T const&) \ - { \ - return 0; \ - } \ - \ - template \ - detail::binary_operator< \ - operators::name_ \ - , T \ - , U \ - > \ - inline operator op(T const&, self_base) \ - { \ - return 0; \ - } \ - \ - detail::binary_operator< \ - operators::name_ \ - , self_type \ - , self_type \ - > \ - inline operator op(self_type, self_type) \ - { \ - return 0; \ - } \ - \ - detail::binary_operator< \ - operators::name_ \ - , self_type \ - , const_self_type \ - > \ - inline operator op(self_type, const_self_type) \ - { \ - return 0; \ - } \ - \ - detail::binary_operator< \ - operators::name_ \ - , const_self_type \ - , self_type \ - > \ - inline operator op(const_self_type, self_type) \ - { \ - return 0; \ - } \ - \ - detail::binary_operator< \ - operators::name_ \ - , const_self_type \ - , const_self_type \ - > \ - inline operator op(const_self_type, const_self_type) \ - { \ - return 0; \ - } - - LUABIND_BINARY_OPERATOR(add, +) - LUABIND_BINARY_OPERATOR(sub, -) - LUABIND_BINARY_OPERATOR(mul, *) - LUABIND_BINARY_OPERATOR(div, /) - LUABIND_BINARY_OPERATOR(pow, ^) - LUABIND_BINARY_OPERATOR(lt, <) - LUABIND_BINARY_OPERATOR(le, <=) - LUABIND_BINARY_OPERATOR(eq, ==) - -#undef LUABIND_UNARY_OPERATOR - -#define LUABIND_UNARY_OPERATOR(name_, op, fn) \ - namespace operators { \ -\ - struct name_ \ - { \ - template \ - struct apply \ - { \ - static void execute(lua_State* L, T x) \ - { \ - detail::operator_result(L, op(x), (Policies*)0); \ - } \ - }; \ -\ - static char const* name() \ - { \ - return "__" # name_; \ - } \ - }; \ -\ - } \ - \ - template \ - detail::unary_operator< \ - operators::name_ \ - , T \ - > \ - inline fn(self_base) \ - { \ - return 0; \ - } - - template - std::string tostring_operator(T const& x) - { -#ifdef LUABIND_NO_STRINGSTREAM - std::strstream s; - s << x << std::ends; -#else - std::stringstream s; - s << x; -#endif - return s.str(); - } - - LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) - LUABIND_UNARY_OPERATOR(unm, -, operator-) - -#undef LUABIND_BINARY_OPERATOR - - namespace { - - LUABIND_ANONYMOUS_FIX self_type self; - LUABIND_ANONYMOUS_FIX const_self_type const_self; - - } // namespace unnamed - -} // namespace luabind - -#endif // OPERATOR_040729_HPP - diff --git a/luabind/luabind/out_value_policy.hpp b/luabind/luabind/out_value_policy.hpp deleted file mode 100644 index ca496b527..000000000 --- a/luabind/luabind/out_value_policy.hpp +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED -#define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED - -#include -#include -#include - -namespace luabind { namespace detail -{ - template - struct char_array - { - char storage[N]; - }; - -#if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 ) - - template - char_array indirect_sizeof_test(by_reference); - - template - char_array indirect_sizeof_test(by_const_reference); - - template - char_array indirect_sizeof_test(by_pointer); - - template - char_array indirect_sizeof_test(by_const_pointer); - - template - char_array indirect_sizeof_test(by_value); - -#else - - template - char_array::type)> indirect_sizeof_test(by_reference); - - template - char_array::type)> indirect_sizeof_test(by_const_reference); - - template - char_array::type)> indirect_sizeof_test(by_pointer); - - template - char_array::type)> indirect_sizeof_test(by_const_pointer); - - template - char_array::type)> indirect_sizeof_test(by_value); - -#endif - - template - struct indirect_sizeof - { - BOOST_STATIC_CONSTANT(int, value = sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T)))); - }; - - namespace mpl = boost::mpl; - - template - struct out_value_converter - { - int const consumed_args(...) - { - return 1; - } - - template - T& apply(lua_State* L, by_reference, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); - return *reinterpret_cast(m_storage); - } - - template - static int match(lua_State* L, by_reference, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typedef typename mpl::apply_wrap2::type converter; - return converter::match(L, LUABIND_DECORATE_TYPE(T), index); - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - typedef typename find_conversion_policy<2, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - template - T* apply(lua_State* L, by_pointer, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); - return reinterpret_cast(m_storage); - } - - template - static int match(lua_State* L, by_pointer, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typedef typename mpl::apply_wrap2::type converter; - return converter::match(L, LUABIND_DECORATE_TYPE(T), index); - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - typedef typename find_conversion_policy<2, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - char m_storage[Size]; - }; - - template - struct out_value_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , typename boost::mpl::if_, is_nonconst_pointer > - , out_value_converter::value, Policies> - , only_accepts_nonconst_references_or_pointers - >::type - , can_only_convert_from_lua_to_cpp - >::type type; - }; - }; - - template - struct pure_out_value_converter - { - int const consumed_args(...) - { - return 0; - } - - template - T& apply(lua_State*, by_reference, int) - { - new (m_storage) T(); - return *reinterpret_cast(m_storage); - } - - template - static int match(lua_State*, by_reference, int) - { - return 0; - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - template - T* apply(lua_State*, by_pointer, int) - { - new (m_storage) T(); - return reinterpret_cast(m_storage); - } - - template - static int match(lua_State*, by_pointer, int) - { - return 0; - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - - char m_storage[Size]; - }; - - template - struct pure_out_value_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , typename boost::mpl::if_, is_nonconst_pointer > - , pure_out_value_converter::value, Policies> - , only_accepts_nonconst_references_or_pointers - >::type - , can_only_convert_from_lua_to_cpp - >::type type; - }; - }; - -}} - -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - out_value(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - pure_out_value(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - pure_out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } -} - -#endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED - diff --git a/luabind/luabind/prefix.hpp b/luabind/luabind/prefix.hpp deleted file mode 100644 index 86f2db1b5..000000000 --- a/luabind/luabind/prefix.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin - -// 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. - -#ifndef PREFIX_040218_HPP -#define PREFIX_040218_HPP - -#ifdef LUABIND_PREFIX_INCLUDE -# include LUABIND_PREFIX_INCLUDE -#endif - -#endif // PREFIX_040218_HPP - diff --git a/luabind/luabind/raw_policy.hpp b/luabind/luabind/raw_policy.hpp deleted file mode 100644 index 6d22da246..000000000 --- a/luabind/luabind/raw_policy.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_RAW_POLICY_HPP_INCLUDED -#define LUABIND_RAW_POLICY_HPP_INCLUDED - -#include -#include - -namespace luabind { namespace detail { - - struct raw_converter - { - int const consumed_args(...) - { - return 0; - } - - lua_State* apply(lua_State* L, by_pointer, int) - { - return L; - } - - static int match(...) - { - return 0; - } - - void converter_postcall(lua_State*, by_pointer, int) {} - }; - - template - struct raw_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - template - struct apply - { - typedef raw_converter type; - }; - }; - -}} // namespace luabind::detail - -namespace luabind { - - template - detail::policy_cons< - detail::raw_policy - , detail::null_type - > - inline raw(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons< - detail::raw_policy - , detail::null_type - >(); - } - -} // namespace luabind - -#endif // LUABIND_RAW_POLICY_HPP_INCLUDED - diff --git a/luabind/luabind/return_reference_to_policy.hpp b/luabind/luabind/return_reference_to_policy.hpp deleted file mode 100644 index 1432f79e0..000000000 --- a/luabind/luabind/return_reference_to_policy.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED -#define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED - -namespace luabind { namespace detail -{ - template - struct return_reference_to_converter; - - template<> - struct return_reference_to_converter - { - template - void apply(lua_State* L, const T&) - { - lua_pushnil(L); - } - }; - - template - struct return_reference_to_policy : conversion_policy<0> - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State* L, const index_map& indices) - { - int result_index = indices[0]; - int ref_to_index = indices[N]; - - lua_pushvalue(L, ref_to_index); - lua_replace(L, result_index); - } - - template - struct apply - { - typedef return_reference_to_converter type; - }; - }; -}} - -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - return_reference_to(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } -} - -#endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED - diff --git a/luabind/luabind/scope.hpp b/luabind/luabind/scope.hpp deleted file mode 100644 index 3b5f293bf..000000000 --- a/luabind/luabind/scope.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef NEW_SCOPE_040211_HPP -#define NEW_SCOPE_040211_HPP - -#include -#include -#include -#include - -namespace luabind { - - struct scope; - -} // namespace luabind - -namespace luabind { namespace detail { - - struct LUABIND_API registration - { - registration(); - virtual ~registration(); - - protected: - virtual void register_(lua_State*) const = 0; - - private: - friend struct ::luabind::scope; - registration* m_next; - }; - -}} // namespace luabind::detail - -namespace luabind { - - struct LUABIND_API scope - { - scope(); - explicit scope(std::auto_ptr reg); - scope(scope const& other_); - ~scope(); - - scope& operator=(scope const& other_); - - scope& operator,(scope s); - - void register_(lua_State* L) const; - - private: - detail::registration* m_chain; - }; - - class LUABIND_API namespace_ : public scope - { - public: - explicit namespace_(char const* name); - namespace_& operator[](scope s); - - private: - struct registration_; - registration_* m_registration; - }; - - class LUABIND_API module_ - { - public: - module_(lua_State* L_, char const* name); - void operator[](scope s); - - private: - lua_State* m_state; - char const* m_name; - }; - - inline module_ module(lua_State* L, char const* name = 0) - { - return module_(L, name); - } - -} // namespace luabind - -#endif // NEW_SCOPE_040211_HPP - diff --git a/luabind/luabind/shared_ptr_converter.hpp b/luabind/luabind/shared_ptr_converter.hpp deleted file mode 100644 index 2f61b5cff..000000000 --- a/luabind/luabind/shared_ptr_converter.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright Daniel Wallin 2009. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_SHARED_PTR_CONVERTER_090211_HPP -# define LUABIND_SHARED_PTR_CONVERTER_090211_HPP - -# include -# include -# include -# include - -namespace luabind { - -namespace detail -{ - - struct shared_ptr_deleter - { - shared_ptr_deleter(lua_State* L, int index) - : life_support(get_main_thread(L), L, index) - {} - - void operator()(void const*) - { - handle().swap(life_support); - } - - handle life_support; - }; - -} // namespace detail - -template -struct default_converter > - : default_converter -{ - typedef boost::mpl::false_ is_native; - - template - int match(lua_State* L, U, int index) - { - return default_converter::match( - L, LUABIND_DECORATE_TYPE(T*), index); - } - - template - boost::shared_ptr apply(lua_State* L, U, int index) - { - T* raw_ptr = default_converter::apply( - L, LUABIND_DECORATE_TYPE(T*), index); - if (!raw_ptr) - return boost::shared_ptr(); - return boost::shared_ptr( - raw_ptr, detail::shared_ptr_deleter(L, index)); - } - - void apply(lua_State* L, boost::shared_ptr const& p) - { - if (detail::shared_ptr_deleter* d = - boost::get_deleter(p)) - { - d->life_support.push(L); - } - else - { - detail::value_converter().apply(L, p); - } - } - - template - void converter_postcall(lua_State*, U const&, int) - {} -}; - -template -struct default_converter const&> - : default_converter > -{}; - -} // namespace luabind - -#endif // LUABIND_SHARED_PTR_CONVERTER_090211_HPP diff --git a/luabind/luabind/tag_function.hpp b/luabind/luabind/tag_function.hpp deleted file mode 100644 index 51fe97b75..000000000 --- a/luabind/luabind/tag_function.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if !BOOST_PP_IS_ITERATING - -# ifndef LUABIND_TAG_FUNCTION_081129_HPP -# define LUABIND_TAG_FUNCTION_081129_HPP - -# if LUABIND_MAX_ARITY <= 8 -# include -# else -# include -# endif -# include -# include -# include -# include - -namespace luabind { - -namespace detail -{ - - template - struct tagged_function - { - tagged_function(F f) - : f(f) - {} - - F f; - }; - - template - Signature deduce_signature(tagged_function const&, ...) - { - return Signature(); - } - - template - int invoke( - lua_State* L, function_object const& self, invoke_context& ctx - , tagged_function const& tagged - , Signature, Policies const& policies) - { - return invoke(L, self, ctx, tagged.f, Signature(), policies); - } - - template - struct signature_from_function; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -} // namespace detail - -template -detail::tagged_function< - typename detail::signature_from_function::type - , F -> -tag_function(F f) -{ - return f; -} - -} // namespace luabind - -# endif // LUABIND_TAG_FUNCTION_081129_HPP - -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define NPLUS1 BOOST_PP_INC(N) - -template -struct signature_from_function -{ - typedef BOOST_PP_CAT(mpl::vector, NPLUS1)< - R BOOST_PP_ENUM_TRAILING_PARAMS(N, A) - > type; -}; - -#endif // BOOST_PP_IS_ITERATING - - diff --git a/luabind/luabind/typeid.hpp b/luabind/luabind/typeid.hpp deleted file mode 100644 index d92d8fbac..000000000 --- a/luabind/luabind/typeid.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_TYPEID_081227_HPP -# define LUABIND_TYPEID_081227_HPP - -# include -# include -# include - -namespace luabind { - -# ifdef BOOST_MSVC -# pragma warning(push) -// std::type_info::before() returns int, rather than bool. -// At least on MSVC7.1, this is true for the comparison -// operators as well. -# pragma warning(disable:4800) -# endif - -class type_id - : public boost::less_than_comparable -{ -public: - type_id() - : id(&typeid(detail::null_type)) - {} - - type_id(std::type_info const& id) - : id(&id) - {} - - bool operator!=(type_id const& other) const - { - return *id != *other.id; - } - - bool operator==(type_id const& other) const - { - return *id == *other.id; - } - - bool operator<(type_id const& other) const - { - return id->before(*other.id); - } - - char const* name() const - { - return id->name(); - } - -private: - std::type_info const* id; -}; - -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif - -} // namespace luabind - -#endif // LUABIND_TYPEID_081227_HPP - diff --git a/luabind/luabind/value_wrapper.hpp b/luabind/luabind/value_wrapper.hpp deleted file mode 100644 index 8e09395d5..000000000 --- a/luabind/luabind/value_wrapper.hpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef LUABIND_VALUE_WRAPPER_050419_HPP -#define LUABIND_VALUE_WRAPPER_050419_HPP - -#include -#include -#include - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# define LUABIND_USE_VALUE_WRAPPER_TAG -#else -#endif - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -namespace luabind { - -// -// Concept ``ValueWrapper`` -// - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits; - -namespace detail -{ - - BOOST_MPL_HAS_XXX_TRAIT_DEF(value_wrapper_tag); - - struct unspecialized_value_wrapper_traits - { - typedef boost::mpl::false_ is_specialized; - }; - - template - struct value_wrapper_traits_aux - { - typedef value_wrapper_traits type; - }; - -} // namespace detail -#endif - -template -struct value_wrapper_traits -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - : boost::mpl::eval_if< - boost::mpl::and_< - boost::mpl::not_< - boost::mpl::or_< - boost::is_reference - , boost::is_pointer - , boost::is_array - > - > - , detail::has_value_wrapper_tag - > - , detail::value_wrapper_traits_aux - , boost::mpl::identity - >::type -{}; -#else -{ - typedef boost::mpl::false_ is_specialized; -}; -#endif - -template -struct is_value_wrapper - : boost::mpl::aux::msvc_eti_base< - typename value_wrapper_traits::is_specialized - >::type -{}; - -} // namespace luabind - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -# include -# include - -namespace luabind { - -template -struct is_value_wrapper_arg - : is_value_wrapper< - typename boost::remove_const< - typename boost::remove_reference::type - >::type - > -{}; - -} // namespace luabind - -#else - -# include -# include - -namespace luabind { - -namespace detail -{ - template - typename is_value_wrapper::type is_value_wrapper_arg_check(T const*); - - yes_t to_yesno(boost::mpl::true_); - no_t to_yesno(boost::mpl::false_); - - template - struct is_value_wrapper_arg_aux - { - static typename boost::add_reference::type x; - - BOOST_STATIC_CONSTANT(bool, value = - sizeof(to_yesno(is_value_wrapper_arg_check(&x))) - == sizeof(yes_t) - ); - - typedef boost::mpl::bool_ type; - }; - -} // namespace detail - -template -struct is_value_wrapper_arg - : detail::is_value_wrapper_arg_aux::type -{ -}; - -} // namespace luabind - -#endif - -#endif // LUABIND_VALUE_WRAPPER_050419_HPP - diff --git a/luabind/luabind/version.hpp b/luabind/luabind/version.hpp deleted file mode 100644 index 63acaf765..000000000 --- a/luabind/luabind/version.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright Daniel Wallin 2009. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_VERSION_090216_HPP -# define LUABIND_VERSION_090216_HPP - -# define LUABIND_VERSION 900 - -// Each component uses two digits, so: -// -// major = LUABIND_VERSION / 10000 -// minor = LUABIND_VERSION / 100 % 100 -// patch = LUABIND_VERSION % 100 - -#endif // LUABIND_VERSION_090216_HPP diff --git a/luabind/luabind/weak_ref.hpp b/luabind/luabind/weak_ref.hpp deleted file mode 100644 index e08e250dc..000000000 --- a/luabind/luabind/weak_ref.hpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#ifndef WEAK_REF_040402_HPP -#define WEAK_REF_040402_HPP - -#include - -struct lua_State; - -namespace luabind { - - class LUABIND_API weak_ref - { - public: - weak_ref(); - weak_ref(lua_State* main, lua_State* L, int index); - weak_ref(weak_ref const&); - ~weak_ref(); - - weak_ref& operator=(weak_ref const&); - - void swap(weak_ref&); - - // returns a unique id that no - // other weak ref will return - int id() const; - - lua_State* state() const; - void get(lua_State* L) const; - - private: - struct impl; - impl* m_impl; - }; - -} // namespace luabind - -#endif // WEAK_REF_040402_HPP - diff --git a/luabind/luabind/wrapper_base.hpp b/luabind/luabind/wrapper_base.hpp deleted file mode 100644 index 9adc05a35..000000000 --- a/luabind/luabind/wrapper_base.hpp +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#if !BOOST_PP_IS_ITERATING - -#ifndef LUABIND_WRAPPER_BASE_HPP_INCLUDED -#define LUABIND_WRAPPER_BASE_HPP_INCLUDED - -#include -#include -#include -#include - -#include -#include - -#include - -namespace luabind -{ - namespace detail - { - struct wrap_access; - - // implements the selection between dynamic dispatch - // or default implementation calls from within a virtual - // function wrapper. The input is the self reference on - // the top of the stack. Output is the function to call - // on the top of the stack (the input self reference will - // be popped) - LUABIND_API void do_call_member_selection(lua_State* L, char const* name); - } - - struct wrapped_self_t: weak_ref - { - detail::lua_reference m_strong_ref; - }; - - struct wrap_base - { - friend struct detail::wrap_access; - wrap_base() {} - - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() - - private: - wrapped_self_t m_self; - }; - -#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 2)) -#include BOOST_PP_ITERATE() - - namespace detail - { - struct wrap_access - { - static wrapped_self_t const& ref(wrap_base const& b) - { - return b.m_self; - } - - static wrapped_self_t& ref(wrap_base& b) - { - return b.m_self; - } - }; - } -} - -#endif // LUABIND_WRAPPER_BASE_HPP_INCLUDED - -#else -#if BOOST_PP_ITERATION_FLAGS() == 1 - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - template - typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type - call(char const* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _), detail::type_* = 0) const - { - typedef boost::tuples::tuple tuple_t; - #if BOOST_PP_ITERATION() == 0 - tuple_t args; - #else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); - #endif - - typedef typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type proxy_type; - - // this will be cleaned up by the proxy object - // once the call has been made - - // TODO: what happens if this virtual function is - // dispatched from a lua thread where the state - // pointer is different? - - // get the function - lua_State* L = m_self.state(); - m_self.get(L); - assert(!lua_isnil(L, -1)); - detail::do_call_member_selection(L, name); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - throw std::runtime_error("Attempt to call nonexistent function"); - } - - // push the self reference as the first parameter - m_self.get(L); - - // now the function and self objects - // are on the stack. These will both - // be popped by pcall - return proxy_type(L, args); - } - -#undef LUABIND_CALL_MEMBER_NAME -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#else // free call_member forwardarding functions - -#define N BOOST_PP_ITERATION() - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - template< - class R - BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) - > - typename boost::mpl::if_< - boost::is_void - , detail::proxy_member_void_caller< - boost::tuples::tuple< - BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) - > - > - , detail::proxy_member_caller< - R - , boost::tuples::tuple< - BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) - > - > - >::type - call_member( - wrap_base const* self - , char const* fn - BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, &a) - , detail::type_* = 0 - ) - { - return self->call( - fn - BOOST_PP_ENUM_TRAILING_PARAMS(N, a) - , (detail::type_*)0 - ); - } - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#undef N - -#endif -#endif \ No newline at end of file diff --git a/luabind/luabind/yield_policy.hpp b/luabind/luabind/yield_policy.hpp deleted file mode 100644 index 9dbbefa29..000000000 --- a/luabind/luabind/yield_policy.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - - -#ifndef LUABIND_YIELD_POLICY_HPP_INCLUDED -#define LUABIND_YIELD_POLICY_HPP_INCLUDED - -#include -#include - -namespace luabind { namespace detail -{ - struct yield_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - }; - - template - struct has_yield - { - BOOST_STATIC_CONSTANT(bool, - value = (boost::is_same::value || - has_yield::value)); - }; - - template<> - struct has_yield - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; -}} - -namespace luabind -{ - detail::policy_cons const yield = {}; - - namespace detail - { - inline void ignore_unused_yield() - { - (void)yield; - } - } -} - -#endif // LUABIND_YIELD_POLICY_HPP_INCLUDED - diff --git a/luabind/src/class.cpp b/luabind/src/class.cpp deleted file mode 100644 index 8a67cf6f3..000000000 --- a/luabind/src/class.cpp +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include - -#include -#include -#include - -#include -#include - -namespace luabind -{ - LUABIND_API detail::nil_type nil; -} - -namespace luabind { namespace detail { - - - namespace - { - struct cast_entry - { - cast_entry(class_id src, class_id target, cast_function cast) - : src(src) - , target(target) - , cast(cast) - {} - - class_id src; - class_id target; - cast_function cast; - }; - - } // namespace unnamed - - struct class_registration : registration - { - class_registration(char const* name); - - void register_(lua_State* L) const; - - const char* m_name; - - mutable std::map m_static_constants; - - typedef std::pair base_desc; - mutable std::vector m_bases; - - type_id m_type; - class_id m_id; - class_id m_wrapper_id; - type_id m_wrapper_type; - std::vector m_casts; - - scope m_scope; - scope m_members; - scope m_default_members; - }; - - class_registration::class_registration(char const* name) - { - m_name = name; - } - - void class_registration::register_(lua_State* L) const - { - LUABIND_CHECK_STACK(L); - - assert(lua_type(L, -1) == LUA_TTABLE); - - lua_pushstring(L, m_name); - - detail::class_rep* crep; - - detail::class_registry* r = detail::class_registry::get_registry(L); - // create a class_rep structure for this class. - // allocate it within lua to let lua collect it on - // lua_close(). This is better than allocating it - // as a static, since it will then be destructed - // when the program exits instead. - // warning: we assume that lua will not - // move the userdata memory. - lua_newuserdata(L, sizeof(detail::class_rep)); - crep = reinterpret_cast(lua_touserdata(L, -1)); - - new(crep) detail::class_rep( - m_type - , m_name - , L - ); - - // register this new type in the class registry - r->add_class(m_type, crep); - - lua_pushstring(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - class_map& classes = *static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - classes.put(m_id, crep); - - bool const has_wrapper = m_wrapper_id != registered_class::id; - - if (has_wrapper) - classes.put(m_wrapper_id, crep); - - crep->m_static_constants.swap(m_static_constants); - - detail::class_registry* registry = detail::class_registry::get_registry(L); - - crep->get_default_table(L); - m_scope.register_(L); - m_default_members.register_(L); - lua_pop(L, 1); - - crep->get_table(L); - m_members.register_(L); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - cast_graph* const casts = static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_id_map* const class_ids = static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - class_ids->put(m_id, m_type); - - if (has_wrapper) - class_ids->put(m_wrapper_id, m_wrapper_type); - - BOOST_FOREACH(cast_entry const& e, m_casts) - { - casts->insert(e.src, e.target, e.cast); - } - - for (std::vector::iterator i = m_bases.begin(); - i != m_bases.end(); ++i) - { - LUABIND_CHECK_STACK(L); - - // the baseclass' class_rep structure - detail::class_rep* bcrep = registry->find_class(i->first); - - detail::class_rep::base_info base; - base.pointer_offset = 0; - base.base = bcrep; - - crep->add_base_class(base); - - // copy base class table - crep->get_table(L); - bcrep->get_table(L); - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if (!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); - - // copy base class detaults table - crep->get_default_table(L); - bcrep->get_default_table(L); - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if (!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); - - } - - lua_settable(L, -3); - } - - // -- interface --------------------------------------------------------- - - class_base::class_base(char const* name) - : scope(std::auto_ptr( - m_registration = new class_registration(name)) - ) - { - } - - void class_base::init( - type_id const& type_id_, class_id id - , type_id const& wrapper_type, class_id wrapper_id) - { - m_registration->m_type = type_id_; - m_registration->m_id = id; - m_registration->m_wrapper_type = wrapper_type; - m_registration->m_wrapper_id = wrapper_id; - } - - void class_base::add_base(type_id const& base, cast_function cast) - { - m_registration->m_bases.push_back(std::make_pair(base, cast)); - } - - void class_base::add_member(registration* member) - { - std::auto_ptr ptr(member); - m_registration->m_members.operator,(scope(ptr)); - } - - void class_base::add_default_member(registration* member) - { - std::auto_ptr ptr(member); - m_registration->m_default_members.operator,(scope(ptr)); - } - - const char* class_base::name() const - { - return m_registration->m_name; - } - - void class_base::add_static_constant(const char* name, int val) - { - m_registration->m_static_constants[name] = val; - } - - void class_base::add_inner_scope(scope& s) - { - m_registration->m_scope.operator,(s); - } - - void class_base::add_cast( - class_id src, class_id target, cast_function cast) - { - m_registration->m_casts.push_back(cast_entry(src, target, cast)); - } - - void add_custom_name(type_id const& i, std::string& s) - { - s += " ["; - s += i.name(); - s += "]"; - } - - std::string get_class_name(lua_State* L, type_id const& i) - { - std::string ret; - - assert(L); - - class_registry* r = class_registry::get_registry(L); - class_rep* crep = r->find_class(i); - - if (crep == 0) - { - ret = "custom"; - add_custom_name(i, ret); - } - else - { - /* TODO reimplement this? - if (i == crep->holder_type()) - { - ret += "smart_ptr<"; - ret += crep->name(); - ret += ">"; - } - else if (i == crep->const_holder_type()) - { - ret += "smart_ptrname(); - ret += ">"; - } - else*/ - { - ret += crep->name(); - } - } - return ret; - } - -}} // namespace luabind::detail - diff --git a/luabind/src/class_info.cpp b/luabind/src/class_info.cpp deleted file mode 100644 index 531f6e0cc..000000000 --- a/luabind/src/class_info.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include -#include -#include - -namespace luabind -{ - LUABIND_API class_info get_class_info(argument const& o) - { - lua_State* L = o.interpreter(); - - o.push(L); - detail::object_rep* obj = detail::get_instance(L, -1); - - if (!obj) - { - class_info result; - result.name = lua_typename(L, lua_type(L, -1)); - lua_pop(L, 1); - result.methods = newtable(L); - result.attributes = newtable(L); - return result; - } - - lua_pop(L, 1); - - obj->crep()->get_table(L); - object table(from_stack(L, -1)); - lua_pop(L, 1); - - class_info result; - result.name = obj->crep()->name(); - result.methods = newtable(L); - result.attributes = newtable(L); - - std::size_t index = 1; - - for (iterator i(table), e; i != e; ++i) - { - if (type(*i) != LUA_TFUNCTION) - continue; - - // We have to create a temporary `object` here, otherwise the proxy - // returned by operator->() will mess up the stack. This is a known - // problem that probably doesn't show up in real code very often. - object member(*i); - member.push(L); - detail::stack_pop pop(L, 1); - - if (lua_tocfunction(L, -1) == &detail::property_tag) - { - result.attributes[index++] = i.key(); - } - else - { - result.methods[i.key()] = *i; - } - } - - return result; - } - - LUABIND_API object get_class_names(lua_State* L) - { - detail::class_registry* reg = detail::class_registry::get_registry(L); - - std::map const& classes = reg->get_classes(); - - object result = newtable(L); - std::size_t index = 1; - - for (std::map::const_iterator iter = classes.begin(); - iter != classes.end(); ++iter) - { - result[index++] = iter->second->name(); - } - - return result; - } - - LUABIND_API void bind_class_info(lua_State* L) - { - module(L) - [ - class_("class_info_data") - .def_readonly("name", &class_info::name) - .def_readonly("methods", &class_info::methods) - .def_readonly("attributes", &class_info::attributes), - - def("class_info", &get_class_info), - def("class_names", &get_class_names) - ]; - } -} - diff --git a/luabind/src/class_registry.cpp b/luabind/src/class_registry.cpp deleted file mode 100644 index 79df30ade..000000000 --- a/luabind/src/class_registry.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin - -// 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. - -#define LUABIND_BUILDING - -#include - -#include -#include -#include -#include - -namespace luabind { namespace detail { - - LUABIND_API void push_instance_metatable(lua_State* L); - - namespace { - - int create_cpp_class_metatable(lua_State* L) - { - lua_newtable(L); - - // mark the table with our (hopefully) unique tag - // that says that the user data that has this - // metatable is a class_rep - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); - - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , &garbage_collector_s< - detail::class_rep - >::apply - , 0); - - lua_rawset(L, -3); - - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); - - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); - - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); - - return luaL_ref(L, LUA_REGISTRYINDEX); - } - - int create_lua_class_metatable(lua_State* L) - { - lua_newtable(L); - - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); - - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , &detail::garbage_collector_s< - detail::class_rep - >::apply - , 0); - - lua_rawset(L, -3); - - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); - - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); - - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); - - return luaL_ref(L, LUA_REGISTRYINDEX); - } - - } // namespace unnamed - - class class_rep; - - class_registry::class_registry(lua_State* L) - : m_cpp_class_metatable(create_cpp_class_metatable(L)) - , m_lua_class_metatable(create_lua_class_metatable(L)) - { - push_instance_metatable(L); - m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); - } - - class_registry* class_registry::get_registry(lua_State* L) - { - -#ifdef LUABIND_NOT_THREADSAFE - - // if we don't have to be thread safe, we can keep a - // chache of the class_registry pointer without the - // need of a mutex - static lua_State* cache_key = 0; - static class_registry* registry_cache = 0; - if (cache_key == L) return registry_cache; - -#endif - - lua_pushstring(L, "__luabind_classes"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_registry* p = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - -#ifdef LUABIND_NOT_THREADSAFE - - cache_key = L; - registry_cache = p; - -#endif - - return p; - } - - void class_registry::add_class(type_id const& info, class_rep* crep) - { - // class is already registered - assert((m_classes.find(info) == m_classes.end()) - && "you are trying to register a class twice"); - m_classes[info] = crep; - } - - class_rep* class_registry::find_class(type_id const& info) const - { - std::map::const_iterator i( - m_classes.find(info)); - - if (i == m_classes.end()) return 0; // the type is not registered - return i->second; - } - -}} // namespace luabind::detail - diff --git a/luabind/src/class_rep.cpp b/luabind/src/class_rep.cpp deleted file mode 100644 index 5f03f3931..000000000 --- a/luabind/src/class_rep.cpp +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include -#include -#include -#include -#include -#include - -using namespace luabind::detail; - -namespace luabind { namespace detail -{ - LUABIND_API int property_tag(lua_State* L) - { - lua_pushstring(L, "luabind: property_tag function can't be called"); - lua_error(L); - return 0; - } -}} - -luabind::detail::class_rep::class_rep(type_id const& type - , const char* name - , lua_State* L -) - : m_type(type) - , m_name(name) - , m_class_type(cpp_class) - , m_operator_cache(0) -{ - lua_newtable(L); - handle(L, -1).swap(m_table); - lua_newtable(L); - handle(L, -1).swap(m_default_table); - lua_pop(L, 2); - - class_registry* r = class_registry::get_registry(L); - assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - - lua_rawgeti(L, LUA_REGISTRYINDEX, r->cpp_class()); - lua_setmetatable(L, -2); - - lua_pushvalue(L, -1); // duplicate our user data - m_self_ref.set(L); - - m_instance_metatable = r->cpp_instance(); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); -} - -luabind::detail::class_rep::class_rep(lua_State* L, const char* name) - : m_type(typeid(null_type)) - , m_name(name) - , m_class_type(lua_class) - , m_operator_cache(0) -{ - lua_newtable(L); - handle(L, -1).swap(m_table); - lua_newtable(L); - handle(L, -1).swap(m_default_table); - lua_pop(L, 2); - - class_registry* r = class_registry::get_registry(L); - assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - - lua_rawgeti(L, LUA_REGISTRYINDEX, r->lua_class()); - lua_setmetatable(L, -2); - lua_pushvalue(L, -1); // duplicate our user data - m_self_ref.set(L); - - m_instance_metatable = r->lua_instance(); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); -} - -luabind::detail::class_rep::~class_rep() -{ -} - -// leaves object on lua stack -std::pair -luabind::detail::class_rep::allocate(lua_State* L) const -{ - const int size = sizeof(object_rep); - char* mem = static_cast(lua_newuserdata(L, size)); - return std::pair(mem, (void*)0); -} - -namespace -{ - - bool super_deprecation_disabled = false; - -} // namespace unnamed - -// this is called as metamethod __call on the class_rep. -int luabind::detail::class_rep::constructor_dispatcher(lua_State* L) -{ - class_rep* cls = static_cast(lua_touserdata(L, 1)); - - int args = lua_gettop(L); - - push_new_instance(L, cls); - - if (super_deprecation_disabled - && cls->get_class_type() == class_rep::lua_class - && !cls->bases().empty()) - { - lua_pushvalue(L, 1); - lua_pushvalue(L, -2); - lua_pushcclosure(L, super_callback, 2); - lua_setglobal(L, "super"); - } - - lua_pushvalue(L, -1); - lua_replace(L, 1); - - cls->get_table(L); - lua_pushliteral(L, "__init"); - lua_gettable(L, -2); - - lua_insert(L, 1); - - lua_pop(L, 1); - lua_insert(L, 1); - - lua_call(L, args, 0); - - if (super_deprecation_disabled) - { - lua_pushnil(L); - lua_setglobal(L, "super"); - } - - return 1; -} - -void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info& binfo) -{ - // If you hit this assert you are deriving from a type that is not registered - // in lua. That is, in the class_<> you are giving a baseclass that isn't registered. - // Please note that if you don't need to have access to the base class or the - // conversion from the derived class to the base class, you don't need - // to tell luabind that it derives. - assert(binfo.base && "You cannot derive from an unregistered type"); - - class_rep* bcrep = binfo.base; - - // import all static constants - for (std::map::const_iterator i = bcrep->m_static_constants.begin(); - i != bcrep->m_static_constants.end(); ++i) - { - int& v = m_static_constants[i->first]; - v = i->second; - } - - // also, save the baseclass info to be used for typecasts - m_bases.push_back(binfo); -} - -LUABIND_API void luabind::disable_super_deprecation() -{ - super_deprecation_disabled = true; -} - -int luabind::detail::class_rep::super_callback(lua_State* L) -{ - int args = lua_gettop(L); - - class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); - class_rep* base = crep->bases()[0].base; - - if (base->bases().empty()) - { - lua_pushnil(L); - lua_setglobal(L, "super"); - } - else - { - lua_pushlightuserdata(L, base); - lua_pushvalue(L, lua_upvalueindex(2)); - lua_pushcclosure(L, super_callback, 2); - lua_setglobal(L, "super"); - } - - base->get_table(L); - lua_pushstring(L, "__init"); - lua_gettable(L, -2); - lua_insert(L, 1); - lua_pop(L, 1); - - lua_pushvalue(L, lua_upvalueindex(2)); - lua_insert(L, 2); - - lua_call(L, args + 1, 0); - - // TODO: instead of clearing the global variable "super" - // store it temporarily in the registry. maybe we should - // have some kind of warning if the super global is used? - lua_pushnil(L); - lua_setglobal(L, "super"); - - return 0; -} - - - -int luabind::detail::class_rep::lua_settable_dispatcher(lua_State* L) -{ - class_rep* crep = static_cast(lua_touserdata(L, 1)); - - // get first table - crep->get_table(L); - - // copy key, value - lua_pushvalue(L, -3); - lua_pushvalue(L, -3); - lua_rawset(L, -3); - // pop table - lua_pop(L, 1); - - // get default table - crep->get_default_table(L); - lua_replace(L, 1); - lua_rawset(L, -3); - - crep->m_operator_cache = 0; // invalidate cache - - return 0; -} - -/* - stack: - 1: class_rep - 2: member name -*/ -int luabind::detail::class_rep::static_class_gettable(lua_State* L) -{ - class_rep* crep = static_cast(lua_touserdata(L, 1)); - - // look in the static function table - crep->get_default_table(L); - lua_pushvalue(L, 2); - lua_gettable(L, -2); - if (!lua_isnil(L, -1)) return 1; - else lua_pop(L, 2); - - const char* key = lua_tostring(L, 2); - - if (std::strlen(key) != lua_strlen(L, 2)) - { - lua_pushnil(L); - return 1; - } - - std::map::const_iterator j = crep->m_static_constants.find(key); - - if (j != crep->m_static_constants.end()) - { - lua_pushnumber(L, j->second); - return 1; - } - -#ifndef LUABIND_NO_ERROR_CHECKING - - { - std::string msg = "no static '"; - msg += key; - msg += "' in class '"; - msg += crep->name(); - msg += "'"; - lua_pushstring(L, msg.c_str()); - } - lua_error(L); - -#endif - - lua_pushnil(L); - - return 1; -} - -bool luabind::detail::is_class_rep(lua_State* L, int index) -{ - if (lua_getmetatable(L, index) == 0) return false; - - lua_pushstring(L, "__luabind_classrep"); - lua_gettable(L, -2); - if (lua_toboolean(L, -1)) - { - lua_pop(L, 2); - return true; - } - - lua_pop(L, 2); - return false; -} - -void luabind::detail::finalize(lua_State* L, class_rep* crep) -{ - if (crep->get_class_type() != class_rep::lua_class) return; - -// lua_pushvalue(L, -1); // copy the object ref - crep->get_table(L); - lua_pushliteral(L, "__finalize"); - lua_gettable(L, -2); - lua_remove(L, -2); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - } - else - { - lua_pushvalue(L, -2); - lua_call(L, 1, 0); - } - - for (std::vector::const_iterator - i = crep->bases().begin(); i != crep->bases().end(); ++i) - { - if (i->base) finalize(L, i->base); - } -} - -void luabind::detail::class_rep::cache_operators(lua_State* L) -{ - m_operator_cache = 0x1; - - for (int i = 0; i < number_of_operators; ++i) - { - get_table(L); - lua_pushstring(L, get_operator_name(i)); - lua_rawget(L, -2); - - if (lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); - - lua_pop(L, 2); - } -} - -bool luabind::detail::class_rep::has_operator_in_lua(lua_State* L, int id) -{ - if ((m_operator_cache & 0x1) == 0) - cache_operators(L); - - const int mask = 1 << (id + 1); - - return (m_operator_cache & mask) != 0; -} diff --git a/luabind/src/create_class.cpp b/luabind/src/create_class.cpp deleted file mode 100644 index 47251ef23..000000000 --- a/luabind/src/create_class.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include - -namespace luabind { namespace detail -{ - namespace - { - // expects two tables on the lua stack: - // 1: destination - // 2: source - void copy_member_table(lua_State* L) - { - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushstring(L, "__init"); - if (lua_equal(L, -1, -3)) - { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __init string - - lua_pushstring(L, "__finalize"); - if (lua_equal(L, -1, -3)) - { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __finalize string - - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - lua_settable(L, -5); - } - } - } - - - int create_class::stage2(lua_State* L) - { - class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); - assert((crep != 0) && "internal error, please report"); - assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); - - #ifndef LUABIND_NO_ERROR_CHECKING - - if (!is_class_rep(L, 1)) - { - lua_pushstring(L, "expected class to derive from or a newline"); - lua_error(L); - } - - #endif - - class_rep* base = static_cast(lua_touserdata(L, 1)); - class_rep::base_info binfo; - - binfo.pointer_offset = 0; - binfo.base = base; - crep->add_base_class(binfo); - - // copy base class members - - crep->get_table(L); - base->get_table(L); - copy_member_table(L); - - crep->get_default_table(L); - base->get_default_table(L); - copy_member_table(L); - - crep->set_type(base->type()); - - return 0; - } - - int create_class::stage1(lua_State* L) - { - - #ifndef LUABIND_NO_ERROR_CHECKING - - if (lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) - { - lua_pushstring(L, "invalid construct, expected class name"); - lua_error(L); - } - - if (std::strlen(lua_tostring(L, 1)) != lua_strlen(L, 1)) - { - lua_pushstring(L, "luabind does not support class names with extra nulls"); - lua_error(L); - } - - #endif - - const char* name = lua_tostring(L, 1); - - void* c = lua_newuserdata(L, sizeof(class_rep)); - new(c) class_rep(L, name); - - // make the class globally available - lua_pushvalue(L, -1); - lua_setglobal(L, name); - - // also add it to the closure as return value - lua_pushcclosure(L, &stage2, 1); - - return 1; - } - -}} - diff --git a/luabind/src/error.cpp b/luabind/src/error.cpp deleted file mode 100644 index 73bbf5c62..000000000 --- a/luabind/src/error.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - - -namespace luabind -{ - - namespace - { - pcall_callback_fun pcall_callback = 0; -#ifdef LUABIND_NO_EXCEPTIONS - error_callback_fun error_callback = 0; - cast_failed_callback_fun cast_failed_callback = 0; -#endif - } - - -#ifdef LUABIND_NO_EXCEPTIONS - - typedef void(*error_callback_fun)(lua_State*); - typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); - - void set_error_callback(error_callback_fun e) - { - error_callback = e; - } - - void set_cast_failed_callback(cast_failed_callback_fun c) - { - cast_failed_callback = c; - } - - error_callback_fun get_error_callback() - { - return error_callback; - } - - cast_failed_callback_fun get_cast_failed_callback() - { - return cast_failed_callback; - } - -#endif - - void set_pcall_callback(pcall_callback_fun e) - { - pcall_callback = e; - } - - pcall_callback_fun get_pcall_callback() - { - return pcall_callback; - } - -} diff --git a/luabind/src/exception_handler.cpp b/luabind/src/exception_handler.cpp deleted file mode 100644 index 555d3858c..000000000 --- a/luabind/src/exception_handler.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright Daniel Wallin 2005. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#define LUABIND_BUILDING - -#include -#include -#include -#include - -#ifndef LUABIND_NO_EXCEPTIONS - -namespace luabind { namespace detail { - -namespace -{ - exception_handler_base* handler_chain = 0; - - void push_exception_string(lua_State* L, char const* exception, char const* what) - { - lua_pushstring(L, exception); - lua_pushstring(L, ": '"); - lua_pushstring(L, what); - lua_pushstring(L, "'"); - lua_concat(L, 4); - } -} - -void exception_handler_base::try_next(lua_State* L) const -{ - if (next) - next->handle(L); - else - throw; -} - -LUABIND_API void handle_exception_aux(lua_State* L) -{ - try - { - if (handler_chain) - handler_chain->handle(L); - else - throw; - } - catch (error const&) - {} - catch (std::logic_error const& e) - { - push_exception_string(L, "std::logic_error", e.what()); - } - catch (std::runtime_error const& e) - { - push_exception_string(L, "std::runtime_error", e.what()); - } - catch (std::exception const& e) - { - push_exception_string(L, "std::exception", e.what()); - } - catch (char const* str) - { - push_exception_string(L, "c-string", str); - } - catch (...) - { - lua_pushstring(L, "Unknown C++ exception"); - } -} - -LUABIND_API void register_exception_handler(exception_handler_base* handler) -{ - if (!handler_chain) handler_chain = handler; - else - { - exception_handler_base* p = handler_chain; - - for (; p->next; p = p->next); - - handler->next = 0; - p->next = handler; - } -} - -}} // namespace luabind::detail - -#endif // LUABIND_NO_EXCEPTIONS diff --git a/luabind/src/function.cpp b/luabind/src/function.cpp deleted file mode 100644 index 20569b2bd..000000000 --- a/luabind/src/function.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#define LUABIND_BUILDING - -#include - -namespace luabind { namespace detail { - -namespace -{ - - int function_destroy(lua_State* L) - { - function_object* fn = *(function_object**)lua_touserdata(L, 1); - delete fn; - return 0; - } - - void push_function_metatable(lua_State* L) - { - lua_pushstring(L, "luabind.function"); - lua_rawget(L, LUA_REGISTRYINDEX); - - if (lua_istable(L, -1)) - return; - - lua_pop(L, 1); - - lua_newtable(L); - - lua_pushstring(L, "__gc"); - lua_pushcclosure(L, &function_destroy, 0); - lua_rawset(L, -3); - - lua_pushstring(L, "luabind.function"); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } - - // A pointer to this is used as a tag value to identify functions exported - // by luabind. - int function_tag = 0; - -} // namespace unnamed - -LUABIND_API bool is_luabind_function(lua_State* L, int index) -{ - if (!lua_getupvalue(L, index, 2)) - return false; - bool result = lua_touserdata(L, -1) == &function_tag; - lua_pop(L, 1); - return result; -} - -namespace -{ - - inline bool is_luabind_function(object const& obj) - { - obj.push(obj.interpreter()); - bool result = detail::is_luabind_function(obj.interpreter(), -1); - lua_pop(obj.interpreter(), 1); - return result; - } - -} // namespace unnamed - -LUABIND_API void add_overload( - object const& context, char const* name, object const& fn) -{ - function_object* f = *touserdata(getupvalue(fn, 1)); - f->name = name; - - if (object overloads = context[name]) - { - if (is_luabind_function(overloads) && is_luabind_function(fn)) - { - f->next = *touserdata(getupvalue(overloads, 1)); - f->keepalive = overloads; - } - } - - context[name] = fn; -} - -LUABIND_API object make_function_aux(lua_State* L, function_object* impl) -{ - void* storage = lua_newuserdata(L, sizeof(function_object*)); - push_function_metatable(L); - *(function_object**)storage = impl; - lua_setmetatable(L, -2); - - lua_pushlightuserdata(L, &function_tag); - lua_pushcclosure(L, impl->entry, 2); - stack_pop pop(L, 1); - - return object(from_stack(L, -1)); -} - -void invoke_context::format_error( - lua_State* L, function_object const* overloads) const -{ - char const* function_name = - overloads->name.empty() ? "" : overloads->name.c_str(); - - if (candidate_index == 0) - { - lua_pushstring(L, "No matching overload found, candidates:\n"); - int count = 0; - for (function_object const* f = overloads; f != 0; f = f->next) - { - if (count != 0) - lua_pushstring(L, "\n"); - f->format_signature(L, function_name); - ++count; - } - lua_concat(L, count * 2); - } - else - { - // Ambiguous - lua_pushstring(L, "Ambiguous, candidates:\n"); - for (int i = 0; i < candidate_index; ++i) - { - if (i != 0) - lua_pushstring(L, "\n"); - candidates[i]->format_signature(L, function_name); - } - lua_concat(L, candidate_index * 2); - } -} - -}} // namespace luabind::detail - diff --git a/luabind/src/inheritance.cpp b/luabind/src/inheritance.cpp deleted file mode 100644 index 2e2ec902a..000000000 --- a/luabind/src/inheritance.cpp +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright Daniel Wallin 2009. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#define LUABIND_BUILDING - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace luabind { namespace detail { - -class_id const class_id_map::local_id_base = - std::numeric_limits::max() / 2; - -namespace -{ - - struct edge - { - edge(class_id target, cast_function cast) - : target(target) - , cast(cast) - {} - - class_id target; - cast_function cast; - }; - - bool operator<(edge const& x, edge const& y) - { - return x.target < y.target; - } - - struct vertex - { - vertex(class_id id) - : id(id) - {} - - class_id id; - std::vector edges; - }; - - typedef std::pair cache_entry; - - class cache - { - public: - static std::ptrdiff_t const unknown; - static std::ptrdiff_t const invalid; - - cache_entry get( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset) const; - - void put( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset - , std::size_t distance, std::ptrdiff_t offset); - - void invalidate(); - - private: - typedef boost::tuple< - class_id, class_id, class_id, std::ptrdiff_t> key_type; - typedef std::map map_type; - map_type m_cache; - }; - - std::ptrdiff_t const cache::unknown = - std::numeric_limits::max(); - std::ptrdiff_t const cache::invalid = cache::unknown - 1; - - cache_entry cache::get( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset) const - { - map_type::const_iterator i = m_cache.find( - key_type(src, target, dynamic_id, object_offset)); - return i != m_cache.end() ? i->second : cache_entry(unknown, -1); - } - - void cache::put( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset, std::size_t distance, std::ptrdiff_t offset) - { - m_cache.insert(std::make_pair( - key_type(src, target, dynamic_id, object_offset) - , cache_entry(offset, distance) - )); - } - - void cache::invalidate() - { - m_cache.clear(); - } - -} // namespace unnamed - -class cast_graph::impl -{ -public: - std::pair cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const; - void insert(class_id src, class_id target, cast_function cast); - -private: - std::vector m_vertices; - mutable cache m_cache; -}; - -namespace -{ - - struct queue_entry - { - queue_entry(void* p, class_id vertex_id, int distance) - : p(p) - , vertex_id(vertex_id) - , distance(distance) - {} - - void* p; - class_id vertex_id; - int distance; - }; - -} // namespace unnamed - -std::pair cast_graph::impl::cast( - void* const p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const -{ - if (src == target) - return std::make_pair(p, 0); - - if (src >= m_vertices.size() || target >= m_vertices.size()) - return std::pair((void*)0, -1); - - std::ptrdiff_t const object_offset = - (char const*)dynamic_ptr - (char const*)p; - - cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); - - if (cached.first != cache::unknown) - { - if (cached.first == cache::invalid) - return std::pair((void*)0, -1); - return std::make_pair((char*)p + cached.first, cached.second); - } - - std::queue q; - q.push(queue_entry(p, src, 0)); - - boost::dynamic_bitset<> visited(m_vertices.size()); - - while (!q.empty()) - { - queue_entry const qe = q.front(); - q.pop(); - - visited[qe.vertex_id] = true; - vertex const& v = m_vertices[qe.vertex_id]; - - if (v.id == target) - { - m_cache.put( - src, target, dynamic_id, object_offset - , qe.distance, (char*)qe.p - (char*)p - ); - - return std::make_pair(qe.p, qe.distance); - } - - BOOST_FOREACH(edge const& e, v.edges) - { - if (visited[e.target]) - continue; - if (void* casted = e.cast(qe.p)) - q.push(queue_entry(casted, e.target, qe.distance + 1)); - } - } - - m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); - - return std::pair((void*)0, -1); -} - -void cast_graph::impl::insert( - class_id src, class_id target, cast_function cast) -{ - class_id const max_id = std::max(src, target); - - if (max_id >= m_vertices.size()) - { - m_vertices.reserve(max_id + 1); - for (class_id i = m_vertices.size(); i < max_id + 1; ++i) - m_vertices.push_back(vertex(i)); - } - - std::vector& edges = m_vertices[src].edges; - - std::vector::iterator i = std::lower_bound( - edges.begin(), edges.end(), edge(target, 0) - ); - - if (i == edges.end() || i->target != target) - { - edges.insert(i, edge(target, cast)); - m_cache.invalidate(); - } -} - -std::pair cast_graph::cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const -{ - return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); -} - -void cast_graph::insert(class_id src, class_id target, cast_function cast) -{ - m_impl->insert(src, target, cast); -} - -cast_graph::cast_graph() - : m_impl(new impl) -{} - -cast_graph::~cast_graph() -{} - -LUABIND_API class_id allocate_class_id(type_id const& cls) -{ - typedef std::map map_type; - - static map_type registered; - static class_id id = 0; - - std::pair inserted = registered.insert( - std::make_pair(cls, id)); - - if (inserted.second) - ++id; - - return inserted.first->second; -} - -}} // namespace luabind::detail diff --git a/luabind/src/link_compatibility.cpp b/luabind/src/link_compatibility.cpp deleted file mode 100644 index 515e0e392..000000000 --- a/luabind/src/link_compatibility.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -namespace luabind { namespace detail -{ - -#ifdef LUABIND_NOT_THREADSAFE - void not_threadsafe_defined_conflict() {} -#else - void not_threadsafe_not_defined_conflict() {} -#endif - -#ifdef LUABIND_NO_ERROR_CHECKING - void no_error_checking_defined_conflict() {} -#else - void no_error_checking_not_defined_conflict() {} -#endif - -}} - diff --git a/luabind/src/object_rep.cpp b/luabind/src/object_rep.cpp deleted file mode 100644 index afc6d9800..000000000 --- a/luabind/src/object_rep.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include -#include -#include - -namespace luabind { namespace detail -{ - - // dest is a function that is called to delete the c++ object this struct holds - object_rep::object_rep(instance_holder* instance, class_rep* crep) - : m_instance(instance) - , m_classrep(crep) - , m_dependency_cnt(0) - {} - - object_rep::~object_rep() - { - if (!m_instance) - return; - m_instance->~instance_holder(); - deallocate(m_instance); - } - - void object_rep::add_dependency(lua_State* L, int index) - { - assert(m_dependency_cnt < sizeof(object_rep)); - - void* key = (char*)this + m_dependency_cnt; - - lua_pushlightuserdata(L, key); - lua_pushvalue(L, index); - lua_rawset(L, LUA_REGISTRYINDEX); - - ++m_dependency_cnt; - } - - void object_rep::release_dependency_refs(lua_State* L) - { - for (std::size_t i = 0; i < m_dependency_cnt; ++i) - { - void* key = (char*)this + i; - lua_pushlightuserdata(L, key); - lua_pushnil(L); - lua_rawset(L, LUA_REGISTRYINDEX); - } - } - - int destroy_instance(lua_State* L) - { - object_rep* instance = static_cast(lua_touserdata(L, 1)); - - lua_pushstring(L, "__finalize"); - lua_gettable(L, 1); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - } - else - { - lua_pushvalue(L, 1); - lua_call(L, 1, 0); - } - - instance->release_dependency_refs(L); - instance->~object_rep(); - return 0; - } - - namespace - { - - int set_instance_value(lua_State* L) - { - lua_getfenv(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - lua_replace(L, -3); - lua_pop(L, 1); - } - - if (lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "set" function and call it. - lua_getupvalue(L, -1, 2); - - if (lua_isnil(L, -1)) - { - lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); - lua_error(L); - } - - lua_pushvalue(L, 1); - lua_pushvalue(L, 3); - lua_call(L, 2, 0); - return 0; - } - - lua_pop(L, 1); - - if (!lua_getmetatable(L, 4)) - { - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfenv(L, 1); - lua_pushvalue(L, 4); - lua_setmetatable(L, -2); - } - else - { - lua_pop(L, 1); - } - - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - lua_rawset(L, -3); - - return 0; - } - - int get_instance_value(lua_State* L) - { - lua_getfenv(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - } - - if (lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "get" function and call it. - lua_getupvalue(L, -1, 1); - lua_pushvalue(L, 1); - lua_call(L, 1, 1); - } - - return 1; - } - - int dispatch_operator(lua_State* L) - { - for (int i = 0; i < 2; ++i) - { - if (get_instance(L, 1 + i)) - { - int nargs = lua_gettop(L); - - lua_pushvalue(L, lua_upvalueindex(1)); - lua_gettable(L, 1 + i); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - continue; - } - - lua_insert(L, 1); // move the function to the bottom - - nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; - - if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil - lua_remove(L, 3); - - lua_call(L, nargs, 1); - return 1; - } - } - - lua_pop(L, lua_gettop(L)); - lua_pushstring(L, "No such operator defined"); - lua_error(L); - - return 0; - } - - } // namespace unnamed - - LUABIND_API void push_instance_metatable(lua_State* L) - { - lua_newtable(L); - - // just indicate that this really is a class and not just - // any user data - lua_pushboolean(L, 1); - lua_setfield(L, -2, "__luabind_class"); - - // This is used as a tag to determine if a userdata is a luabind - // instance. We use a numeric key and a cclosure for fast comparision. - lua_pushnumber(L, 1); - lua_pushcclosure(L, get_instance_value, 0); - lua_rawset(L, -3); - - lua_pushcclosure(L, destroy_instance, 0); - lua_setfield(L, -2, "__gc"); - - lua_pushcclosure(L, get_instance_value, 0); - lua_setfield(L, -2, "__index"); - - lua_pushcclosure(L, set_instance_value, 0); - lua_setfield(L, -2, "__newindex"); - - for (int op = 0; op < number_of_operators; ++op) - { - lua_pushstring(L, get_operator_name(op)); - lua_pushvalue(L, -1); - lua_pushboolean(L, op == op_unm || op == op_len); - lua_pushcclosure(L, &dispatch_operator, 2); - lua_settable(L, -3); - } - } - - LUABIND_API object_rep* get_instance(lua_State* L, int index) - { - object_rep* result = static_cast(lua_touserdata(L, index)); - - if (!result || !lua_getmetatable(L, index)) - return 0; - - lua_rawgeti(L, -1, 1); - - if (lua_tocfunction(L, -1) != &get_instance_value) - result = 0; - - lua_pop(L, 2); - - return result; - } - - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) - { - void* storage = lua_newuserdata(L, sizeof(object_rep)); - object_rep* result = new (storage) object_rep(0, cls); - cls->get_table(L); - lua_setfenv(L, -2); - lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); - lua_setmetatable(L, -2); - return result; - } - -}} - diff --git a/luabind/src/open.cpp b/luabind/src/open.cpp deleted file mode 100644 index ec8e4ff64..000000000 --- a/luabind/src/open.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include -#include -#include - -namespace luabind { - -namespace -{ - - int make_property(lua_State* L) - { - int args = lua_gettop(L); - - if (args == 0 || args > 2) - { - lua_pushstring(L, "make_property() called with wrong number of arguments."); - lua_error(L); - } - - if (args == 1) - lua_pushnil(L); - - lua_pushcclosure(L, &detail::property_tag, 2); - return 1; - } - - int main_thread_tag; - - int deprecated_super(lua_State* L) - { - lua_pushstring(L, - "DEPRECATION: 'super' has been deprecated in favor of " - "directly calling the base class __init() function. " - "This error can be disabled by calling 'luabind::disable_super_deprecation()'." - ); - lua_error(L); - - return 0; - } - - int destroy_class_id_map(lua_State* L) - { - detail::class_id_map* m = - (detail::class_id_map*)lua_touserdata(L, 1); - m->~class_id_map(); - return 0; - } - - int destroy_cast_graph(lua_State* L) - { - detail::cast_graph* g = - (detail::cast_graph*)lua_touserdata(L, 1); - g->~cast_graph(); - return 0; - } - - int destroy_class_map(lua_State* L) - { - detail::class_map* m = - (detail::class_map*)lua_touserdata(L, 1); - m->~class_map(); - return 0; - } - -} // namespace unnamed - - LUABIND_API lua_State* get_main_thread(lua_State* L) - { - lua_pushlightuserdata(L, &main_thread_tag); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_State* result = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - - if (!result) - throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); - - return result; - } - - LUABIND_API void open(lua_State* L) - { - bool is_main_thread = lua_pushthread(L) == 1; - lua_pop(L, 1); - - if (!is_main_thread) - { - throw std::runtime_error( - "luabind::open() must be called with the main thread " - "lua_State*" - ); - } - - if (detail::class_registry::get_registry(L)) - return; - - lua_pushstring(L, "__luabind_classes"); - detail::class_registry* r = static_cast( - lua_newuserdata(L, sizeof(detail::class_registry))); - - // set gc metatable - lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , detail::garbage_collector_s< - detail::class_registry - >::apply - , 0); - - lua_settable(L, -3); - lua_setmetatable(L, -2); - - new(r) detail::class_registry(L); - lua_settable(L, LUA_REGISTRYINDEX); - - lua_pushstring(L, "__luabind_class_id_map"); - void* classes_storage = lua_newuserdata(L, sizeof(detail::class_id_map)); - detail::class_id_map* class_ids = new (classes_storage) detail::class_id_map; - (void)class_ids; - - lua_newtable(L); - lua_pushcclosure(L, &destroy_class_id_map, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - lua_pushstring(L, "__luabind_cast_graph"); - void* cast_graph_storage = lua_newuserdata( - L, sizeof(detail::cast_graph)); - detail::cast_graph* graph = new (cast_graph_storage) detail::cast_graph; - (void)graph; - - lua_newtable(L); - lua_pushcclosure(L, &destroy_cast_graph, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - lua_pushstring(L, "__luabind_class_map"); - void* class_map_storage = lua_newuserdata( - L, sizeof(detail::class_map)); - detail::class_map* classes = new (class_map_storage) detail::class_map; - (void)classes; - - lua_newtable(L); - lua_pushcclosure(L, &destroy_class_map, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - // add functions (class, cast etc...) - lua_pushcclosure(L, detail::create_class::stage1, 0); - lua_setglobal(L, "class"); - - lua_pushcclosure(L, &make_property, 0); - lua_setglobal(L, "property"); - - lua_pushlightuserdata(L, &main_thread_tag); - lua_pushlightuserdata(L, L); - lua_rawset(L, LUA_REGISTRYINDEX); - - lua_pushcclosure(L, &deprecated_super, 0); - lua_setglobal(L, "super"); - } - -} // namespace luabind - diff --git a/luabind/src/pcall.cpp b/luabind/src/pcall.cpp deleted file mode 100644 index 1bf642531..000000000 --- a/luabind/src/pcall.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include -#include -#include - -namespace luabind { namespace detail -{ - int pcall(lua_State *L, int nargs, int nresults) - { - pcall_callback_fun e = get_pcall_callback(); - int en = 0; - if ( e ) - { - int base = lua_gettop(L) - nargs; - lua_pushcfunction(L, e); - lua_insert(L, base); // push pcall_callback under chunk and args - en = base; - } - int result = lua_pcall(L, nargs, nresults, en); - if ( en ) - lua_remove(L, en); // remove pcall_callback - return result; - } - - int resume_impl(lua_State *L, int nargs, int) - { -#if LUA_VERSION_NUM >= 502 - int res = lua_resume(L, NULL, nargs); -#else - int res = lua_resume(L, nargs); -#endif - -#if LUA_VERSION_NUM >= 501 - // Lua 5.1 added LUA_YIELD as a possible return value, - // this was causing crashes, because the caller expects 0 on success. - return (res == LUA_YIELD) ? 0 : res; -#else - return res; -#endif - } - -}} diff --git a/luabind/src/scope.cpp b/luabind/src/scope.cpp deleted file mode 100644 index 52bd132f9..000000000 --- a/luabind/src/scope.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include -#include -#include -#include -#include - -namespace luabind { namespace detail { - - registration::registration() - : m_next(0) - { - } - - registration::~registration() - { - delete m_next; - } - - } // namespace detail - - scope::scope() - : m_chain(0) - { - } - - scope::scope(std::auto_ptr reg) - : m_chain(reg.release()) - { - } - - scope::scope(scope const& other) - : m_chain(other.m_chain) - { - const_cast(other).m_chain = 0; - } - - scope& scope::operator=(scope const& other_) - { - delete m_chain; - m_chain = other_.m_chain; - const_cast(other_).m_chain = 0; - return *this; - } - - scope::~scope() - { - delete m_chain; - } - - scope& scope::operator,(scope s) - { - if (!m_chain) - { - m_chain = s.m_chain; - s.m_chain = 0; - return *this; - } - - for (detail::registration* c = m_chain;; c = c->m_next) - { - if (!c->m_next) - { - c->m_next = s.m_chain; - s.m_chain = 0; - break; - } - } - - return *this; - } - - void scope::register_(lua_State* L) const - { - for (detail::registration* r = m_chain; r != 0; r = r->m_next) - { - LUABIND_CHECK_STACK(L); - r->register_(L); - } - } - -} // namespace luabind - -namespace luabind { - - namespace { - - struct lua_pop_stack - { - lua_pop_stack(lua_State* L) - : m_state(L) - { - } - - ~lua_pop_stack() - { - lua_pop(m_state, 1); - } - - lua_State* m_state; - }; - - } // namespace unnamed - - module_::module_(lua_State* L, char const* name = 0) - : m_state(L) - , m_name(name) - { - } - - void module_::operator[](scope s) - { - if (m_name) - { - lua_getglobal(m_state, m_name); - - if (!lua_istable(m_state, -1)) - { - lua_pop(m_state, 1); - - lua_newtable(m_state); - lua_pushvalue(m_state, -1); - lua_setglobal(m_state, m_name); - } - } - else - { - lua_pushglobaltable(m_state); - } - - lua_pop_stack guard(m_state); - - s.register_(m_state); - } - - struct namespace_::registration_ : detail::registration - { - registration_(char const* name) - : m_name(name) - { - } - - void register_(lua_State* L) const - { - LUABIND_CHECK_STACK(L); - assert(lua_gettop(L) >= 1); - - lua_pushstring(L, m_name); - lua_gettable(L, -2); - - detail::stack_pop p(L, 1); // pops the table on exit - - if (!lua_istable(L, -1)) - { - lua_pop(L, 1); - - lua_newtable(L); - lua_pushstring(L, m_name); - lua_pushvalue(L, -2); - lua_settable(L, -4); - } - - m_scope.register_(L); - } - - char const* m_name; - scope m_scope; - }; - - namespace_::namespace_(char const* name) - : scope(std::auto_ptr( - m_registration = new registration_(name))) - { - } - - namespace_& namespace_::operator[](scope s) - { - m_registration->m_scope.operator,(s); - return *this; - } - -} // namespace luabind - diff --git a/luabind/src/stack_content_by_name.cpp b/luabind/src/stack_content_by_name.cpp deleted file mode 100644 index 38b5c691d..000000000 --- a/luabind/src/stack_content_by_name.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include - -using namespace luabind::detail; - -std::string luabind::detail::stack_content_by_name(lua_State* L, int start_index) -{ - std::string ret; - int top = lua_gettop(L); - for (int i = start_index; i <= top; ++i) - { - object_rep* obj = get_instance(L, i); - class_rep* crep = is_class_rep(L, i)?(class_rep*)lua_touserdata(L, i):0; - if (obj == 0 && crep == 0) - { - int type = lua_type(L, i); - ret += lua_typename(L, type); - } - else if (obj) - { - if (obj->is_const()) ret += "const "; - ret += obj->crep()->name(); - } - else if (crep) - { - ret += "<"; - ret += crep->name(); - ret += ">"; - } - if (i < top) ret += ", "; - } - return ret; -} - diff --git a/luabind/src/weak_ref.cpp b/luabind/src/weak_ref.cpp deleted file mode 100644 index 245b26c2e..000000000 --- a/luabind/src/weak_ref.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include - -#include - -#include -#include -#include - -namespace luabind { - -namespace -{ - - int weak_table_tag; - -} // namespace unnamed - -LUABIND_API void get_weak_table(lua_State* L) -{ - lua_pushlightuserdata(L, &weak_table_tag); - lua_rawget(L, LUA_REGISTRYINDEX); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_newtable(L); - // metatable - lua_newtable(L); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "v"); - lua_rawset(L, -3); - // set metatable - lua_setmetatable(L, -2); - - lua_pushlightuserdata(L, &weak_table_tag); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } -} - -} // namespace luabind - -namespace luabind -{ - - struct weak_ref::impl - { - impl(lua_State* main, lua_State* s, int index) - : count(0) - , state(main) - , ref(0) - { - get_weak_table(s); - lua_pushvalue(s, index); - ref = luaL_ref(s, -2); - lua_pop(s, 1); - } - - ~impl() - { - get_weak_table(state); - luaL_unref(state, -1, ref); - lua_pop(state, 1); - } - - int count; - lua_State* state; - int ref; - }; - - weak_ref::weak_ref() - : m_impl(0) - { - } - - weak_ref::weak_ref(lua_State* main, lua_State* L, int index) - : m_impl(new impl(main, L, index)) - { - m_impl->count = 1; - } - - weak_ref::weak_ref(weak_ref const& other) - : m_impl(other.m_impl) - { - if (m_impl) ++m_impl->count; - } - - weak_ref::~weak_ref() - { - if (m_impl && --m_impl->count == 0) - { - delete m_impl; - } - } - - weak_ref& weak_ref::operator=(weak_ref const& other) - { - weak_ref(other).swap(*this); - return *this; - } - - void weak_ref::swap(weak_ref& other) - { - std::swap(m_impl, other.m_impl); - } - - int weak_ref::id() const - { - assert(m_impl); - return m_impl->ref; - } - - // L may not be the same pointer as - // was used when creating this reference - // since it may be a thread that shares - // the same globals table. - void weak_ref::get(lua_State* L) const - { - assert(m_impl); - assert(L); - get_weak_table(L); - lua_rawgeti(L, -1, m_impl->ref); - lua_remove(L, -2); - } - - lua_State* weak_ref::state() const - { - assert(m_impl); - return m_impl->state; - } - -} // namespace luabind - diff --git a/luabind/src/wrapper_base.cpp b/luabind/src/wrapper_base.cpp deleted file mode 100644 index 9fb54a5db..000000000 --- a/luabind/src/wrapper_base.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// 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. - -#define LUABIND_BUILDING - -#include -#include -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - LUABIND_API void do_call_member_selection(lua_State* L, char const* name) - { - object_rep* obj = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); // pop self - - obj->crep()->get_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table - - if (!is_luabind_function(L, -1)) - return; - - // this (usually) means the function has not been - // overridden by lua, call the default implementation - lua_pop(L, 1); - obj->crep()->get_default_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table - } -}} diff --git a/utils/TaskMaster/activities.cpp b/utils/TaskMaster/activities.cpp index 4f2d211f4..4cbb2a1b5 100644 --- a/utils/TaskMaster/activities.cpp +++ b/utils/TaskMaster/activities.cpp @@ -127,7 +127,7 @@ void MainFrame::NewActivity(wxCommandEvent& event) if(mMysql){ char * mActQuery = 0; - MakeAnyLenString(&mActQuery, "INSERT INTO `activities` (`taskid`,`activityid`,`step`,`activitytype`,`text1`,`text2`,`text3`,`goalid`,`goalmethod`,`goalcount`,`delivertonpc`,`zoneid`,`optional`) VALUES (%u,%u,%u,%u,'%s','%s','%s',%u,%u,%u,%u,%u,%u)", + MakeAnyLenString(&mActQuery, "INSERT INTO `task_activities` (`taskid`,`activityid`,`step`,`activitytype`,`text1`,`text2`,`text3`,`goalid`,`goalmethod`,`goalcount`,`delivertonpc`,`zoneid`,`optional`) VALUES (%u,%u,%u,%u,'%s','%s','%s',%u,%u,%u,%u,%u,%u)", newAct.id, newAct.activityId, newAct.step, newAct.activityType, newAct.text1, newAct.text2, newAct.text3, newAct.goalid, newAct.goalmethod, newAct.goalcount, newAct.deliverToNpc, newAct.zoneid, newAct.optional ); mErrorLog->Log(eqEmuLogSQL, "%s", mActQuery); @@ -167,7 +167,7 @@ void MainFrame::DeleteActivity(wxCommandEvent& event) { if(mMysql){ char * mActQuery = 0; - MakeAnyLenString(&mActQuery, "DELETE FROM activities WHERE taskid=%u AND activityid=%u",selAct->id, selAct->activityid); + MakeAnyLenString(&mActQuery, "DELETE FROM `task_activities` WHERE taskid=%u AND activityid=%u",selAct->id, selAct->activityid); mErrorLog->Log(eqEmuLogSQL, "%s", mActQuery); if (mysql_query(mMysql, mActQuery)) { mErrorLog->Log(eqEmuLogBoth, "MySQL Error: %s", mysql_error(mMysql)); @@ -554,7 +554,7 @@ void MainFrame::SaveActivity(wxCommandEvent& event) if(canUpdate) { char * mQuery = 0; - MakeAnyLenString(&mQuery, "UPDATE activities SET step=%u, activitytype=%u, text1='%s', text2='%s', text3='%s', goalid=%u, goalmethod=%u,goalcount=%u, delivertonpc=%u, zoneid=%u, optional=%u WHERE taskid=%u AND activityid =%u", + MakeAnyLenString(&mQuery, "UPDATE `task_activities` SET step=%u, activitytype=%u, text1='%s', text2='%s', text3='%s', goalid=%u, goalmethod=%u,goalcount=%u, delivertonpc=%u, zoneid=%u, optional=%u WHERE taskid=%u AND activityid =%u", ourAct.step, ourAct.activityType, MakeStringSQLSafe(ourAct.text1).mb_str(), MakeStringSQLSafe(ourAct.text2).mb_str(), MakeStringSQLSafe(ourAct.text3).mb_str(), ourAct.goalid, ourAct.goalmethod, ourAct.goalcount, ourAct.deliverToNpc, ourAct.zoneid, ourAct.optional, ourAct.id, ourAct.activityId ); mErrorLog->Log(eqEmuLogSQL, "%s", mQuery); if (mysql_query(mMysql, mQuery)) { @@ -565,14 +565,14 @@ void MainFrame::SaveActivity(wxCommandEvent& event) else { char * mQuery = 0; - MakeAnyLenString(&mQuery, "DELETE FROM activities WHERE taskid=%u AND activityid=%u", ourAct.id, delid); + MakeAnyLenString(&mQuery, "DELETE FROM `task_activities` WHERE taskid=%u AND activityid=%u", ourAct.id, delid); mErrorLog->Log(eqEmuLogSQL, "%s", mQuery); if (mysql_query(mMysql, mQuery)) { mErrorLog->Log(eqEmuLogBoth, "MySQL Error: %s", mysql_error(mMysql)); return; } - MakeAnyLenString(&mQuery, "INSERT INTO `activities` (`taskid`,`activityid`,`step`,`activitytype`,`text1`,`text2`,`text3`,`goalid`,`goalmethod`,`goalcount`,`delivertonpc`,`zoneid`,`optional`) VALUES (%u,%u,%u,%u,'%s','%s','%s',%u,%u,%u,%u,%u,%u)", + MakeAnyLenString(&mQuery, "INSERT INTO `task_activities` (`taskid`,`activityid`,`step`,`activitytype`,`text1`,`text2`,`text3`,`goalid`,`goalmethod`,`goalcount`,`delivertonpc`,`zoneid`,`optional`) VALUES (%u,%u,%u,%u,'%s','%s','%s',%u,%u,%u,%u,%u,%u)", ourAct.id, ourAct.activityId, ourAct.step, ourAct.activityType, MakeStringSQLSafe(ourAct.text1).mb_str(), MakeStringSQLSafe(ourAct.text2).mb_str(), MakeStringSQLSafe(ourAct.text3).mb_str(), ourAct.goalid, ourAct.goalmethod, ourAct.goalcount, ourAct.deliverToNpc, ourAct.zoneid, ourAct.optional); mErrorLog->Log(eqEmuLogSQL, "%s", mQuery); if (mysql_query(mMysql, mQuery)) { diff --git a/utils/TaskMaster/base_utility.cpp b/utils/TaskMaster/base_utility.cpp index 96dcf9e3a..d507bdb89 100644 --- a/utils/TaskMaster/base_utility.cpp +++ b/utils/TaskMaster/base_utility.cpp @@ -241,44 +241,43 @@ bool MainFrame::LoadGoals() return true; } -bool MainFrame::LoadActivities() -{ - if(mMysql){ +bool MainFrame::LoadActivities() { + if (mMysql) { mErrorLog->Log(eqEmuLogBoth, "Loading Activities..."); unsigned int activitiesLoaded = 0; - MYSQL_RES *res; - MYSQL_ROW row; + MYSQL_RES *res; + MYSQL_ROW row; - if (mysql_query(mMysql, "SELECT taskid, activityid, step, activitytype, text1, text2, text3, goalid, goalmethod, goalcount, delivertonpc, zoneid, optional FROM activities")) { + if (mysql_query(mMysql, + "SELECT taskid, activityid, step, activitytype, text1, text2, text3, goalid, goalmethod, goalcount, delivertonpc, zoneid, optional FROM `task_activities`")) { mErrorLog->Log(eqEmuLogBoth, "MySQL Connection Error: %s", mysql_error(mMysql)); return false; } - res = mysql_use_result(mMysql); - while ((row = mysql_fetch_row(res)) != NULL){ + res = mysql_use_result(mMysql); + while ((row = mysql_fetch_row(res)) != NULL) { eqtask_activities newAL; - newAL.id = atoi(row[0]); - newAL.activityId = atoi(row[1]); - newAL.step = atoi(row[2]); + newAL.id = atoi(row[0]); + newAL.activityId = atoi(row[1]); + newAL.step = atoi(row[2]); newAL.activityType = atoi(row[3]); strcpy(newAL.text1, row[4]); strcpy(newAL.text2, row[5]); strcpy(newAL.text3, row[6]); - newAL.goalid = atoi(row[7]); - newAL.goalmethod = atoi(row[8]); - newAL.goalcount = atoi(row[9]); + newAL.goalid = atoi(row[7]); + newAL.goalmethod = atoi(row[8]); + newAL.goalcount = atoi(row[9]); newAL.deliverToNpc = atoi(row[10]); - newAL.zoneid = atoi(row[11]); - newAL.optional = atoi(row[12]) ? true : false; + newAL.zoneid = atoi(row[11]); + newAL.optional = atoi(row[12]) ? true : false; taskActivitiesList.push_back(newAL); activitiesLoaded++; } mErrorLog->Log(eqEmuLogBoth, "%u Successfully Loaded Activities", activitiesLoaded); mysql_free_result(res); - } - else{ + } else { mErrorLog->Log(eqEmuLogBoth, "Mysql connection did not exist for activity load."); return false; } diff --git a/utils/patches/patch_RoF.conf b/utils/patches/patch_RoF.conf index b348ea1ad..9467ab337 100644 --- a/utils/patches/patch_RoF.conf +++ b/utils/patches/patch_RoF.conf @@ -562,6 +562,7 @@ OP_AvaliableTask=0x2bf8 # Was 0x2377 OP_TaskHistoryRequest=0x6cf6 OP_TaskHistoryReply=0x25eb OP_DeclineAllTasks=0x0000 +OP_TaskRequestTimer=0x4b76 # Title opcodes OP_NewTitlesAvailable=0x45d1 diff --git a/utils/patches/patch_RoF2.conf b/utils/patches/patch_RoF2.conf index 9bd507bc1..f410a3193 100644 --- a/utils/patches/patch_RoF2.conf +++ b/utils/patches/patch_RoF2.conf @@ -567,6 +567,7 @@ OP_AvaliableTask=0x36e8 OP_TaskHistoryRequest=0x5f1c OP_TaskHistoryReply=0x3d05 OP_DeclineAllTasks=0x0000 +OP_TaskRequestTimer=0x7a48 # Title opcodes OP_NewTitlesAvailable=0x0d32 diff --git a/utils/patches/patch_SoD.conf b/utils/patches/patch_SoD.conf index ab8267a8a..d836c6360 100644 --- a/utils/patches/patch_SoD.conf +++ b/utils/patches/patch_SoD.conf @@ -533,6 +533,9 @@ OP_TaskHistoryRequest=0x29d7 # C OP_TaskHistoryReply=0x3d2a # C OP_CancelTask=0x726b # C OP_DeclineAllTasks=0x0000 # +OP_TaskRequestTimer=0x2e70 + + OP_Shroud=0x6d1f OP_ShroudRemove=0x17f6 OP_ShroudUnknown1=0x169a diff --git a/utils/patches/patch_SoF.conf b/utils/patches/patch_SoF.conf index 6360617a2..a10715918 100644 --- a/utils/patches/patch_SoF.conf +++ b/utils/patches/patch_SoF.conf @@ -509,6 +509,7 @@ OP_TaskAddPlayer=0x5d1d OP_TaskRemovePlayer=0x516f OP_TaskPlayerList=0x0ad6 OP_TaskQuit=0x2c8c +OP_TaskRequestTimer=0x0b08 #Title opcodes OP_NewTitlesAvailable=0x179c # diff --git a/utils/patches/patch_Titanium.conf b/utils/patches/patch_Titanium.conf index 27aa18376..9a7e1e800 100644 --- a/utils/patches/patch_Titanium.conf +++ b/utils/patches/patch_Titanium.conf @@ -474,6 +474,7 @@ OP_TaskAddPlayer=0x6bc4 OP_TaskRemovePlayer=0x37b9 OP_TaskPlayerList=0x3961 OP_TaskQuit=0x35dd +OP_TaskRequestTimer=0x6a1d #task complete related: 0x0000 (24 bytes), 0x0000 (8 bytes), 0x0000 (4 bytes) diff --git a/utils/patches/patch_UF.conf b/utils/patches/patch_UF.conf index c08edbca3..71966dcbb 100644 --- a/utils/patches/patch_UF.conf +++ b/utils/patches/patch_UF.conf @@ -556,6 +556,7 @@ OP_TaskHistoryRequest=0x547c # C OP_TaskHistoryReply=0x4524 # C OP_CancelTask=0x3bf5 # C OP_DeclineAllTasks=0x0000 # +OP_TaskRequestTimer=0x719e # Title opcodes OP_NewTitlesAvailable=0x4b49 # C diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 8921cf89f..9201a9e27 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -1546,9 +1546,9 @@ sub map_files_fetch_bulk{ ); for my $file (@files) { $destination_file = $file; - $destination_file =~s/maps\/EQEmuMaps-master\/maps\///g; + $destination_file =~s/maps\/EQEmuMaps-master\///g; print "[Install] Installing :: " . $destination_file . "\n"; - copy_file($file, "maps/" . $new_file); + copy_file($file, "maps/" . $destination_file); } print "[Install] Fetched Latest Maps\n"; @@ -2396,4 +2396,4 @@ sub quest_heading_convert { print get_mysql_result("INSERT INTO `variables` (varname, value, information, ts) VALUES ('new_heading_conversion', 'true', 'Script ran against quests folder to convert new heading values', NOW())"); print "Total matches: " . $total_matches . "\n"; -} \ No newline at end of file +} diff --git a/utils/scripts/linux_installer/install.sh b/utils/scripts/linux_installer/install.sh index bffa2d939..8f6f2f4d4 100644 --- a/utils/scripts/linux_installer/install.sh +++ b/utils/scripts/linux_installer/install.sh @@ -120,6 +120,7 @@ if [[ "$OS" == "Debian" ]]; then apt-get $apt_options install libsodium-dev apt-get $apt_options install libsodium18 apt-get $apt_options install libjson-perl + apt-get $apt_options install libssl-dev # Install libsodium wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium-dev_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium-dev.deb diff --git a/utils/scripts/lua-doc-parser.pl b/utils/scripts/lua-doc-parser.pl new file mode 100644 index 000000000..a5608944a --- /dev/null +++ b/utils/scripts/lua-doc-parser.pl @@ -0,0 +1,241 @@ +#!/usr/bin/perl + +# Author: Akkadius +# @file: lua-doc-parser.pl +# @description: Script meant to parse the source code to build the LUA API list + +use File::Find; +use Data::Dumper; + +sub usage() { + print "Usage:\n"; + print " --client - Prints methods for just client class methods\n"; + print " --mob - Prints methods for just mob class methods\n"; + print " --npc - Prints methods for just npc class methods\n"; + print " --entity - Prints methods for just entity class methods\n"; + print " --entity_list - Prints methods for just entity_list class methods\n"; + print " --door - Prints methods for just door class methods\n"; + print " --object - Prints methods for just object class methods\n"; + print " --group - Prints methods for just group class methods\n"; + print " --raid - Prints methods for just raid class methods\n"; + print " --item - Prints methods for just item class methods\n"; + print " --iteminst - Prints methods for just iteminst class methods\n"; + print " --inventory - Prints methods for just inventory class methods\n"; + print " --corpse - Prints methods for just corpse class methods\n"; + print " --hate_entry - Prints methods for just hate_entry class methods\n"; + print " --quest - Prints methods for just quest class methods\n"; + print " --spell - Prints methods for just spell class methods\n"; + print " --spawn - Prints methods for just spawn class methods\n"; + print " --packet - Prints methods for just packet class methods\n"; + print " --stat_bonuses - Prints methods for just stat_bonuses class methods\n"; + print " --all - Prints methods for all classes\n"; + exit(1); +} + +if($#ARGV < 0) { + usage(); +} + +#::: Open File +my $filename = 'lua-api.md'; +open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + +my $export = $ARGV[0]; +$export=~s/--//g; + +my $export_file_search = $export; + +if ($export eq "quest") { + $export_file_search = "lua_general"; +} + +my @files; +my $start_dir = "zone/"; +find( + sub { push @files, $File::Find::name unless -d; }, + $start_dir +); +for my $file (@files) { + + #::: Skip non lua.cpp files + if($file!~/lua_/i || $file!~/cpp/i){ + next; + } + + #::: If we are specifying a specific class type, skip everything else + if ($export ne "all" && $export ne "") { + if ($file!~/$export_file_search\.cpp/i) { + next; + } + } + + @methods = (); + $split_key = ""; + $object_prefix = ""; + + #::: Client Export + if ($export=~/all|client/i && $file=~/_client/i) { + $split_key = "Client::"; + $object_prefix = "client:"; + } + + #::: Mob Export + if ($export=~/all|mob/i && $file=~/_mob/i) { + $split_key = "Mob::"; + $object_prefix = "mob:"; + } + + #::: NPC Export + if ($export=~/all|npc/i && $file=~/_npc/i) { + $split_key = "NPC::"; + $object_prefix = "npc:"; + } + + #::: Object Export + if ($export=~/all|object/i && $file=~/_object/i) { + $split_key = "Object::"; + $object_prefix = "object:"; + } + + #::: Door Export + if ($export=~/all|door/i && $file=~/_door/i) { + $split_key = "Door::"; + $object_prefix = "door:"; + } + + #::: Entity Export + if ($export=~/all|entity/i && $file=~/_entity/i) { + $split_key = "Entity::"; + $object_prefix = "entity:"; + } + + #::: Entity List Export + if ($export=~/all|entity_list/i && $file=~/_entity_list/i) { + $split_key = "EntityList::"; + $object_prefix = "entity_list:"; + } + + #::: Group + if ($export=~/all|group/i && $file=~/_group/i) { + $split_key = "Group::"; + $object_prefix = "group:"; + } + + #::: Raid + if ($export=~/all|raid/i && $file=~/_raid/i) { + $split_key = "Raid::"; + $object_prefix = "raid:"; + } + + #::: Corpse + if ($export=~/all|corpse/i && $file=~/_corpse/i) { + $split_key = "Corpse::"; + $object_prefix = "corpse:"; + } + + #::: Hateentry + if ($export=~/all|hate_entry/i && $file=~/_hate_entry/i) { + $split_key = "HateEntry::"; + $object_prefix = "hate_entry:"; + } + + #::: Spell + if ($export=~/all|spell/i && $file=~/_spell/i) { + $split_key = "Spell::"; + $object_prefix = "spell:"; + } + + #::: Spawn + if ($export=~/all|spawn/i && $file=~/_spawn/i) { + $split_key = "Spawn::"; + $object_prefix = "spawn:"; + } + + #::: StatBonuses + if ($export=~/all|stat_bonuses/i && $file=~/stat_bonuses/i) { + $split_key = "StatBonuses::"; + $object_prefix = "statbonuses:"; + } + + #::: Item + if ($export=~/all|item/i && $file=~/_item/i) { + $split_key = "Item::"; + $object_prefix = "item:"; + } + + #::: ItemInst + if ($export=~/all|iteminst/i && $file=~/_iteminst/i) { + $split_key = "ItemInst::"; + $object_prefix = "iteminst:"; + } + + #::: Inventory + if ($export=~/all|inventory/i && $file=~/_inventory/i) { + $split_key = "Inventory::"; + $object_prefix = "inventory:"; + } + + #::: Packet + if ($export=~/all|packet/i && $file=~/_packet/i) { + $split_key = "Packet::"; + $object_prefix = "packet:"; + } + + #::: Quest + if ($export=~/all|quest/i && $file=~/lua_general/i) { + $split_key = " lua_"; + $object_prefix = "eq."; + } + + #::: Open File + print "\nOpening '" . $file . "'\n"; + + if ($split_key eq "") { + next; + } + + open (FILE, $file); + while () { + chomp; + $line = $_; + + @data = split(" ", $line); + + if ((lc(substr($data[1], 0, 4)) eq "lua_") && $line!~/luabind/i && $line!~/return |#ifdef|struct /i) { + #::: Get return type + $return_type = trim($data[0]); + + @method_split = split($split_key, $line); + @method_end = split("{", $method_split[1]); + + $method = $object_prefix . trim($method_end[0]) . "; -- " . $return_type . "\n"; + + push @methods, $method; + } + } + + #::: Header + $header = $split_key; + $header =~s/:://g; + + print $fh "# " . $header . "\n"; + print $fh "```lua\n"; + + @methods = sort @methods; + foreach $method (@methods) { + print $fh $method; + print $method; + } + + print $fh "```\n\n"; +} + +close $fh; + +#::: Trim Whitespaces +sub trim { + my $string = $_[0]; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} \ No newline at end of file diff --git a/utils/scripts/opcode_handlers.py b/utils/scripts/opcode_handlers.py index fb3923209..5a3f0af34 100644 --- a/utils/scripts/opcode_handlers.py +++ b/utils/scripts/opcode_handlers.py @@ -14,6 +14,7 @@ values, server handler and whether opcodes are translated on tx/rx, etc... import sys import os +import fnmatch from time import time, ctime @@ -23,18 +24,22 @@ VERBOSE = False # messaging: {False - minimal, True - robust} base_path = os.getcwd()[:-14] # '/utils/scripts' base_path = base_path.replace('\\', '/') -client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'UF', 'RoF', 'RoF2'] -server_list = ['Login', 'World', 'Zone', 'UCS'] +client_list = ['Titanium', 'SoF', 'SoD', 'UF', 'RoF', 'RoF2'] +server_list = ['Login', 'World', 'Zone', 'UCS', 'Query', 'EQLaunch', 'HeadlessClient', 'Common'] # 'Common' is not a server..but, may contain shared functions +server_dirs = {'Login': 'loginserver', 'World': 'world', 'Zone': 'zone', 'UCS': 'ucs', 'Query': 'queryserv', 'EQLaunch': 'eqlaunch', 'HeadlessClient': 'hc', 'Common': 'common'} +file_exts = ['cpp', 'h'] client_opcodes = {} # x[key='Client'][key='OP_CodeName'](value='0x####') server_opcodes = {} # x[key='OP_CodeName'](value=) - opcodes apply to all servers +servertalk_opcodes = {} # x[key='OP_CodeName'](value=) - opcodes apply to all servers client_encodes = {} # x[key='Client'](value='OP_CodeName') client_decodes = {} # x[key='Client'](value='OP_CodeName') server_handlers = {} # x[key='Server'][key='OP_CodeName'](value='[%X] Near Handler::ReferenceFunction') +servertalk_handlers = {} # x[key='Server'][key='OP_CodeName'](value='[%X] Near Handler::ReferenceFunction') -out_files = {} # x[key='Server'](value=) +out_files = {} # x[key='Object'](value=) #statistics = {} #report_entries = {} @@ -81,24 +86,30 @@ def main(): if fault: faults.append('loadserveropcodes()') + if not fault: + fault = not loadservertalkopcodes() + + if fault: + faults.append('loadservertalkopcodes()') + if not fault: fault = not loadclienttranslators() if fault: faults.append('loadclienttranslators()') - if not fault: - fault = not loadserverhandlers() - - if fault: - faults.append('loadserverhandlers()') - if not fault: fault = not discoverserverhandlers() if fault: faults.append('discoverserverhandlers()') + if not fault: + fault = not discoverservertalkhandlers() + + if fault: + faults.append('discoverservertalkhandlers()') + if not fault: fault = not clearemptyserverentries() @@ -129,6 +140,12 @@ def main(): if fault: faults.append('parseserveropcodedata()') + if not fault: + fault = not parseservertalkopcodedata() + + if fault: + faults.append('parseservertalkopcodedata()') + if not fault: print('Destroying output streams...') @@ -181,14 +198,15 @@ def opendebugfile(): dprint( '>> \'Opcode-Handler\' DEBUG dump file\n' - '>> file generated @ {0}\n\n' - '->open: \'{1}\' in \'w\' mode\n' - 'leaving \'opendebugfile()\'\n\n'.format( - ctime(time()), - file_name - ) + '>> file generated @ {0}\n\n'.format(ctime(time())) ) + if VERBOSE: + dprint( + '->open: \'{0}\' in \'w\' mode\n' + 'leaving \'opendebugfile()\'\n\n'.format(file_name) + ) + return True except: print('(Exception Error: {0}) opendebugfile()'.format(sys.exc_info()[0])) @@ -206,7 +224,8 @@ def opendebugfile(): def openundefinedfile(): """ UNDEFINED FILE should always open """ - dprint('entering \'openundefinedfile()\'\n') + if VERBOSE: + dprint('entering \'openundefinedfile()\'\n') try: file_name = '{0}/utils/scripts/opcode_handlers_output/UNDEFINED.txt'.format(base_path) @@ -220,10 +239,11 @@ def openundefinedfile(): '>> file generated @ {0}\n\n'.format(ctime(time())) ) - dprint( - '->open: \'{0}\' in \'w\' mode\n' - 'leaving \'openundefinedfile()\'\n\n'.format(file_name) - ) + if VERBOSE: + dprint( + '->open: \'{0}\' in \'w\' mode\n' + 'leaving \'openundefinedfile()\'\n\n'.format(file_name) + ) return True except: @@ -242,7 +262,8 @@ def openundefinedfile(): def loadclientopcodes(): """ Load CLIENT OPCODES into memory """ - dprint('entering \'loadclientopcodes()\'\n') + if VERBOSE: + dprint('entering \'loadclientopcodes()\'\n') bad_clients = [] @@ -258,7 +279,8 @@ def loadclientopcodes(): vprint(file_name) with open(file_name, 'r') as data_file: - dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) client_opcodes[client] = {} line_no = 0 @@ -280,22 +302,34 @@ def loadclientopcodes(): value = int(data_line[(val_begin + 2):val_end].lower(), 16) if value == 0: + if VERBOSE: + uprint('\nUNDEFINED OPCODE FOUND: ../utils/patches{0}({1}:{2}) [{3}][{4}] = {5}\n'.format( + short_name, + line_no, + key_begin, + client, + data_line[key_begin:key_end], + '0x{0}'.format(hex(value)[2:].zfill(4)) + )) + continue client_opcodes[client][data_line[key_begin:key_end]] = '0x{0}'.format(hex(value)[2:].zfill(4)) - dprint('../utils/patches{0}({1}:{2}) [{3}][{4}] = {5}\n'.format( - short_name, - line_no, - key_begin, - client, - data_line[key_begin:key_end], - client_opcodes[client][data_line[key_begin:key_end]] - )) + if VERBOSE: + dprint('../utils/patches{0}({1}:{2}) [{3}][{4}] = {5}\n'.format( + short_name, + line_no, + key_begin, + client, + data_line[key_begin:key_end], + client_opcodes[client][data_line[key_begin:key_end]] + )) data_file.close() - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) if not len(client_opcodes[client]) > 0: bad_clients.append(client) @@ -340,7 +374,8 @@ def loadclientopcodes(): return False - dprint('leaving \'loadclientopcodes()\'\n\n') + if VERBOSE: + dprint('leaving \'loadclientopcodes()\'\n\n') return True @@ -348,20 +383,23 @@ def loadclientopcodes(): def loadserveropcodes(): """ Load SERVER OPCODES into memory """ - dprint('entering \'loadserveropcodes()\'\n') + if VERBOSE: + dprint('entering \'loadserveropcodes()\'\n') try: server_opcodes['OP_Unknown'] = 0 value = 1 - dprint('(manual) \'Servers\' [OP_Unknown] = {0}\n'.format(server_opcodes['OP_Unknown'])) + if VERBOSE: + dprint('(manual) \'Servers\' [OP_Unknown] = {0}\n'.format(server_opcodes['OP_Unknown'])) file_name = '{0}/common/emu_oplist.h'.format(base_path) vprint(file_name) with open(file_name, 'r') as data_file: - dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) line_no = 0 @@ -377,23 +415,26 @@ def loadserveropcodes(): server_opcodes[data_line[val_begin:val_end]] = value value += 1 - dprint('../common/emu_oplist.h({0}:{1}) \'Servers\' [{2}] = {3}\n'.format( - line_no, - val_begin, - data_line[val_begin:val_end], - server_opcodes[data_line[val_begin:val_end]] - )) + if VERBOSE: + dprint('../common/emu_oplist.h({0}:{1}) \'Servers\' [{2}] = {3}\n'.format( + line_no, + val_begin, + data_line[val_begin:val_end], + server_opcodes[data_line[val_begin:val_end]] + )) data_file.close() - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) file_name = '{0}/common/mail_oplist.h'.format(base_path) vprint(file_name) with open(file_name, 'r') as data_file: - dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) line_no = 0 @@ -409,16 +450,18 @@ def loadserveropcodes(): server_opcodes[data_line[val_begin:val_end]] = value value += 1 - dprint('../common/mail_oplist.h({0}:{1}) \'Servers\' [{2}] = {3}\n'.format( - line_no, - val_begin, - data_line[val_begin:val_end], - server_opcodes[data_line[val_begin:val_end]] - )) + if VERBOSE: + dprint('../common/mail_oplist.h({0}:{1}) \'Servers\' [{2}] = {3}\n'.format( + line_no, + val_begin, + data_line[val_begin:val_end], + server_opcodes[data_line[val_begin:val_end]] + )) data_file.close() - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) except: print('(Exception Error: {0}) loadserveropcodes()'.format(sys.exc_info()[0])) @@ -433,7 +476,79 @@ def loadserveropcodes(): return False - dprint('leaving \'loadserveropcodes()\'\n\n') + if VERBOSE: + dprint('leaving \'loadserveropcodes()\'\n\n') + + return True + + +def loadservertalkopcodes(): + """ Load SERVERTALK OPCODES into memory """ + + if VERBOSE: + dprint('entering \'loadservertalkopcodes()\'\n') + + try: + file_name = '{0}/common/servertalk.h'.format(base_path) + + vprint(file_name) + + with open(file_name, 'r') as data_file: + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + + line_no = 0 + + for data_line in data_file: + line_no += 1 + + if not data_line[:7] == '#define': + continue + + key_begin = data_line.find('ServerOP_', 8) + key_end = data_line.find('0x', key_begin) + + if key_begin < 0 or key_end < 0: + continue + + key_value = data_line[key_begin:key_end] + key_value = key_value.rstrip() + + val_begin = key_end + val_end = val_begin + 6 + + servertalk_opcodes[key_value] = data_line[val_begin:val_end] + + if VERBOSE: + dprint('../common/servertalk.h({0}:{1}) \'Servers\' [{2}] = {3}\n'.format( + line_no, + key_begin, + key_value, + servertalk_opcodes[key_value] + )) + + data_file.close() + + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) + + + except: + print('(Exception Error: {0}) loadservertalkopcodes()'.format(sys.exc_info()[0])) + + dprint('leaving \'loadservertalkopcodes(): EXCEPTION ERROR\'\n\n') + + return False + + if not len(servertalk_opcodes) > 0: + print('Could not locate servertalk opcode list...') + + dprint('leaving \'loadservertalkopcodes(): SERVERTALK OPCODES NOT FOUND\'\n\n') + + return False + + if VERBOSE: + dprint('leaving \'loadservertalkopcodes()\'\n\n') return True @@ -448,16 +563,14 @@ def loadclienttranslators(): """ - dprint('entering \'loadclienttranslators()\'\n') + if VERBOSE: + dprint('entering \'loadclienttranslators()\'\n') bad_clients = [] for client in client_list: try: - if client == '6.2': - short_name = '/client62_ops.h' - else: - short_name = '/{0}_ops.h'.format(client).lower() + short_name = '/{0}_ops.h'.format(client).lower() file_name = '{0}/common/patches{1}'.format( base_path, @@ -467,7 +580,8 @@ def loadclienttranslators(): vprint(file_name) with open(file_name, 'r') as data_file: - dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) client_encodes[client] = [] client_decodes[client] = [] @@ -484,27 +598,30 @@ def loadclienttranslators(): if data_line[:1] == 'E': client_encodes[client].append(data_line[val_begin:val_end]) - dprint('..{0}({1}:{2}) \'ENCODE\' [{3}] = {4}\n'.format( - short_name, - line_no, - val_begin, - client, - data_line[val_begin:val_end] - )) + if VERBOSE: + dprint('..{0}({1}:{2}) \'ENCODE\' [{3}] = {4}\n'.format( + short_name, + line_no, + val_begin, + client, + data_line[val_begin:val_end] + )) elif data_line[:1] == 'D': client_decodes[client].append(data_line[val_begin:val_end]) - dprint('..{0}({1}:{2}) \'DECODE\' [{3}] = {4}\n'.format( - short_name, - line_no, - val_begin, - client, - data_line[val_begin:val_end] - )) + if VERBOSE: + dprint('..{0}({1}:{2}) \'DECODE\' [{3}] = {4}\n'.format( + short_name, + line_no, + val_begin, + client, + data_line[val_begin:val_end] + )) data_file.close() - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) except: print('(Exception Error: {0}) loadclienttranslators() [{1}]'.format( sys.exc_info()[0], @@ -537,194 +654,26 @@ def loadclienttranslators(): return False - dprint('leaving \'loadclienttranslators()\'\n\n') - - return True - - -def loadserverhandlers(): - """ Load pre-designated SERVER OPCODE HANDLERS """ - - # TODO: handle remarked out definitions in file (i.e., // and /**/) - - dprint('entering \'loadserverhandlers()\'\n') - - bad_servers = [] - - for server in server_list: - try: - if server == 'Login': - vprint('No pre-designated server opcode handlers for \'Login\'') - dprint('->pass: \'Login\' server\n') - - continue - elif server == 'World': - vprint('No pre-designated server opcode handlers for \'World\'') - dprint('->pass: \'World\' server\n') - - continue - elif server == 'Zone': - file_name = '{0}/zone/client_packet.cpp'.format(base_path) - - vprint(file_name) - - with open(file_name, 'r') as data_file: - dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) - - server_handlers[server] = {} - handler_assigns = {} - step_1 = False - step_2 = False - line_no = 0 - hint = 'Near beginning of file' - - for data_line in data_file: - line_no += 1 - read_begin = 0 - - if step_1 is False: - if data_line[:19] == 'void MapOpcodes() {': - step_1 = True - - continue - - if step_2 is False: - if data_line[0:1] == '}': - step_2 = True - - continue - - val_begin = data_line.find('OP_', read_begin) - val_end = data_line.find(']', val_begin) - - if val_begin < 0 or val_end < 0: - continue - - if not data_line[val_begin:val_end] in server_opcodes: - dprint('\nILLEGAL OPCODE FOUND: ../zone/client_packet.cpp({0}:{1}) \'{2}\'\n'.format( - line_no, - val_begin, - data_line[val_begin:val_end] - )) - - continue - - key_begin = data_line.find('Client::', val_end) - key_end = data_line.find(';', key_begin) - - if key_begin < 0 or key_end < 0: - continue - - if not data_line[key_begin:key_end] in handler_assigns: - handler_assigns[data_line[key_begin:key_end]] = data_line[val_begin:val_end] - - continue - - if data_line[:1].isalpha(): - hint_begin = 0 - hint_end = data_line.find('(') - - if not hint_end < 0: - hint_begin = hint_end - 1 - - while not hint_begin < 0: - if data_line[(hint_begin - 1):hint_begin].isspace(): - if not data_line[hint_begin:(hint_begin + 1)].isalpha(): - hint_begin += 1 - - hint = '[RX] Near {0}'.format(data_line[hint_begin:hint_end]) - - break - - hint_begin -= 1 - else: - continue - - if hint[10:] in handler_assigns: - if not handler_assigns[hint[10:]] in server_handlers[server]: - server_handlers[server][handler_assigns[hint[10:]]] = [] - - server_handlers[server][handler_assigns[hint[10:]]].append( - '../zone/client_packet.cpp({0}:{1}) \'{2}\''.format( - line_no, - hint_begin, - hint - ) - ) - - dprint('../zone/client_packet.cpp({0}:{1}) [{2}][{3}] = \'{4}\'\n'.format( - line_no, - hint_begin, - server, - handler_assigns[hint[10:]], - hint - )) - - del handler_assigns[hint[10:]] - - if len(handler_assigns) > 0: - for unhandled in handler_assigns: - dprint('\nUNMATCHED DESIGNATED HANDLER FOUND: ../zone/client_packet.cpp \'{0}\'\n'.format( - unhandled - )) - - data_file.close() - - dprint('->close: \'{0}\'\n'.format(file_name)) - elif server == 'UCS': - vprint('No pre-designated server opcode handlers for \'UCS\'') - dprint('->pass: \'UCS\' server\n') - - continue - else: - vprint('No pre-designated server opcode handlers for \'{0}\''.format(server)) - dprint('->pass: \'{0}\' server\n'.format(server)) - - continue - except: - print('(Exception Error: {0}) loadserverhandlers() [{1}]'.format( - sys.exc_info()[0], - server - )) - - dprint('<-except: \'{0} [{1}]\'\n'.format( - sys.exc_info()[0], - server - )) - - bad_servers.append(server) - - for bad_server in bad_servers: - if bad_server in server_handlers: - vprint('Deleting stale entries for \'{0}\' server...'.format(bad_server)) - - del server_handlers[bad_server] - - dprint('->delete: \'{0}\' server designated handler entries\n'.format(bad_server)) - - dprint('leaving \'loadserverhandlers()\'\n\n') + if VERBOSE: + dprint('leaving \'loadclienttranslators()\'\n\n') return True def discoverserverhandlers(): """ - Load undefined SERVER OPCODE HANDLERS using 'discovery' method - - When adding new servers and/or search locations, use the following format: - - if 'Server' in locations: - locations['Server'].append('//.') + Load SERVER OPCODE HANDLERS using 'discovery' method Lists are instantiated for all SERVERS in SERVER LIST. The lists are then appended with location data based on the presence of the SERVER in the parent dictionary. """ - # TODO: handle remarked out definitions in file (i.e., // and /**/) + # TODO: handle multi-line remark statements in file # TODO: if/how to include perl, lua and non-'..//' location handlers... - dprint('entering \'discoverserverhandlers()\'\n') + if VERBOSE: + dprint('entering \'discoverserverhandlers()\'\n') bad_servers = [] locations = {} @@ -733,60 +682,21 @@ def discoverserverhandlers(): if not server in locations: locations[server] = [] - if 'Login' in locations: - locations['Login'].append('/loginserver/client.cpp') - locations['Login'].append('/loginserver/server_manager.cpp') - locations['Login'].append('/loginserver/world_server.cpp') + for server in locations: + file_path = '{0}/{1}/'.format(base_path, server_dirs[server]) - if 'World' in locations: - locations['World'].append('/world/client.cpp') + file_list = os.listdir(file_path) - if 'Zone' in locations: - locations['Zone'].append('/zone/aa.cpp') - locations['Zone'].append('/zone/attack.cpp') - locations['Zone'].append('/zone/bot.cpp') - locations['Zone'].append('/zone/bot_command.cpp') - locations['Zone'].append('/zone/client.cpp') - locations['Zone'].append('/zone/client_packet.cpp') - locations['Zone'].append('/zone/client_process.cpp') - locations['Zone'].append('/zone/command.cpp') - locations['Zone'].append('/zone/corpse.cpp') - locations['Zone'].append('/zone/doors.cpp') - locations['Zone'].append('/zone/effects.cpp') - locations['Zone'].append('/zone/entity.cpp') - locations['Zone'].append('/zone/exp.cpp') - locations['Zone'].append('/zone/groups.cpp') - locations['Zone'].append('/zone/guild.cpp') - locations['Zone'].append('/zone/guild_mgr.cpp') - locations['Zone'].append('/zone/horse.cpp') - locations['Zone'].append('/zone/inventory.cpp') - locations['Zone'].append('/zone/loottables.cpp') - locations['Zone'].append('/zone/merc.cpp') - locations['Zone'].append('/zone/mob.cpp') - locations['Zone'].append('/zone/mob_ai.cpp') - locations['Zone'].append('/zone/object.cpp') - locations['Zone'].append('/zone/pathing.cpp') - locations['Zone'].append('/zone/petitions.cpp') - locations['Zone'].append('/zone/questmgr.cpp') - locations['Zone'].append('/zone/raids.cpp') - locations['Zone'].append('/zone/special_attacks.cpp') - locations['Zone'].append('/zone/spells.cpp') - locations['Zone'].append('/zone/spell_effects.cpp') - locations['Zone'].append('/zone/tasks.cpp') - locations['Zone'].append('/zone/titles.cpp') - locations['Zone'].append('/zone/tradeskills.cpp') - locations['Zone'].append('/zone/trading.cpp') - locations['Zone'].append('/zone/trap.cpp') - locations['Zone'].append('/zone/tribute.cpp') - locations['Zone'].append('/zone/worldserver.cpp') - locations['Zone'].append('/zone/zone.cpp') - locations['Zone'].append('/zone/zonedb.cpp') - locations['Zone'].append('/zone/zoning.cpp') + for extension in file_exts: + if VERBOSE: + dprint('->file discovery: \'{0}*.{1}\'\n'.format(file_path, extension)) - if 'UCS' in locations: - locations['UCS'].append('/ucs/clientlist.cpp') - locations['UCS'].append('/ucs/database.cpp') + for file_name in fnmatch.filter(file_list, '*.{0}'.format(extension)): + if file_name in ['emu_oplist.h', 'mail_oplist.h', 'opcode_dispatch.h', 'opcode_map.cpp', 'op_codes.h']: + continue + locations[server].append('/{0}/{1}'.format(server_dirs[server], file_name)) + for server in server_list: if not server in server_handlers: server_handlers[server] = {} @@ -800,7 +710,8 @@ def discoverserverhandlers(): vprint(file_name) with open(file_name, 'r') as data_file: - dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) line_no = 0 hint = 'Near beginning of file' @@ -831,17 +742,401 @@ def discoverserverhandlers(): if op_begin < 0: continue - if data_line[(op_begin - 20):op_begin] == 'EQApplicationPacket(': + # exclusions + if data_line[(op_begin - 1):op_begin].isalnum(): + continue + elif data_line[:op_begin].find('//', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nREMARKED OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('Log(Logs::', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nLOGGING OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('std::cout', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nCONSOLE MESSAGE OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('MakeAnyLenString', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nSTRING FORMAT OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('printf', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nSTRING FORMAT OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('VERIFY_PACKET_LENGTH', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nPACKET LENGTH OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('ConnectingOpcodes', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nOPCODE HANDLER ASSIGNMENT REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('ConnectedOpcodes', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nOPCODE HANDLER ASSIGNMENT REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('command_add', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nCOMMAND HANDLER ASSIGNMENT OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('luabind::value', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nLUA API OPCODE ASSIGNMENT REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].find('Message', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nCLIENT MESSAGE OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].count('"') and 1: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nSTRING TEXT OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[(op_begin - 3):op_begin] == '!= ': + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[(op_begin - 2):op_begin] == '!=': + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[(op_begin - 3):op_begin] == '>= ': + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[(op_begin - 2):op_begin] == '>=': + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[(op_begin - 3):op_begin] == '<= ': + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[(op_begin - 2):op_begin] == '<=': + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].isspace(): + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 3 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + # inclusion [RX] + elif data_line[(op_begin - 7):op_begin] == 'Handle_': key_begin = op_begin key_end = key_begin + 3 - direction = '[TX]' + direction = '[RX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - elif data_line[(op_begin - 12):op_begin] == '->SetOpcode(': + elif data_line[(op_begin - 15):op_begin] == 'Handle_Connect_': key_begin = op_begin key_end = key_begin + 3 - direction = '[TX]' + direction = '[RX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 @@ -866,120 +1161,49 @@ def discoverserverhandlers(): while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - elif data_line[(op_begin - 3):op_begin] == '!= ': + # inclusions [TX] + elif data_line[(op_begin - 1):op_begin] == '(' and data_line[:op_begin].find('EQProtocolPacket', 0) >= 0: key_begin = op_begin key_end = key_begin + 3 + direction = '[TX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - - dprint( - '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' - '->line: \'{4}\'\n'.format( - location, - line_no, - key_begin, - data_line[key_begin:key_end], - data_line[:-1] - ) - ) - - continue - elif data_line[(op_begin - 2):op_begin] == '!=': + elif data_line[(op_begin - 2):op_begin] == ' (' and data_line[:op_begin].find('EQProtocolPacket', 0) >= 0: key_begin = op_begin key_end = key_begin + 3 + direction = '[TX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - - dprint( - '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' - '->line: \'{4}\'\n'.format( - location, - line_no, - key_begin, - data_line[key_begin:key_end], - data_line[:-1] - ) - ) - - continue - elif data_line[(op_begin - 3):op_begin] == '>= ': + elif data_line[(op_begin - 1):op_begin] == '(' and data_line[:op_begin].find('EQApplicationPacket', 0) >= 0: key_begin = op_begin key_end = key_begin + 3 + direction = '[TX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - - dprint( - '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' - '->line: \'{4}\'\n'.format( - location, - line_no, - key_begin, - data_line[key_begin:key_end], - data_line[:-1] - ) - ) - - continue - elif data_line[(op_begin - 2):op_begin] == '>=': + elif data_line[(op_begin - 2):op_begin] == ' (' and data_line[:op_begin].find('EQApplicationPacket', 0) >= 0: key_begin = op_begin key_end = key_begin + 3 + direction = '[TX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - - dprint( - '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' - '->line: \'{4}\'\n'.format( - location, - line_no, - key_begin, - data_line[key_begin:key_end], - data_line[:-1] - ) - ) - - continue - elif data_line[(op_begin - 3):op_begin] == '<= ': + elif data_line[(op_begin - 12):op_begin] == '->SetOpcode(': key_begin = op_begin key_end = key_begin + 3 + direction = '[TX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - - dprint( - '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' - '->line: \'{4}\'\n'.format( - location, - line_no, - key_begin, - data_line[key_begin:key_end], - data_line[:-1] - ) - ) - - continue - elif data_line[(op_begin - 2):op_begin] == '<=': + elif data_line[(op_begin - 11):op_begin] == '.SetOpcode(': key_begin = op_begin key_end = key_begin + 3 + direction = '[TX]' while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 - - dprint( - '\nILL-DEFINED OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' - '->line: \'{4}\'\n'.format( - location, - line_no, - key_begin, - data_line[key_begin:key_end], - data_line[:-1] - ) - ) - - continue elif data_line[(op_begin - 2):op_begin] == '= ': key_begin = op_begin key_end = key_begin + 3 @@ -994,6 +1218,7 @@ def discoverserverhandlers(): while data_line[key_end:(key_end + 1)].isalnum(): key_end += 1 + # fall-through else: key_begin = op_begin key_end = key_begin + 3 @@ -1042,19 +1267,21 @@ def discoverserverhandlers(): ) ) - dprint('..{0}({1}:{2}) [{3}][{4}] = \'{5} {6}\'\n'.format( - location, - line_no, - key_begin, - server, - data_line[key_begin:key_end], - direction, - hint - )) + if VERBOSE: + dprint('..{0}({1}:{2}) [{3}][{4}] = \'{5} {6}\'\n'.format( + location, + line_no, + key_begin, + server, + data_line[key_begin:key_end], + direction, + hint + )) data_file.close() - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) except: print('(Exception Error: {0}) discoverserverhandlers() [{1}]'.format( sys.exc_info()[0], @@ -1077,7 +1304,357 @@ def discoverserverhandlers(): dprint('->delete: \'{0}\' server discovered handler entries\n'.format(bad_server)) - dprint('leaving \'discoverserverhandlers()\'\n\n') + if VERBOSE: + dprint('leaving \'discoverserverhandlers()\'\n\n') + + return True + + +def discoverservertalkhandlers(): + """ + Load SERVERTALK OPCODE HANDLERS using 'discovery' method + + Lists are instantiated for all SERVERS in SERVER LIST. The lists are then appended + with location data based on the presence of the SERVER in the parent dictionary. + + """ + + # TODO: handle multi-line remark statements in file + # TODO: if/how to include perl, lua and non-'..//' location handlers... + + if VERBOSE: + dprint('entering \'discoverservertalkhandlers()\'\n') + + bad_servers = [] + locations = {} + + for server in server_list: + if not server in locations: + locations[server] = [] + + for server in locations: + file_path = '{0}/{1}/'.format(base_path, server_dirs[server]) + + file_list = os.listdir(file_path) + + for extension in file_exts: + if VERBOSE: + dprint('->file discovery: \'{0}*.{1}\'\n'.format(file_path, extension)) + + for file_name in fnmatch.filter(file_list, '*.{0}'.format(extension)): + if file_name in ['emu_oplist.h', 'mail_oplist.h', 'opcode_dispatch.h', 'opcode_map.cpp', 'op_codes.h', 'servertalk.h']: + continue + + locations[server].append('/{0}/{1}'.format(server_dirs[server], file_name)) + + for server in server_list: + if not server in servertalk_handlers: + servertalk_handlers[server] = {} + + for location in locations[server]: + try: + file_name = '{0}{1}'.format( + base_path, + location) + + vprint(file_name) + + with open(file_name, 'r') as data_file: + if VERBOSE: + dprint('->open: \'{0}\' in \'r\' mode\n'.format(file_name)) + + line_no = 0 + hint = 'Near beginning of file' + + for data_line in data_file: + line_no += 1 + read_begin = 0 + + if data_line[:1].isalpha(): + hint_end = data_line.find('(') + + if not hint_end < 0: + hint_begin = hint_end - 1 + + while not hint_begin < 0: + if data_line[(hint_begin - 1):hint_begin].isspace(): + if not data_line[hint_begin:(hint_begin + 1)].isalpha(): + hint_begin += 1 + + hint = 'Near {0}'.format(data_line[hint_begin:hint_end]) + + break + + hint_begin -= 1 + + op_begin = data_line.find('ServerOP_', read_begin) + + if op_begin < 0: + continue + + # exclusions + if data_line[(op_begin - 1):op_begin].isalnum(): + continue + elif data_line[op_begin:].find('_Struct', 0) >= 0 and not data_line[op_begin:data_line[op_begin:].find('_Struct', 0)].isspace(): + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 9 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nIll-DEFINED SERVERTALK OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[read_begin:op_begin].find('//', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 9 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nREMARKED SERVERTALK OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[read_begin:op_begin].find('Log(Logs::', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 9 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nLOGGING SERVERTALK OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[read_begin:op_begin].find('std::cout', 0) >= 0: + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 9 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nCONSOLE MESSAGE SERVERTALK OPCODE REFERENCE FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + elif data_line[:op_begin].isspace(): + if VERBOSE: + key_begin = op_begin + key_end = key_begin + 9 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + dprint( + '\nILL-DEFINED SERVERTALK OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + # inclusions [RX] + elif data_line[(op_begin - 1):op_begin] == '(' and data_line[read_begin:op_begin].find('OnMessage', 0) >= 0: + key_begin = op_begin + key_end = key_begin + 9 + direction = '[RX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 2):op_begin] == ' (' and data_line[read_begin:op_begin].find('OnMessage', 0) >= 0: + key_begin = op_begin + key_end = key_begin + 9 + direction = '[RX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 5):op_begin] == 'case ': + key_begin = op_begin + key_end = key_begin + 9 + direction = '[RX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 3):op_begin] == '== ': + key_begin = op_begin + key_end = key_begin + 9 + direction = '[RX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 2):op_begin] == '==': + key_begin = op_begin + key_end = key_begin + 9 + direction = '[RX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + # inclusions [TX] + elif data_line[(op_begin - 1):op_begin] == '(' and data_line[read_begin:op_begin].find('ServerPacket', 0) >= 0: + key_begin = op_begin + key_end = key_begin + 9 + direction = '[TX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 2):op_begin] == ' (' and data_line[read_begin:op_begin].find('ServerPacket', 0) >= 0: + key_begin = op_begin + key_end = key_begin + 9 + direction = '[TX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 7):op_begin] == '->Send(': + key_begin = op_begin + key_end = key_begin + 9 + direction = '[TX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 2):op_begin] == '= ': + key_begin = op_begin + key_end = key_begin + 9 + direction = '[TX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + elif data_line[(op_begin - 1):op_begin] == '=': + key_begin = op_begin + key_end = key_begin + 9 + direction = '[TX]' + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + # fall-through + else: + key_begin = op_begin + key_end = key_begin + 9 + + while data_line[key_end:(key_end + 1)].isalnum(): + key_end += 1 + + uprint( + '\nUNDEFINED SERVERTALK OPCODE CONDITIONAL FOUND: ..{0}({1}:{2}) \'{3}\'\n' + '->line: \'{4}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end], + data_line[:-1] + ) + ) + + continue + + if key_end < 0: + continue + + if not data_line[key_begin:key_end] in servertalk_opcodes: + dprint('\nILLEGAL SERVERTALK OPCODE FOUND: ..{0}({1}:{2}) \'{3}\'\n'.format( + location, + line_no, + key_begin, + data_line[key_begin:key_end] + )) + + continue + + if not data_line[key_begin:key_end] in servertalk_handlers[server]: + servertalk_handlers[server][data_line[key_begin:key_end]] = [] + + servertalk_handlers[server][data_line[key_begin:key_end]].append( + '..{0}({1}:{2}) \'{3}\''.format( + location, + line_no, + key_begin, + '{0} {1}'.format( + direction, + hint + ) + ) + ) + + if VERBOSE: + dprint('..{0}({1}:{2}) [{3}][{4}] = \'{5} {6}\'\n'.format( + location, + line_no, + key_begin, + server, + data_line[key_begin:key_end], + direction, + hint + )) + + data_file.close() + + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) + except: + print('(Exception Error: {0}) discoverservertalkhandlers() [{1}]'.format( + sys.exc_info()[0], + server + )) + + dprint('<-except: \'{0} [{1}]\'\n'.format( + sys.exc_info()[0], + server + )) + + if not server in bad_servers: + bad_servers.append(server) + + for bad_server in bad_servers: + if bad_server in servertalk_handlers: + vprint('Deleting stale entries for \'{0}\' server...'.format(bad_server)) + + del servertalk_handlers[bad_server] + + dprint('->delete: \'{0}\' server discovered servertalk handler entries\n'.format(bad_server)) + + if VERBOSE: + dprint('leaving \'discoverservertalkhandlers()\'\n\n') return True @@ -1095,7 +1672,8 @@ def clearemptyserverentries(): """ - dprint('entering \'clearemptyserverentries()\'\n') + if VERBOSE: + dprint('entering \'clearemptyserverentries()\'\n') bad_servers = [] @@ -1143,7 +1721,8 @@ def clearemptyserverentries(): return False - dprint('leaving \'clearemptyserverentries()\'\n\n') + if VERBOSE: + dprint('leaving \'clearemptyserverentries()\'\n\n') return True @@ -1151,7 +1730,8 @@ def clearemptyserverentries(): def openoutputfiles(): """ Open OUTPUT FILES in 'w' mode - create/overwrite mode """ - dprint('entering \'openoutputfiles()\'\n') + if VERBOSE: + dprint('entering \'openoutputfiles()\'\n') try: file_name = '{0}/utils/scripts/opcode_handlers_output/REPORT.txt'.format(base_path) @@ -1160,7 +1740,8 @@ def openoutputfiles(): out_files['REPORT'] = open(file_name, 'w') - dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) rprint( '>> \'Opcode-Handler\' REPORT file\n' @@ -1177,7 +1758,8 @@ def openoutputfiles(): out_files[client] = open(file_name, 'w') - dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) cprint( client, @@ -1198,7 +1780,8 @@ def openoutputfiles(): out_files[server] = open(file_name, 'w') - dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) + if VERBOSE: + dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) sprint( server, @@ -1209,7 +1792,22 @@ def openoutputfiles(): ) ) - dprint('leaving \'openoutputfiles()\'\n\n') + file_name = '{0}/utils/scripts/opcode_handlers_output/ServerTalk_opcode_handlers.txt'.format(base_path) + + vprint(file_name) + + out_files['ServerTalk'] = open(file_name, 'w') + + if VERBOSE: + dprint('->open: \'{0}\' in \'w\' mode\n'.format(file_name)) + + stprint( + '>> \'Opcode-Handler\' analysis for ServerTalk\n' + '>> file generated @ {0}\n\n'.format(ctime(time())) + ) + + if VERBOSE: + dprint('leaving \'openoutputfiles()\'\n\n') return True except: @@ -1238,7 +1836,15 @@ def openoutputfiles(): del out_files[server] - dprint('leaving \'openoutputfiles(): EXCEPTION ERROR\'\n\n') + if 'ServerTalk' in out_files: + vprint('Closing ServerTalk output file...') + + out_files['ServerTalk'].close() + + del out_files['ServerTalk'] + + if VERBOSE: + dprint('leaving \'openoutputfiles(): EXCEPTION ERROR\'\n\n') return False @@ -1246,7 +1852,8 @@ def openoutputfiles(): def parseclientopcodedata(): """ Process CLIENT OPCODE cross-link references """ - dprint('entering \'parseclientopcodedata()\'\n') + if VERBOSE: + dprint('entering \'parseclientopcodedata()\'\n') for client in client_list: server_max_len = 0 @@ -1296,9 +1903,11 @@ def parseclientopcodedata(): cprint(client, message) - dprint('->parse: \'{0}\' client\n'.format(client)) - - dprint('leaving \'parseclientopcodedata()\'\n\n') + if VERBOSE: + dprint('->parse: \'{0}\' client\n'.format(client)) + + if VERBOSE: + dprint('leaving \'parseclientopcodedata()\'\n\n') return True @@ -1306,7 +1915,8 @@ def parseclientopcodedata(): def parseserveropcodedata(): """ Process SERVER OPCODE cross-link references """ - dprint('entering \'parseserveropcodedata()\'\n') + if VERBOSE: + dprint('entering \'parseserveropcodedata()\'\n') for server in server_list: client_max_len = 0 @@ -1354,9 +1964,59 @@ def parseserveropcodedata(): sprint(server, message) - dprint('->parse: \'{0}\' server\n'.format(server)) + if VERBOSE: + dprint('->parse: \'{0}\' server\n'.format(server)) - dprint('leaving \'parseserveropcodedata()\'\n\n') + if VERBOSE: + dprint('leaving \'parseserveropcodedata()\'\n\n') + + return True + + +def parseservertalkopcodedata(): + """ Process SERVERTALK OPCODE references """ + + if VERBOSE: + dprint('entering \'parseservertalkopcodedata()\'\n') + + local_handlers = {} # swap key order for local processing + + for keya in servertalk_handlers: + for keyb in servertalk_handlers[keya]: + if not keyb in local_handlers: + local_handlers[keyb] = {} + if not keya in local_handlers[keyb]: + local_handlers[keyb][keya] = [] + + local_handlers[keyb][keya] = servertalk_handlers[keya][keyb] + + opcode_keys = local_handlers.keys() + opcode_keys.sort() + + for opcode_key in opcode_keys: + server_keys = local_handlers[opcode_key].keys() + server_keys.sort() + + message = '' + + for server_key in local_handlers[opcode_key]: + handler_list = local_handlers[opcode_key][server_key] + handler_list.sort() + + for handler_entry in handler_list: + message += 'Opcode: {0} ({1}) | Handler: [{2}] {3}\n'.format( + opcode_key, + '{0}'.format(servertalk_opcodes[opcode_key]).zfill(4), + server_key, + handler_entry) + + message += '\n' + + stprint(message) + + if VERBOSE: + dprint('->parse: ServerTalk\n') + dprint('leaving \'parseservertalkopcodedata()\'\n\n') return True @@ -1364,7 +2024,8 @@ def parseserveropcodedata(): def closeoutputfiles(): """ Close OUTPUT FILES - excluding DEBUG FILE """ - dprint('entering \'closeoutputfiles()\'\n') + if VERBOSE: + dprint('entering \'closeoutputfiles()\'\n') if 'REPORT' in out_files: file_name = out_files['REPORT'].name @@ -1373,7 +2034,8 @@ def closeoutputfiles(): del out_files['REPORT'] - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) if 'UNDEFINED' in out_files: file_name = out_files['UNDEFINED'].name @@ -1382,7 +2044,8 @@ def closeoutputfiles(): del out_files['UNDEFINED'] - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) for client in client_list: if client in out_files: @@ -1392,7 +2055,8 @@ def closeoutputfiles(): del out_files[client] - dprint('->close: \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) for server in server_list: if server in out_files: @@ -1402,9 +2066,21 @@ def closeoutputfiles(): del out_files[server] + if VERBOSE: + dprint('->close: \'{0}\'\n'.format(file_name)) + + if 'ServerTalk' in out_files: + file_name = out_files['ServerTalk'].name + + out_files['ServerTalk'].close() + + del out_files['ServerTalk'] + + if VERBOSE: dprint('->close: \'{0}\'\n'.format(file_name)) - dprint('leaving \'closeoutputfiles()\'\n\n') + if VERBOSE: + dprint('leaving \'closeoutputfiles()\'\n\n') return True @@ -1412,12 +2088,14 @@ def closeoutputfiles(): def closedebugfile(): """ Close DEBUG FILE - last performed action to catch late messages """ - dprint('entering \'closedebugfile()\'\n') + if VERBOSE: + dprint('entering \'closedebugfile()\'\n') if 'DEBUG' in out_files: file_name = out_files['DEBUG'].name - dprint('closing \'{0}\'\n'.format(file_name)) + if VERBOSE: + dprint('closing \'{0}\'\n'.format(file_name)) out_files['DEBUG'].close() @@ -1454,6 +2132,13 @@ def sprint(server, message): out_files[server].write(message) +def stprint(message): + """ SERVERTALK PRINT helper function """ + + if 'ServerTalk' in out_files: + out_files['ServerTalk'].write(message) + + def uprint(message): """ UNDEFINED PRINT helper function """ diff --git a/utils/scripts/perl-doc-parser.pl b/utils/scripts/perl-doc-parser.pl new file mode 100755 index 000000000..30cf6e116 --- /dev/null +++ b/utils/scripts/perl-doc-parser.pl @@ -0,0 +1,179 @@ +#!/usr/bin/perl + +# Author: Akkadius +# @file: perl-doc-parser.pl +# @description: Script meant to parse the source code to build the Perl API list + +use File::Find; +use Data::Dumper; + +sub usage() { + print "Usage:\n"; + print " --client - Prints methods for just client class methods\n"; + print " --mob - Prints methods for just mob class methods\n"; + print " --npc - Prints methods for just npc class methods\n"; + print " --entity - Prints methods for just entity class methods\n"; + print " --door - Prints methods for just door class methods\n"; + print " --object - Prints methods for just object class methods\n"; + print " --group - Prints methods for just group class methods\n"; + print " --raid - Prints methods for just raid class methods\n"; + print " --questitem - Prints methods for just questitem class methods\n"; + print " --corpse - Prints methods for just corpse class methods\n"; + print " --hateentry - Prints methods for just hateentry class methods\n"; + print " --quest - Prints methods for just quest class methods\n"; + print " --all - Prints methods for all classes\n"; + exit(1); +} + +if($#ARGV < 0) { + usage(); +} + +my $export = $ARGV[0]; +$export=~s/--//g; + +my $export_file_search = $export; + +if ($export eq "quest") { + $export_file_search = "embparser_api"; +} + +my @files; +my $start_dir = "zone/"; +find( + sub { push @files, $File::Find::name unless -d; }, + $start_dir +); +for my $file (@files) { + + #::: Skip non Perl files + if($file!~/perl_|embparser_api/i){ + next; + } + + #::: If we are specifying a specific class type, skip everything else + if ($export ne "all" && $export ne "") { + if ($file!~/$export_file_search/i) { + next; + } + } + + @methods = (); + $split_key = ""; + $object_prefix = ""; + + #::: Open File + print "\nOpening '" . $file . "'\n"; + open (FILE, $file); + while () { + chomp; + $line = $_; + + if ($line=~/Perl_croak/i && $line=~/Usa/i && $line=~/::/i && $line!~/::new/i) { + + #::: Client export + if ($export=~/all|client/i && $line=~/Client::/i) { + $split_key = "Client::"; + $object_prefix = "\$client->"; + } + + #::: Mob export + if ($export=~/all|mob/i && $line=~/Mob::/i) { + $split_key = "Mob::"; + $object_prefix = "\$mob->"; + } + + #::: NPC export + if ($export=~/all|npc/i && $line=~/NPC::/i) { + $split_key = "NPC::"; + $object_prefix = "\$npc->"; + } + + #::: Corpse export + if ($export=~/all|corpse/i && $line=~/Corpse::/i) { + $split_key = "Corpse::"; + $object_prefix = "\$corpse->"; + } + + #::: Entity export + if ($export=~/all|entity/i && $line=~/EntityList::/i) { + $split_key = "EntityList::"; + $object_prefix = "\$entity_list->"; + } + + #::: Doors export + if ($export=~/all|door/i && $line=~/Doors::/i) { + $split_key = "Doors::"; + $object_prefix = "\$door->"; + } + + #::: Object export + if ($export=~/all|object/i && $line=~/Object::/i) { + $split_key = "Object::"; + $object_prefix = "\$object->"; + } + + #::: Group export + if ($export=~/all|group/i && $line=~/Group::/i) { + $split_key = "Group::"; + $object_prefix = "\$group->"; + } + + #::: Raid export + if ($export=~/all|raid/i && $line=~/Raid::/i) { + $split_key = "Raid::"; + $object_prefix = "\$raid->"; + } + + #::: Hateentry export + if ($export=~/all|hateentry/i && $line=~/HateEntry::/i) { + $split_key = "HateEntry::"; + $object_prefix = "\$hate_entry->"; + } + + #::: Questitem export + if ($export=~/all|questitem/i && $line=~/QuestItem::/i) { + $split_key = "QuestItem::"; + $object_prefix = "\$quest_item->"; + } + + #::: Quest:: exports + if ($export=~/all|quest/i && $line=~/quest::/i) { + $split_key = "quest::"; + $object_prefix = "\quest::"; + } + + #::: Split on croak usage + @data = split($split_key, $line); + $usage = trim($data[1]); + + #::: Split out param borders and get method name + @params_begin = split('\(', $usage); + $method_name = trim($params_begin[0]); + + #::: Get params string built + @params_end = split('\)', $params_begin[1]); + $params_string = trim($params_end[0]); + $params_string =~s/THIS\,//g; + $params_string =~s/THIS//g; + $params_string = trim($params_string); + + $method = $object_prefix . $method_name . "(" . lc($params_string) . ")\n"; + + push @methods, $method; + } + } + + @methods = sort @methods; + foreach $method (@methods) { + print $method; + } +} + +#::: Trim Whitespaces +sub trim { + my $string = $_[0]; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} \ No newline at end of file diff --git a/utils/sql/character_table_list.txt b/utils/sql/character_table_list.txt index 2a902d009..4d70051ec 100644 --- a/utils/sql/character_table_list.txt +++ b/utils/sql/character_table_list.txt @@ -1,19 +1,26 @@ adventure_stats char_recipe_list +character_auras character_activities character_alt_currency character_alternate_abilities character_bandolier character_bind +character_buffs +character_corpse_items +character_corpses character_currency character_data character_disciplines character_enabledtasks character_inspect_messages +character_item_recast character_languages character_leadership_abilities character_material character_memmed_spells +character_pet_buffs +character_pet_inventory character_potionbelt character_skills character_spells diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index db0a04ca8..22a593176 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -376,6 +376,9 @@ 9120|2018_02_13_Heading.sql|SELECT value FROM variables WHERE varname = 'fixed_heading'|empty| 9121|2018_02_18_bug_reports.sql|SHOW TABLES LIKE 'bug_reports'|empty| 9122|2018_03_07_ucs_command.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'ucs'|empty| +9123|2018_07_07_data_buckets.sql|SHOW TABLES LIKE 'data_buckets'|empty| +9124|2018_07_09_tasks.sql|SHOW COLUMNS FROM `tasks` LIKE 'type'|empty| +9125|2018_07_20_task_emote.sql|SHOW COLUMNS FROM `tasks` LIKE 'completion_emote'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2018_07_07_data_buckets.sql b/utils/sql/git/required/2018_07_07_data_buckets.sql new file mode 100644 index 000000000..d2a842f64 --- /dev/null +++ b/utils/sql/git/required/2018_07_07_data_buckets.sql @@ -0,0 +1,8 @@ +CREATE TABLE `data_buckets` ( + `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT, + `key` varchar(100) DEFAULT NULL, + `value` text, + `expires` int(11) unsigned DEFAULT '0', + PRIMARY KEY (`id`), + KEY `key_index` (`key`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/utils/sql/git/required/2018_07_09_tasks.sql b/utils/sql/git/required/2018_07_09_tasks.sql new file mode 100644 index 000000000..fdc9daada --- /dev/null +++ b/utils/sql/git/required/2018_07_09_tasks.sql @@ -0,0 +1,22 @@ +ALTER TABLE `tasks` ADD `type` TINYINT NOT NULL DEFAULT '0' AFTER `id`; +ALTER TABLE `tasks` ADD `duration_code` TINYINT NOT NULL DEFAULT '0' AFTER `duration`; +UPDATE `tasks` SET `type` = '2'; -- we were treating them all as quests +ALTER TABLE `character_tasks` ADD `type` TINYINT NOT NULL DEFAULT '0' AFTER `slot`; +UPDATE `character_tasks` SET `type` = '2'; -- we were treating them all as quests +ALTER TABLE `activities` ADD `target_name` VARCHAR(64) NOT NULL DEFAULT '' AFTER `activitytype`; +ALTER TABLE `activities` ADD `item_list` VARCHAR(128) NOT NULL DEFAULT '' AFTER `target_name`; +ALTER TABLE `activities` ADD `skill_list` VARCHAR(64) NOT NULL DEFAULT '-1' AFTER `item_list`; +ALTER TABLE `activities` ADD `spell_list` VARCHAR(64) NOT NULL DEFAULT '0' AFTER `skill_list`; +ALTER TABLE `activities` ADD `description_override` VARCHAR(128) NOT NULL DEFAULT '' AFTER `spell_list`; +ALTER TABLE `activities` ADD `zones` VARCHAR(64) NOT NULL DEFAULT '' AFTER `zoneid`; +UPDATE `activities` SET `description_override` = `text3`; +UPDATE `activities` SET `target_name` = `text1`; +UPDATE `activities` SET `item_list` = `text2`; +UPDATE `activities` SET `zones` = `zoneid`; -- should be safe for us ... +ALTER TABLE `activities` DROP COLUMN `text1`; +ALTER TABLE `activities` DROP COLUMN `text2`; +ALTER TABLE `activities` DROP COLUMN `text3`; +ALTER TABLE `activities` DROP COLUMN `zoneid`; +ALTER TABLE `tasks` DROP COLUMN `startzone`; +ALTER TABLE `tasks` ADD `faction_reward` INT(10) NOT NULL DEFAULT '0'; +RENAME TABLE `activities` TO `task_activities`; \ No newline at end of file diff --git a/utils/sql/git/required/2018_07_20_task_emote.sql b/utils/sql/git/required/2018_07_20_task_emote.sql new file mode 100644 index 000000000..1bccf105e --- /dev/null +++ b/utils/sql/git/required/2018_07_20_task_emote.sql @@ -0,0 +1 @@ +ALTER TABLE `tasks` ADD `completion_emote` VARCHAR(128) NOT NULL DEFAULT ''; diff --git a/utils/sql/system_tables.txt b/utils/sql/system_tables.txt index ba1489b65..7816fea21 100644 --- a/utils/sql/system_tables.txt +++ b/utils/sql/system_tables.txt @@ -5,7 +5,7 @@ aa_required_level_cost aa_ranks aa_rank_effects aa_rank_prereqs -activities +task_activities adventure_template adventure_template_entry adventure_template_entry_flavor @@ -24,6 +24,7 @@ faction_list_mod fear_hints fishing forage +global_loot goallists graveyard grid @@ -97,4 +98,4 @@ zone zone_points zone_server zone_state_dump -zoneserver_auth \ No newline at end of file +zoneserver_auth diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index 233c2e1c9..e8b999107 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -65,6 +65,6 @@ TARGET_LINK_LIBRARIES(world ${SERVER_LIBS}) IF(EQEMU_BUILD_PERL) TARGET_LINK_LIBRARIES(world ${PERL_LIBRARY}) -ENDIF(EQEMU_BUILD_PERL) +ENDIF() SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/world/client.cpp b/world/client.cpp index d3b74ae3f..f8b4fe3f4 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -212,8 +212,8 @@ void Client::SendMaxCharCreate() { MaxCharacters_Struct* mc = (MaxCharacters_Struct*)outapp->pBuffer; mc->max_chars = EQEmu::constants::Lookup(m_ClientVersion)->CharacterCreationLimit; - if (mc->max_chars > EQEmu::constants::CharacterCreationMax) - mc->max_chars = EQEmu::constants::CharacterCreationMax; + if (mc->max_chars > EQEmu::constants::CHARACTER_CREATION_LIMIT) + mc->max_chars = EQEmu::constants::CHARACTER_CREATION_LIMIT; QueuePacket(outapp); safe_delete(outapp); @@ -766,8 +766,8 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) { // (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration) if (!is_player_zoning) { size_t character_limit = EQEmu::constants::Lookup(eqs->ClientVersion())->CharacterCreationLimit; - if (character_limit > EQEmu::constants::CharacterCreationMax) { character_limit = EQEmu::constants::CharacterCreationMax; } - if (eqs->ClientVersion() == EQEmu::versions::ClientVersion::Titanium) { character_limit = 8; } + if (character_limit > EQEmu::constants::CHARACTER_CREATION_LIMIT) { character_limit = EQEmu::constants::CHARACTER_CREATION_LIMIT; } + if (eqs->ClientVersion() == EQEmu::versions::ClientVersion::Titanium) { character_limit = Titanium::constants::CHARACTER_CREATION_LIMIT; } std::string tgh_query = StringFormat( "SELECT " diff --git a/world/net.cpp b/world/net.cpp index c9a3f134c..7065ea6c3 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -85,6 +85,7 @@ union semun { #include "console.h" #include "../common/net/servertalk_server.h" +#include "../zone/data_bucket.h" ClientList client_list; GroupLFPList LFPGroupList; @@ -309,6 +310,9 @@ int main(int argc, char** argv) { } } + Log(Logs::General, Logs::World_Server, "Purging expired data buckets..."); + database.PurgeAllDeletedDataBuckets(); + Log(Logs::General, Logs::World_Server, "Loading zones.."); database.LoadZoneNames(); Log(Logs::General, Logs::World_Server, "Clearing groups.."); @@ -389,6 +393,7 @@ int main(int argc, char** argv) { Log(Logs::General, Logs::World_Server, "Purging expired instances"); database.PurgeExpiredInstances(); + Timer PurgeInstanceTimer(450000); PurgeInstanceTimer.Start(450000); @@ -545,9 +550,9 @@ int main(int argc, char** argv) { client_list.Process(); - if (PurgeInstanceTimer.Check()) - { + if (PurgeInstanceTimer.Check()) { database.PurgeExpiredInstances(); + database.PurgeAllDeletedDataBuckets(); } if (EQTimeTimer.Check()) { diff --git a/world/worlddb.cpp b/world/worlddb.cpp index cbf901cf7..67b0eab38 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -39,8 +39,8 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou size_t character_limit = EQEmu::constants::Lookup(client_version)->CharacterCreationLimit; // Validate against absolute server max - if (character_limit > EQEmu::constants::CharacterCreationMax) - character_limit = EQEmu::constants::CharacterCreationMax; + if (character_limit > EQEmu::constants::CHARACTER_CREATION_LIMIT) + character_limit = EQEmu::constants::CHARACTER_CREATION_LIMIT; // Force Titanium clients to use '8' if (client_version == EQEmu::versions::ClientVersion::Titanium) diff --git a/world/zonelist.cpp b/world/zonelist.cpp index d86f727f6..db831e941 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -43,6 +43,7 @@ ZSList::ZSList() memset(pLockedZones, 0, sizeof(pLockedZones)); m_tick.reset(new EQ::Timer(5000, true, std::bind(&ZSList::OnTick, this, std::placeholders::_1))); + m_keepalive.reset(new EQ::Timer(2500, true, std::bind(&ZSList::OnKeepAlive, this, std::placeholders::_1))); } ZSList::~ZSList() { @@ -745,4 +746,11 @@ void ZSList::OnTick(EQ::Timer *t) } web_interface.SendEvent(out); -} \ No newline at end of file +} + +void ZSList::OnKeepAlive(EQ::Timer *t) +{ + for (auto &zone : list) { + zone->SendKeepAlive(); + } +} diff --git a/world/zonelist.h b/world/zonelist.h index 9911b87e0..c63e1686b 100644 --- a/world/zonelist.h +++ b/world/zonelist.h @@ -63,6 +63,7 @@ public: private: void OnTick(EQ::Timer *t); + void OnKeepAlive(EQ::Timer *t); uint32 NextID; std::list> list; uint16 pLockedZones[MaxLockedZones]; @@ -70,6 +71,7 @@ private: uint16 LastAllocatedPort; std::unique_ptr m_tick; + std::unique_ptr m_keepalive; }; #endif /*ZONELIST_H_*/ diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index e685b280e..263aeee2f 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1400,6 +1400,13 @@ void ZoneServer::SendGroupIDs() { delete pack; } + +void ZoneServer::SendKeepAlive() +{ + ServerPacket pack(ServerOP_KeepAlive, 0); + SendPacket(&pack); +} + void ZoneServer::ChangeWID(uint32 iCharID, uint32 iWID) { auto pack = new ServerPacket(ServerOP_ChangeWID, sizeof(ServerChangeWID_Struct)); ServerChangeWID_Struct* scw = (ServerChangeWID_Struct*)pack->pBuffer; diff --git a/world/zoneserver.h b/world/zoneserver.h index 1f9e9516c..f5d7296df 100644 --- a/world/zoneserver.h +++ b/world/zoneserver.h @@ -39,6 +39,7 @@ public: void SendPacket(ServerPacket* pack) { tcpc->SendPacket(pack); } void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...); void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message); + void SendKeepAlive(); bool SetZone(uint32 iZoneID, uint32 iInstanceID = 0, bool iStaticZone = false); void TriggerBootup(uint32 iZoneID = 0, uint32 iInstanceID = 0, const char* iAdminName = 0, bool iMakeStatic = false); void Disconnect() { auto handle = tcpc->Handle(); if (handle) { handle->Disconnect(); } } diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index b10ab32a0..0414a8d2b 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -19,6 +19,7 @@ SET(zone_sources client_process.cpp command.cpp corpse.cpp + data_bucket.cpp doors.cpp effects.cpp embparser.cpp @@ -87,6 +88,10 @@ SET(zone_sources npc_ai.cpp object.cpp oriented_bounding_box.cpp + pathfinder_interface.cpp + pathfinder_nav_mesh.cpp + pathfinder_null.cpp + pathfinder_waypoint.cpp pathing.cpp perl_client.cpp perl_doors.cpp @@ -151,6 +156,7 @@ SET(zone_headers command.h common.h corpse.h + data_bucket.h doors.h embparser.h embperl.h @@ -203,7 +209,10 @@ SET(zone_headers npc_ai.h object.h oriented_bounding_box.h - pathing.h + pathfinder_interface.h + pathfinder_nav_mesh.h + pathfinder_null.h + pathfinder_waypoint.h perlpacket.h petitions.h pets.h @@ -250,7 +259,7 @@ TARGET_LINK_LIBRARIES(zone ${SERVER_LIBS}) IF(EQEMU_BUILD_PERL) TARGET_LINK_LIBRARIES(zone ${PERL_LIBRARY}) -ENDIF(EQEMU_BUILD_PERL) +ENDIF() IF(EQEMU_BUILD_LUA) TARGET_LINK_LIBRARIES(zone luabind ${LUA_LIBRARY}) diff --git a/zone/aa.cpp b/zone/aa.cpp index 38d477fb8..9fa76a9d4 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -435,7 +435,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) //gear stuff, need to make sure there's //no situation where this stuff can be duped - for (int x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::EQUIPMENT_END; x++) // (< 21) added MainAmmo + for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) { uint32 sitem = 0; sitem = CorpseToUse->GetWornItem(x); diff --git a/zone/aggro.cpp b/zone/aggro.cpp index d73b96f6f..91d14498f 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -931,7 +931,9 @@ bool Mob::CombatRange(Mob* other) if (size_mod > 10000) size_mod = size_mod / 7; - float _DistNoRoot = DistanceSquared(m_Position, other->GetPosition()); + float _DistNoRoot = DistanceSquaredNoZ(m_Position, other->GetPosition()); + float _zDist = m_Position.z - other->GetZ(); + _zDist *= _zDist; if (GetSpecialAbility(NPC_CHASE_DISTANCE)){ @@ -960,6 +962,11 @@ bool Mob::CombatRange(Mob* other) if (_DistNoRoot <= size_mod) { + //A hack to kill an exploit till we get something better. + if (flymode == 0 && _zDist > 500 && !CheckLastLosState()) { + return false; + } + return true; } return false; diff --git a/zone/attack.cpp b/zone/attack.cpp index 817a8e359..a48d68934 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -136,7 +136,7 @@ EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstanc } // If we're attacking with the secondary hand, play the dual wield anim - if (Hand == EQEmu::inventory::slotSecondary) // DW anim + if (Hand == EQEmu::invslot::slotSecondary) // DW anim type = animDualWield; DoAnim(type, 0, false); @@ -386,7 +386,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit) // riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo bool ImmuneRipo = attacker->aabonuses.RiposteChance || attacker->spellbonuses.RiposteChance || attacker->itembonuses.RiposteChance || attacker->IsEnraged(); // Need to check if we have something in MainHand to actually attack with (or fists) - if (hit.hand != EQEmu::inventory::slotRange && (CanThisClassRiposte() || IsEnraged()) && InFront && !ImmuneRipo) { + if (hit.hand != EQEmu::invslot::slotRange && (CanThisClassRiposte() || IsEnraged()) && InFront && !ImmuneRipo) { if (IsEnraged()) { hit.damage_done = DMG_RIPOSTED; Log(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack."); @@ -408,7 +408,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit) chance -= chance * counter; } // AA Slippery Attacks - if (hit.hand == EQEmu::inventory::slotSecondary) { + if (hit.hand == EQEmu::invslot::slotSecondary) { int slip = aabonuses.OffhandRiposteFail + itembonuses.OffhandRiposteFail + spellbonuses.OffhandRiposteFail; chance += chance * slip / 100; } @@ -453,7 +453,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit) } // parry - if (CanThisClassParry() && InFront && hit.hand != EQEmu::inventory::slotRange) { + if (CanThisClassParry() && InFront && hit.hand != EQEmu::invslot::slotRange) { if (IsClient()) CastToClient()->CheckIncreaseSkill(EQEmu::skills::SkillParry, other, -10); // check auto discs ... I guess aa/items too :P @@ -783,7 +783,7 @@ int Mob::ACSum() int shield_ac = 0; if (HasShieldEquiped() && IsClient()) { auto client = CastToClient(); - auto inst = client->GetInv().GetItem(EQEmu::inventory::slotSecondary); + auto inst = client->GetInv().GetItem(EQEmu::invslot::slotSecondary); if (inst) { if (inst->GetItemRecommendedLevel(true) <= GetLevel()) shield_ac = inst->GetItemArmorClass(true); @@ -1111,7 +1111,7 @@ int Mob::GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, u else { bool MagicGloves = false; if (IsClient()) { - const EQEmu::ItemInstance *gloves = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotHands); + const EQEmu::ItemInstance *gloves = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotHands); if (gloves) MagicGloves = gloves->GetItemMagical(true); } @@ -1397,12 +1397,12 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b return false; // Rogean: How can you attack while feigned? Moved up from Aggro Code. EQEmu::ItemInstance* weapon = nullptr; - if (Hand == EQEmu::inventory::slotSecondary) { // Kaiyodo - Pick weapon from the attacking hand - weapon = GetInv().GetItem(EQEmu::inventory::slotSecondary); + if (Hand == EQEmu::invslot::slotSecondary) { // Kaiyodo - Pick weapon from the attacking hand + weapon = GetInv().GetItem(EQEmu::invslot::slotSecondary); OffHandAtk(true); } else { - weapon = GetInv().GetItem(EQEmu::inventory::slotPrimary); + weapon = GetInv().GetItem(EQEmu::invslot::slotPrimary); OffHandAtk(false); } @@ -1440,10 +1440,10 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b if (my_hit.base_damage > 0) { // if we revamp this function be more general, we will have to make sure this isn't // executed for anything BUT normal melee damage weapons from auto attack - if (Hand == EQEmu::inventory::slotPrimary || Hand == EQEmu::inventory::slotSecondary) + if (Hand == EQEmu::invslot::slotPrimary || Hand == EQEmu::invslot::slotSecondary) my_hit.base_damage = DoDamageCaps(my_hit.base_damage); auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod; - if (shield_inc > 0 && HasShieldEquiped() && Hand == EQEmu::inventory::slotPrimary) { + if (shield_inc > 0 && HasShieldEquiped() && Hand == EQEmu::invslot::slotPrimary) { my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100; hate = hate * (100 + shield_inc) / 100; } @@ -1465,7 +1465,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b int ucDamageBonus = 0; - if (Hand == EQEmu::inventory::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) + if (Hand == EQEmu::invslot::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) { // Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above // who belong to a melee class. If we're here, then all of these conditions apply. @@ -1477,7 +1477,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b } #endif //Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon. - if (Hand == EQEmu::inventory::slotSecondary) { + if (Hand == EQEmu::invslot::slotSecondary) { if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc) { ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr, true); @@ -1927,28 +1927,28 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool my_hit.skill = EQEmu::skills::SkillHandtoHand; my_hit.hand = Hand; my_hit.damage_done = 1; - if (Hand == EQEmu::inventory::slotPrimary) { + if (Hand == EQEmu::invslot::slotPrimary) { my_hit.skill = static_cast(GetPrimSkill()); OffHandAtk(false); } - if (Hand == EQEmu::inventory::slotSecondary) { + if (Hand == EQEmu::invslot::slotSecondary) { my_hit.skill = static_cast(GetSecSkill()); OffHandAtk(true); } //figure out what weapon they are using, if any const EQEmu::ItemData* weapon = nullptr; - if (Hand == EQEmu::inventory::slotPrimary && equipment[EQEmu::inventory::slotPrimary] > 0) - weapon = database.GetItem(equipment[EQEmu::inventory::slotPrimary]); - else if (equipment[EQEmu::inventory::slotSecondary]) - weapon = database.GetItem(equipment[EQEmu::inventory::slotSecondary]); + if (Hand == EQEmu::invslot::slotPrimary && equipment[EQEmu::invslot::slotPrimary] > 0) + weapon = database.GetItem(equipment[EQEmu::invslot::slotPrimary]); + else if (equipment[EQEmu::invslot::slotSecondary]) + weapon = database.GetItem(equipment[EQEmu::invslot::slotSecondary]); //We dont factor much from the weapon into the attack. //Just the skill type so it doesn't look silly using punching animations and stuff while wielding weapons if (weapon) { Log(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID); - if (Hand == EQEmu::inventory::slotSecondary && weapon->ItemType == EQEmu::item::ItemTypeShield) { + if (Hand == EQEmu::invslot::slotSecondary && weapon->ItemType == EQEmu::item::ItemTypeShield) { Log(Logs::Detail, Logs::Combat, "Attack with shield canceled."); return false; } @@ -3896,7 +3896,7 @@ void Mob::TryDefensiveProc(Mob *on, uint16 hand) { float ProcChance, ProcBonus; on->GetDefensiveProcChances(ProcBonus, ProcChance, hand, this); - if (hand != EQEmu::inventory::slotPrimary) + if (hand != EQEmu::invslot::slotPrimary) ProcChance /= 2; int level_penalty = 0; @@ -3969,7 +3969,7 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData * ProcBonus += static_cast(itembonuses.ProcChance) / 10.0f; // Combat Effects float ProcChance = GetProcChances(ProcBonus, hand); - if (hand != EQEmu::inventory::slotPrimary) //Is Archery intened to proc at 50% rate? + if (hand != EQEmu::invslot::slotPrimary) //Is Archery intened to proc at 50% rate? ProcChance /= 2; // Try innate proc on weapon @@ -4008,7 +4008,7 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData * proced = false; if (!proced && inst) { - for (int r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) { + for (int r = EQEmu::invaug::SOCKET_BEGIN; r <= EQEmu::invaug::SOCKET_END; r++) { const EQEmu::ItemInstance *aug_i = inst->GetAugment(r); if (!aug_i) // no aug, try next slot! continue; @@ -4051,11 +4051,11 @@ void Mob::TrySpellProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData *w float ProcChance = 0.0f; ProcChance = GetProcChances(ProcBonus, hand); - if (hand != EQEmu::inventory::slotPrimary) //Is Archery intened to proc at 50% rate? + if (hand != EQEmu::invslot::slotPrimary) //Is Archery intened to proc at 50% rate? ProcChance /= 2; bool rangedattk = false; - if (weapon && hand == EQEmu::inventory::slotRange) { + if (weapon && hand == EQEmu::invslot::slotRange) { if (weapon->ItemType == EQEmu::item::ItemTypeArrow || weapon->ItemType == EQEmu::item::ItemTypeLargeThrowing || weapon->ItemType == EQEmu::item::ItemTypeSmallThrowing || @@ -4064,11 +4064,11 @@ void Mob::TrySpellProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData *w } } - if (!weapon && hand == EQEmu::inventory::slotRange && GetSpecialAbility(SPECATK_RANGED_ATK)) + if (!weapon && hand == EQEmu::invslot::slotRange && GetSpecialAbility(SPECATK_RANGED_ATK)) rangedattk = true; for (uint32 i = 0; i < MAX_PROCS; i++) { - if (IsPet() && hand != EQEmu::inventory::slotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets) + if (IsPet() && hand != EQEmu::invslot::slotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets) continue; // If pets ever can proc from off hand, this will need to change // Not ranged @@ -4128,7 +4128,7 @@ void Mob::TrySpellProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData *w } } - if (HasSkillProcs() && hand != EQEmu::inventory::slotRange) { //We check ranged skill procs within the attack functions. + if (HasSkillProcs() && hand != EQEmu::invslot::slotRange) { //We check ranged skill procs within the attack functions. uint16 skillinuse = 28; if (weapon) skillinuse = GetSkillByItemType(weapon->ItemType); @@ -4451,7 +4451,7 @@ void Mob::DoRiposte(Mob *defender) return; } - defender->Attack(this, EQEmu::inventory::slotPrimary, true); + defender->Attack(this, EQEmu::invslot::slotPrimary, true); if (HasDied()) return; @@ -4462,7 +4462,7 @@ void Mob::DoRiposte(Mob *defender) if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) { Log(Logs::Detail, Logs::Combat, "Preforming a double riposted from SE_DoubleRiposte (%d percent chance)", DoubleRipChance); - defender->Attack(this, EQEmu::inventory::slotPrimary, true); + defender->Attack(this, EQEmu::invslot::slotPrimary, true); if (HasDied()) return; } @@ -4475,7 +4475,7 @@ void Mob::DoRiposte(Mob *defender) Log(Logs::Detail, Logs::Combat, "Preforming a double riposted from SE_GiveDoubleRiposte base1 == 0 (%d percent chance)", DoubleRipChance); - defender->Attack(this, EQEmu::inventory::slotPrimary, true); + defender->Attack(this, EQEmu::invslot::slotPrimary, true); if (HasDied()) return; } @@ -4888,7 +4888,7 @@ float Mob::GetSkillProcChances(uint16 ReuseTime, uint16 hand) { if (!ReuseTime && hand) { weapon_speed = GetWeaponSpeedbyHand(hand); ProcChance = static_cast(weapon_speed) * (RuleR(Combat, AvgProcsPerMinute) / 60000.0f); - if (hand != EQEmu::inventory::slotPrimary) + if (hand != EQEmu::invslot::slotPrimary) ProcChance /= 2; } @@ -5182,13 +5182,13 @@ void Client::SetAttackTimer() Timer *TimerToUse = nullptr; - for (int i = EQEmu::inventory::slotRange; i <= EQEmu::inventory::slotSecondary; i++) { + for (int i = EQEmu::invslot::slotRange; i <= EQEmu::invslot::slotSecondary; i++) { //pick a timer - if (i == EQEmu::inventory::slotPrimary) + if (i == EQEmu::invslot::slotPrimary) TimerToUse = &attack_timer; - else if (i == EQEmu::inventory::slotRange) + else if (i == EQEmu::invslot::slotRange) TimerToUse = &ranged_timer; - else if (i == EQEmu::inventory::slotSecondary) + else if (i == EQEmu::invslot::slotSecondary) TimerToUse = &attack_dw_timer; else //invalid slot (hands will always hit this) continue; @@ -5201,7 +5201,7 @@ void Client::SetAttackTimer() ItemToUse = ci->GetItem(); //special offhand stuff - if (i == EQEmu::inventory::slotSecondary) { + if (i == EQEmu::invslot::slotSecondary) { //if we cant dual wield, skip it if (!CanThisClassDualWield() || HasTwoHanderEquipped()) { attack_dw_timer.Disable(); @@ -5276,19 +5276,19 @@ void NPC::SetAttackTimer() else speed = static_cast((attack_delay / haste_mod) + ((hhe / 100.0f) * attack_delay)); - for (int i = EQEmu::inventory::slotRange; i <= EQEmu::inventory::slotSecondary; i++) { + for (int i = EQEmu::invslot::slotRange; i <= EQEmu::invslot::slotSecondary; i++) { //pick a timer - if (i == EQEmu::inventory::slotPrimary) + if (i == EQEmu::invslot::slotPrimary) TimerToUse = &attack_timer; - else if (i == EQEmu::inventory::slotRange) + else if (i == EQEmu::invslot::slotRange) TimerToUse = &ranged_timer; - else if (i == EQEmu::inventory::slotSecondary) + else if (i == EQEmu::invslot::slotSecondary) TimerToUse = &attack_dw_timer; else //invalid slot (hands will always hit this) continue; //special offhand stuff - if (i == EQEmu::inventory::slotSecondary) { + if (i == EQEmu::invslot::slotSecondary) { // SPECATK_QUAD is uncheesable if (!CanThisClassDualWield() || (HasTwoHanderEquipped() && !GetSpecialAbility(SPECATK_QUAD))) { attack_dw_timer.Disable(); @@ -5310,7 +5310,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell) bool candouble = CanThisClassDoubleAttack(); // extra off hand non-sense, can only double with skill of 150 or above // or you have any amount of GiveDoubleAttack - if (candouble && hand == EQEmu::inventory::slotSecondary) + if (candouble && hand == EQEmu::invslot::slotSecondary) candouble = GetSkill(EQEmu::skills::SkillDoubleAttack) > 149 || (aabonuses.GiveDoubleAttack + spellbonuses.GiveDoubleAttack + itembonuses.GiveDoubleAttack) > 0; @@ -5321,7 +5321,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell) Attack(target, hand, false, false, IsFromSpell); // Modern AA description: Increases your chance of ... performing one additional hit with a 2-handed weapon when double attacking by 2%. - if (hand == EQEmu::inventory::slotPrimary) { + if (hand == EQEmu::invslot::slotPrimary) { auto extraattackchance = aabonuses.ExtraAttackChance + spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance; if (extraattackchance && HasTwoHanderEquipped() && zone->random.Roll(extraattackchance)) @@ -5329,7 +5329,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell) } // you can only triple from the main hand - if (hand == EQEmu::inventory::slotPrimary && CanThisClassTripleAttack()) { + if (hand == EQEmu::invslot::slotPrimary && CanThisClassTripleAttack()) { CheckIncreaseSkill(EQEmu::skills::SkillTripleAttack, target, -10); if (CheckTripleAttack()) { Attack(target, hand, false, false, IsFromSpell); @@ -5383,9 +5383,9 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts) if (RuleB(Combat, UseLiveCombatRounds)) { // A "quad" on live really is just a successful dual wield where both double attack // The mobs that could triple lost the ability to when the triple attack skill was added in - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); if (CanThisClassDoubleAttack() && CheckDoubleAttack()) { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { int chance = spellbonuses.PC_Pet_Flurry + itembonuses.PC_Pet_Flurry + aabonuses.PC_Pet_Flurry; if (chance && zone->random.Roll(chance)) @@ -5398,16 +5398,16 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts) if (IsNPC()) { int16 n_atk = CastToNPC()->GetNumberOfAttacks(); if (n_atk <= 1) { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); } else { for (int i = 0; i < n_atk; ++i) { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); } } } else { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); } // we use this random value in three comparisons with different @@ -5418,15 +5418,15 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts) // check double attack, this is NOT the same rules that clients use... && RandRoll < (GetLevel() + NPCDualAttackModifier)) { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); // lets see if we can do a triple attack with the main hand // pets are excluded from triple and quads... if ((GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD)) && !IsPet() && RandRoll < (GetLevel() + NPCTripleAttackModifier)) { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); // now lets check the quad attack if (GetSpecialAbility(SPECATK_QUAD) && RandRoll < (GetLevel() + NPCQuadAttackModifier)) { - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); } } } @@ -5442,9 +5442,9 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts) (RuleB(Combat, UseLiveCombatRounds) && GetSpecialAbility(SPECATK_QUAD))) || GetEquipment(EQEmu::textures::weaponSecondary) != 0) { if (CheckDualWield()) { - Attack(target, EQEmu::inventory::slotSecondary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotSecondary, false, false, false, opts); if (CanThisClassDoubleAttack() && GetLevel() > 35 && CheckDoubleAttack()) { - Attack(target, EQEmu::inventory::slotSecondary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotSecondary, false, false, false, opts); if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { int chance = spellbonuses.PC_Pet_Flurry + itembonuses.PC_Pet_Flurry + aabonuses.PC_Pet_Flurry; diff --git a/zone/beacon.h b/zone/beacon.h index c22189dfd..3e8f6edcc 100644 --- a/zone/beacon.h +++ b/zone/beacon.h @@ -36,7 +36,7 @@ public: //abstract virtual function implementations requird by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; } virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; } - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } virtual bool HasRaid() { return false; } virtual bool HasGroup() { return false; } diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index c444ff9dd..b6de679d1 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -161,35 +161,35 @@ void Client::CalcItemBonuses(StatBonuses* newbon) { unsigned int i; // Update: MainAmmo should only calc skill mods (TODO: Check for other cases) - for (i = EQEmu::inventory::slotCharm; i <= EQEmu::inventory::slotAmmo; i++) { + for (i = EQEmu::invslot::BONUS_BEGIN; i <= EQEmu::invslot::BONUS_SKILL_END; i++) { const EQEmu::ItemInstance* inst = m_inv[i]; if(inst == 0) continue; - AddItemBonuses(inst, newbon, false, false, 0, (i == EQEmu::inventory::slotAmmo)); + AddItemBonuses(inst, newbon, false, false, 0, (i == EQEmu::invslot::slotAmmo)); //These are given special flags due to how often they are checked for various spell effects. const EQEmu::ItemData *item = inst->GetItem(); - if (i == EQEmu::inventory::slotSecondary && (item && item->ItemType == EQEmu::item::ItemTypeShield)) + if (i == EQEmu::invslot::slotSecondary && (item && item->ItemType == EQEmu::item::ItemTypeShield)) SetShieldEquiped(true); - else if (i == EQEmu::inventory::slotPrimary && (item && item->ItemType == EQEmu::item::ItemType2HBlunt)) { + else if (i == EQEmu::invslot::slotPrimary && (item && item->ItemType == EQEmu::item::ItemType2HBlunt)) { SetTwoHandBluntEquiped(true); SetTwoHanderEquipped(true); } - else if (i == EQEmu::inventory::slotPrimary && (item && (item->ItemType == EQEmu::item::ItemType2HSlash || item->ItemType == EQEmu::item::ItemType2HPiercing))) + else if (i == EQEmu::invslot::slotPrimary && (item && (item->ItemType == EQEmu::item::ItemType2HSlash || item->ItemType == EQEmu::item::ItemType2HPiercing))) SetTwoHanderEquipped(true); } //Power Source Slot if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - const EQEmu::ItemInstance* inst = m_inv[EQEmu::inventory::slotPowerSource]; + const EQEmu::ItemInstance* inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]; if(inst) AddItemBonuses(inst, newbon); } //tribute items - for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++) { - const EQEmu::ItemInstance* inst = m_inv[EQEmu::legacy::TRIBUTE_BEGIN + i]; + for (i = EQEmu::invslot::TRIBUTE_BEGIN; i <= EQEmu::invslot::TRIBUTE_END; i++) { + const EQEmu::ItemInstance* inst = m_inv[i]; if(inst == 0) continue; AddItemBonuses(inst, newbon, false, true); @@ -197,7 +197,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) { //Optional ability to have worn effects calculate as an addititive bonus instead of highest value if (RuleI(Spells, AdditiveBonusWornType) && RuleI(Spells, AdditiveBonusWornType) != EQEmu::item::ItemEffectWorn){ - for (i = EQEmu::inventory::slotCharm; i < EQEmu::inventory::slotAmmo; i++) { + for (i = EQEmu::invslot::BONUS_BEGIN; i <= EQEmu::invslot::BONUS_STAT_END; i++) { const EQEmu::ItemInstance* inst = m_inv[i]; if(inst == 0) continue; @@ -543,7 +543,7 @@ void Client::AddItemBonuses(const EQEmu::ItemInstance *inst, StatBonuses *newbon } if (!isAug) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) AddItemBonuses(inst->GetAugment(i), newbon, true, false, rec_level, ammo_slot_item); } } @@ -581,7 +581,7 @@ void Client::AdditiveWornBonuses(const EQEmu::ItemInstance *inst, StatBonuses* n if (!isAug) { int i; - for (i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { AdditiveWornBonuses(inst->GetAugment(i),newbon,true); } } @@ -592,32 +592,32 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) { bool food = false; bool drink = false; - for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_BAGS_BEGIN; i++) + for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) { if (food && drink) break; const EQEmu::ItemInstance* inst = GetInv().GetItem(i); if (inst && inst->GetItem() && inst->IsClassCommon()) { const EQEmu::ItemData *item = inst->GetItem(); - if (item->ItemType == EQEmu::item::ItemTypeFood && !food) + if (!food && item->ItemType == EQEmu::item::ItemTypeFood) food = true; - else if (item->ItemType == EQEmu::item::ItemTypeDrink && !drink) + else if (!drink && item->ItemType == EQEmu::item::ItemTypeDrink) drink = true; else continue; AddItemBonuses(inst, newbon); } } - for (i = EQEmu::legacy::GENERAL_BAGS_BEGIN; i <= EQEmu::legacy::GENERAL_BAGS_END; i++) + for (i = EQEmu::invbag::GENERAL_BAGS_BEGIN; i <= EQEmu::invbag::GENERAL_BAGS_END; i++) { if (food && drink) break; const EQEmu::ItemInstance* inst = GetInv().GetItem(i); if (inst && inst->GetItem() && inst->IsClassCommon()) { const EQEmu::ItemData *item = inst->GetItem(); - if (item->ItemType == EQEmu::item::ItemTypeFood && !food) + if (!food && item->ItemType == EQEmu::item::ItemTypeFood) food = true; - else if (item->ItemType == EQEmu::item::ItemTypeDrink && !drink) + else if (!drink && item->ItemType == EQEmu::item::ItemTypeDrink) drink = true; else continue; @@ -3261,7 +3261,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon) { if(newbon){ - for (int i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++){ + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++){ const EQEmu::ItemData *cur = database.GetItem(equipment[i]); if(cur){ //basic stats @@ -3339,24 +3339,24 @@ void Client::CalcItemScale() { bool changed = false; // MainAmmo excluded in helper function below - if (CalcItemScale(EQEmu::legacy::EQUIPMENT_BEGIN, EQEmu::legacy::EQUIPMENT_END)) // original coding excluded MainAmmo (< 21) + if (CalcItemScale(EQEmu::invslot::EQUIPMENT_BEGIN, EQEmu::invslot::EQUIPMENT_END)) // original coding excluded MainAmmo (< 21) changed = true; - if (CalcItemScale(EQEmu::legacy::GENERAL_BEGIN, EQEmu::legacy::GENERAL_END)) // original coding excluded MainCursor (< 30) + if (CalcItemScale(EQEmu::invslot::GENERAL_BEGIN, EQEmu::invslot::GENERAL_END)) // original coding excluded MainCursor (< 30) changed = true; // I excluded cursor bag slots here because cursor was excluded above..if this is incorrect, change 'slot_y' here to CURSOR_BAG_END // and 'slot_y' above to CURSOR from GENERAL_END above - or however it is supposed to be... - if (CalcItemScale(EQEmu::legacy::GENERAL_BAGS_BEGIN, EQEmu::legacy::GENERAL_BAGS_END)) // (< 341) + if (CalcItemScale(EQEmu::invbag::GENERAL_BAGS_BEGIN, EQEmu::invbag::GENERAL_BAGS_END)) // (< 341) changed = true; - if (CalcItemScale(EQEmu::legacy::TRIBUTE_BEGIN, EQEmu::legacy::TRIBUTE_END)) // (< 405) + if (CalcItemScale(EQEmu::invslot::TRIBUTE_BEGIN, EQEmu::invslot::TRIBUTE_END)) // (< 405) changed = true; //Power Source Slot if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - if (CalcItemScale(EQEmu::inventory::slotPowerSource, EQEmu::inventory::slotPowerSource)) + if (CalcItemScale(EQEmu::invslot::SLOT_POWER_SOURCE, EQEmu::invslot::SLOT_POWER_SOURCE)) changed = true; } @@ -3371,7 +3371,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) { bool changed = false; uint32 i; for (i = slot_x; i <= slot_y; i++) { - if (i == EQEmu::inventory::slotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot + if (i == EQEmu::invslot::slotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot continue; EQEmu::ItemInstance* inst = m_inv.GetItem(i); @@ -3381,7 +3381,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) { // TEST CODE: test for bazaar trader crashing with charm items if (Trader) - if (i >= EQEmu::legacy::GENERAL_BAGS_BEGIN && i <= EQEmu::legacy::GENERAL_BAGS_END) { + if (i >= EQEmu::invbag::GENERAL_BAGS_BEGIN && i <= EQEmu::invbag::GENERAL_BAGS_END) { EQEmu::ItemInstance* parent_item = m_inv.GetItem(EQEmu::InventoryProfile::CalcSlotId(i)); if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel continue; @@ -3401,7 +3401,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) { } //iterate all augments - for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x) + for (int x = EQEmu::invaug::SOCKET_BEGIN; x <= EQEmu::invaug::SOCKET_END; ++x) { EQEmu::ItemInstance * a_inst = inst->GetAugment(x); if(!a_inst) @@ -3433,24 +3433,24 @@ void Client::DoItemEnterZone() { bool changed = false; // MainAmmo excluded in helper function below - if (DoItemEnterZone(EQEmu::legacy::EQUIPMENT_BEGIN, EQEmu::legacy::EQUIPMENT_END)) // original coding excluded MainAmmo (< 21) + if (DoItemEnterZone(EQEmu::invslot::EQUIPMENT_BEGIN, EQEmu::invslot::EQUIPMENT_END)) // original coding excluded MainAmmo (< 21) changed = true; - if (DoItemEnterZone(EQEmu::legacy::GENERAL_BEGIN, EQEmu::legacy::GENERAL_END)) // original coding excluded MainCursor (< 30) + if (DoItemEnterZone(EQEmu::invslot::GENERAL_BEGIN, EQEmu::invslot::GENERAL_END)) // original coding excluded MainCursor (< 30) changed = true; // I excluded cursor bag slots here because cursor was excluded above..if this is incorrect, change 'slot_y' here to CURSOR_BAG_END // and 'slot_y' above to CURSOR from GENERAL_END above - or however it is supposed to be... - if (DoItemEnterZone(EQEmu::legacy::GENERAL_BAGS_BEGIN, EQEmu::legacy::GENERAL_BAGS_END)) // (< 341) + if (DoItemEnterZone(EQEmu::invbag::GENERAL_BAGS_BEGIN, EQEmu::invbag::GENERAL_BAGS_END)) // (< 341) changed = true; - if (DoItemEnterZone(EQEmu::legacy::TRIBUTE_BEGIN, EQEmu::legacy::TRIBUTE_END)) // (< 405) + if (DoItemEnterZone(EQEmu::invslot::TRIBUTE_BEGIN, EQEmu::invslot::TRIBUTE_END)) // (< 405) changed = true; //Power Source Slot if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - if (DoItemEnterZone(EQEmu::inventory::slotPowerSource, EQEmu::inventory::slotPowerSource)) + if (DoItemEnterZone(EQEmu::invslot::SLOT_POWER_SOURCE, EQEmu::invslot::SLOT_POWER_SOURCE)) changed = true; } @@ -3464,7 +3464,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1 bool changed = false; for(uint32 i = slot_x; i <= slot_y; i++) { - if (i == EQEmu::inventory::slotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot + if (i == EQEmu::invslot::slotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot continue; EQEmu::ItemInstance* inst = m_inv.GetItem(i); @@ -3474,7 +3474,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { // TEST CODE: test for bazaar trader crashing with charm items if (Trader) - if (i >= EQEmu::legacy::GENERAL_BAGS_BEGIN && i <= EQEmu::legacy::GENERAL_BAGS_END) { + if (i >= EQEmu::invbag::GENERAL_BAGS_BEGIN && i <= EQEmu::invbag::GENERAL_BAGS_END) { EQEmu::ItemInstance* parent_item = m_inv.GetItem(EQEmu::InventoryProfile::CalcSlotId(i)); if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel continue; @@ -3486,7 +3486,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { uint16 oldexp = inst->GetExp(); parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, inst, nullptr, "", 0); - if (i <= EQEmu::inventory::slotAmmo || i == EQEmu::inventory::slotPowerSource) { + if (i <= EQEmu::invslot::slotAmmo || i == EQEmu::invslot::SLOT_POWER_SOURCE) { parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i); } @@ -3496,7 +3496,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { update_slot = true; } } else { - if (i <= EQEmu::inventory::slotAmmo || i == EQEmu::inventory::slotPowerSource) { + if (i <= EQEmu::invslot::slotAmmo || i == EQEmu::invslot::SLOT_POWER_SOURCE) { parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i); } @@ -3504,7 +3504,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { } //iterate all augments - for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x) + for (int x = EQEmu::invaug::SOCKET_BEGIN; x <= EQEmu::invaug::SOCKET_END; ++x) { EQEmu::ItemInstance *a_inst = inst->GetAugment(x); if(!a_inst) diff --git a/zone/bot.cpp b/zone/bot.cpp index 01bbb1593..6d39a7df9 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -243,8 +243,8 @@ void Bot::SetBotSpellID(uint32 newSpellID) { } uint32 Bot::GetBotArcheryRange() { - const EQEmu::ItemInstance *range_inst = GetBotItem(EQEmu::inventory::slotRange); - const EQEmu::ItemInstance *ammo_inst = GetBotItem(EQEmu::inventory::slotAmmo); + const EQEmu::ItemInstance *range_inst = GetBotItem(EQEmu::invslot::slotRange); + const EQEmu::ItemInstance *ammo_inst = GetBotItem(EQEmu::invslot::slotAmmo); if (!range_inst || !ammo_inst) return 0; @@ -260,15 +260,15 @@ uint32 Bot::GetBotArcheryRange() { void Bot::ChangeBotArcherWeapons(bool isArcher) { if((GetClass()==WARRIOR) || (GetClass()==PALADIN) || (GetClass()==RANGER) || (GetClass()==SHADOWKNIGHT) || (GetClass()==ROGUE)) { if(!isArcher) { - BotAddEquipItem(EQEmu::inventory::slotPrimary, GetBotItemBySlot(EQEmu::inventory::slotPrimary)); - BotAddEquipItem(EQEmu::inventory::slotSecondary, GetBotItemBySlot(EQEmu::inventory::slotSecondary)); + BotAddEquipItem(EQEmu::invslot::slotPrimary, GetBotItemBySlot(EQEmu::invslot::slotPrimary)); + BotAddEquipItem(EQEmu::invslot::slotSecondary, GetBotItemBySlot(EQEmu::invslot::slotSecondary)); SetAttackTimer(); BotGroupSay(this, "My blade is ready"); } else { - BotRemoveEquipItem(EQEmu::inventory::slotPrimary); - BotRemoveEquipItem(EQEmu::inventory::slotSecondary); - BotAddEquipItem(EQEmu::inventory::slotAmmo, GetBotItemBySlot(EQEmu::inventory::slotAmmo)); - BotAddEquipItem(EQEmu::inventory::slotSecondary, GetBotItemBySlot(EQEmu::inventory::slotRange)); + BotRemoveEquipItem(EQEmu::invslot::slotPrimary); + BotRemoveEquipItem(EQEmu::invslot::slotSecondary); + BotAddEquipItem(EQEmu::invslot::slotAmmo, GetBotItemBySlot(EQEmu::invslot::slotAmmo)); + BotAddEquipItem(EQEmu::invslot::slotSecondary, GetBotItemBySlot(EQEmu::invslot::slotRange)); SetAttackTimer(); BotGroupSay(this, "My bow is true and ready"); } @@ -1166,11 +1166,11 @@ int32 Bot::acmod() { uint16 Bot::GetPrimarySkillValue() { EQEmu::skills::SkillType skill = EQEmu::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill - bool equiped = m_inv.GetItem(EQEmu::inventory::slotPrimary); + bool equiped = m_inv.GetItem(EQEmu::invslot::slotPrimary); if(!equiped) skill = EQEmu::skills::SkillHandtoHand; else { - uint8 type = m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->ItemType; //is this the best way to do this? + uint8 type = m_inv.GetItem(EQEmu::invslot::slotPrimary)->GetItem()->ItemType; //is this the best way to do this? switch(type) { case EQEmu::item::ItemType1HSlash: skill = EQEmu::skills::Skill1HSlashing; @@ -1718,8 +1718,8 @@ bool Bot::LoadPet() if (!botdb.LoadPetBuffs(GetBotID(), pet_buffs)) bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetBuffs(), GetCleanName()); - uint32 pet_items[EQEmu::legacy::EQUIPMENT_SIZE]; - memset(pet_items, 0, (sizeof(uint32) * EQEmu::legacy::EQUIPMENT_SIZE)); + uint32 pet_items[EQEmu::invslot::EQUIPMENT_COUNT]; + memset(pet_items, 0, (sizeof(uint32) * EQEmu::invslot::EQUIPMENT_COUNT)); if (!botdb.LoadPetItems(GetBotID(), pet_items)) bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetItems(), GetCleanName()); @@ -1746,11 +1746,11 @@ bool Bot::SavePet() char* pet_name = new char[64]; SpellBuff_Struct pet_buffs[PET_BUFF_COUNT]; - uint32 pet_items[EQEmu::legacy::EQUIPMENT_SIZE]; + uint32 pet_items[EQEmu::invslot::EQUIPMENT_COUNT]; memset(pet_name, 0, 64); memset(pet_buffs, 0, (sizeof(SpellBuff_Struct) * PET_BUFF_COUNT)); - memset(pet_items, 0, (sizeof(uint32) * EQEmu::legacy::EQUIPMENT_SIZE)); + memset(pet_items, 0, (sizeof(uint32) * EQEmu::invslot::EQUIPMENT_COUNT)); pet_inst->GetPetState(pet_buffs, pet_items, pet_name); @@ -1904,12 +1904,12 @@ void Bot::BotRangedAttack(Mob* other) { return; } - EQEmu::ItemInstance* rangedItem = GetBotItem(EQEmu::inventory::slotRange); + EQEmu::ItemInstance* rangedItem = GetBotItem(EQEmu::invslot::slotRange); const EQEmu::ItemData* RangeWeapon = nullptr; if(rangedItem) RangeWeapon = rangedItem->GetItem(); - EQEmu::ItemInstance* ammoItem = GetBotItem(EQEmu::inventory::slotAmmo); + EQEmu::ItemInstance* ammoItem = GetBotItem(EQEmu::invslot::slotAmmo); const EQEmu::ItemData* Ammo = nullptr; if(ammoItem) Ammo = ammoItem->GetItem(); @@ -2003,19 +2003,19 @@ void Bot::ApplySpecialAttackMod(EQEmu::skills::SkillType skill, int32 &dmg, int3 case EQEmu::skills::SkillFlyingKick: case EQEmu::skills::SkillRoundKick: case EQEmu::skills::SkillKick: - item_slot = EQEmu::inventory::slotFeet; + item_slot = EQEmu::invslot::slotFeet; break; case EQEmu::skills::SkillBash: - item_slot = EQEmu::inventory::slotSecondary; + item_slot = EQEmu::invslot::slotSecondary; break; case EQEmu::skills::SkillDragonPunch: case EQEmu::skills::SkillEagleStrike: case EQEmu::skills::SkillTigerClaw: - item_slot = EQEmu::inventory::slotHands; + item_slot = EQEmu::invslot::slotHands; break; } - if (item_slot >= EQEmu::legacy::EQUIPMENT_BEGIN){ + if (item_slot >= EQEmu::invslot::EQUIPMENT_BEGIN){ const EQEmu::ItemInstance* inst = GetBotItem(item_slot); const EQEmu::ItemData* botweapon = nullptr; if(inst) @@ -2312,8 +2312,8 @@ void Bot::AI_Process() { bool atCombatRange = false; - const auto* p_item = GetBotItem(EQEmu::inventory::slotPrimary); - const auto* s_item = GetBotItem(EQEmu::inventory::slotSecondary); + const auto* p_item = GetBotItem(EQEmu::invslot::slotPrimary); + const auto* s_item = GetBotItem(EQEmu::invslot::slotSecondary); bool behind_mob = false; bool backstab_weapon = false; @@ -2508,7 +2508,7 @@ void Bot::AI_Process() { if (GetArchetype() == ARCHETYPE_CASTER || GetClass() == ROGUE) { if (tar_distance <= melee_distance_max) { if (PlotPositionAroundTarget(this, Goal.x, Goal.y, Goal.z)) { - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); return; } } @@ -2520,7 +2520,7 @@ void Bot::AI_Process() { if (caster_distance_min && tar_distance < caster_distance_min && !tar->IsFeared()) { // Caster back-off adjustment if (PlotPositionAroundTarget(this, Goal.x, Goal.y, Goal.z)) { if (DistanceSquared(Goal, tar->GetPosition()) <= caster_distance_max) { - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); return; } } @@ -2528,7 +2528,7 @@ void Bot::AI_Process() { else if (tar_distance < melee_distance_min) { // Melee back-off adjustment if (PlotPositionAroundTarget(this, Goal.x, Goal.y, Goal.z)) { if (DistanceSquared(Goal, tar->GetPosition()) <= melee_distance_max) { - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); return; } } @@ -2536,7 +2536,7 @@ void Bot::AI_Process() { else if (backstab_weapon && !behind_mob) { // Move the rogue to behind the mob if (PlotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z)) { if (DistanceSquared(Goal, tar->GetPosition()) <= melee_distance_max) { - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotRunspeed(), true, false); // rogues are agile enough to run in melee range + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetBotRunspeed(), true, false); // rogues are agile enough to run in melee range return; } } @@ -2547,7 +2547,7 @@ void Bot::AI_Process() { PlotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z)) // If we're behind the mob, we can attack when it's enraged { if (DistanceSquared(Goal, tar->GetPosition()) <= melee_distance_max) { - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetBotWalkspeed(), true, false); return; } } @@ -2589,31 +2589,31 @@ void Bot::AI_Process() { TEST_TARGET(); if (attack_timer.Check()) { // Process primary weapon attacks - Attack(tar, EQEmu::inventory::slotPrimary); + Attack(tar, EQEmu::invslot::slotPrimary); TEST_TARGET(); - TriggerDefensiveProcs(tar, EQEmu::inventory::slotPrimary, false); + TriggerDefensiveProcs(tar, EQEmu::invslot::slotPrimary, false); TEST_TARGET(); - TryWeaponProc(p_item, tar, EQEmu::inventory::slotPrimary); + TryWeaponProc(p_item, tar, EQEmu::invslot::slotPrimary); //bool tripleSuccess = false; TEST_TARGET(); if (CanThisClassDoubleAttack()) { if (CheckBotDoubleAttack()) - Attack(tar, EQEmu::inventory::slotPrimary, true); + Attack(tar, EQEmu::invslot::slotPrimary, true); TEST_TARGET(); if (GetSpecialAbility(SPECATK_TRIPLE) && CheckBotDoubleAttack(true)) { //tripleSuccess = true; - Attack(tar, EQEmu::inventory::slotPrimary, true); + Attack(tar, EQEmu::invslot::slotPrimary, true); } TEST_TARGET(); //quad attack, does this belong here?? if (GetSpecialAbility(SPECATK_QUAD) && CheckBotDoubleAttack(true)) - Attack(tar, EQEmu::inventory::slotPrimary, true); + Attack(tar, EQEmu::invslot::slotPrimary, true); } TEST_TARGET(); @@ -2622,10 +2622,10 @@ void Bot::AI_Process() { if (flurrychance) { if (zone->random.Int(0, 100) < flurrychance) { Message_StringID(MT_NPCFlurry, YOU_FLURRY); - Attack(tar, EQEmu::inventory::slotPrimary, false); + Attack(tar, EQEmu::invslot::slotPrimary, false); TEST_TARGET(); - Attack(tar, EQEmu::inventory::slotPrimary, false); + Attack(tar, EQEmu::invslot::slotPrimary, false); } } @@ -2634,7 +2634,7 @@ void Bot::AI_Process() { if (ExtraAttackChanceBonus) { if (p_item && p_item->GetItem()->IsType2HWeapon()) { if (zone->random.Int(0, 100) < ExtraAttackChanceBonus) - Attack(tar, EQEmu::inventory::slotPrimary, false); + Attack(tar, EQEmu::invslot::slotPrimary, false); } } } @@ -2666,15 +2666,15 @@ void Bot::AI_Process() { float random = zone->random.Real(0, 1); if (random < DualWieldProbability){ // Max 78% of DW - Attack(tar, EQEmu::inventory::slotSecondary); // Single attack with offhand + Attack(tar, EQEmu::invslot::slotSecondary); // Single attack with offhand TEST_TARGET(); - TryWeaponProc(s_item, tar, EQEmu::inventory::slotSecondary); + TryWeaponProc(s_item, tar, EQEmu::invslot::slotSecondary); TEST_TARGET(); if (CanThisClassDoubleAttack() && CheckBotDoubleAttack()) { if (tar->GetHP() > -10) - Attack(tar, EQEmu::inventory::slotSecondary); // Single attack with offhand + Attack(tar, EQEmu::invslot::slotSecondary); // Single attack with offhand } } } @@ -2699,8 +2699,7 @@ void Bot::AI_Process() { tar_ndx = 20; } - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotRunspeed()); - + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetBotRunspeed()); return; } else { @@ -2828,8 +2827,7 @@ void Bot::AI_Process() { tar_ndx = 20; } - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed); - + CalculateNewPosition(Goal.x, Goal.y, Goal.z, speed); return; } } @@ -2911,14 +2909,14 @@ void Bot::PetAIProcess() { if(botPet->GetClass() == ROGUE && !petHasAggro && !botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY())) { // Move the rogue to behind the mob if(botPet->PlotPositionAroundTarget(botPet->GetTarget(), newX, newY, newZ)) { - botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetRunspeed()); + botPet->CalculateNewPosition(newX, newY, newZ, botPet->GetRunspeed()); return; } } else if(GetTarget() == botPet->GetTarget() && !petHasAggro && !botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY())) { // If the bot owner and the bot are fighting the same mob, then move the pet to the rear arc of the mob if(botPet->PlotPositionAroundTarget(botPet->GetTarget(), newX, newY, newZ)) { - botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetRunspeed()); + botPet->CalculateNewPosition(newX, newY, newZ, botPet->GetRunspeed()); return; } } @@ -2933,7 +2931,7 @@ void Bot::PetAIProcess() { moveBehindMob = true; if(botPet->PlotPositionAroundTarget(botPet->GetTarget(), newX, newY, newZ, moveBehindMob)) { - botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetRunspeed()); + botPet->CalculateNewPosition(newX, newY, newZ, botPet->GetRunspeed()); return; } } @@ -2947,12 +2945,12 @@ void Bot::PetAIProcess() { if(!botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY()) && botPet->GetTarget()->IsEnraged()) return; - if (botPet->Attack(GetTarget(), EQEmu::inventory::slotPrimary)) // try the main hand + if (botPet->Attack(GetTarget(), EQEmu::invslot::slotPrimary)) // try the main hand if (botPet->GetTarget()) { // We're a pet so we re able to dual attack int32 RandRoll = zone->random.Int(0, 99); if (botPet->CanThisClassDoubleAttack() && (RandRoll < (botPet->GetLevel() + NPCDualAttackModifier))) { - if (botPet->Attack(botPet->GetTarget(), EQEmu::inventory::slotPrimary)) {} + if (botPet->Attack(botPet->GetTarget(), EQEmu::invslot::slotPrimary)) {} } } @@ -2990,11 +2988,11 @@ void Bot::PetAIProcess() { float DualWieldProbability = ((botPet->GetSkill(EQEmu::skills::SkillDualWield) + botPet->GetLevel()) / 400.0f); DualWieldProbability -= zone->random.Real(0, 1); if(DualWieldProbability < 0) { - botPet->Attack(botPet->GetTarget(), EQEmu::inventory::slotSecondary); + botPet->Attack(botPet->GetTarget(), EQEmu::invslot::slotSecondary); if (botPet->CanThisClassDoubleAttack()) { int32 RandRoll = zone->random.Int(0, 99); if (RandRoll < (botPet->GetLevel() + 20)) - botPet->Attack(botPet->GetTarget(), EQEmu::inventory::slotSecondary); + botPet->Attack(botPet->GetTarget(), EQEmu::invslot::slotSecondary); } } } @@ -3016,7 +3014,7 @@ void Bot::PetAIProcess() { botPet->SetRunAnimSpeed(0); if(!botPet->IsRooted()) { Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", botPet->GetTarget()->GetCleanName()); - botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetOwner()->GetRunspeed()); + botPet->CalculateNewPosition(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetOwner()->GetRunspeed()); return; } else { botPet->SetHeading(botPet->GetTarget()->GetHeading()); @@ -3044,7 +3042,7 @@ void Bot::PetAIProcess() { float dist = DistanceSquared(botPet->GetPosition(), botPet->GetTarget()->GetPosition()); botPet->SetRunAnimSpeed(0); if(dist > 184) { - botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetTarget()->GetRunspeed()); + botPet->CalculateNewPosition(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetTarget()->GetRunspeed()); return; } else { botPet->SetHeading(botPet->GetTarget()->GetHeading()); @@ -3119,7 +3117,7 @@ bool Bot::Spawn(Client* botCharacterOwner) { // I re-enabled this until I can sort it out uint32 itemID = 0; uint8 materialFromSlot = 0xFF; - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; ++i) { itemID = GetBotItemBySlot(i); if(itemID != 0) { materialFromSlot = EQEmu::InventoryProfile::CalcMaterialFromSlot(i); @@ -3227,7 +3225,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { } } - inst = GetBotItem(EQEmu::inventory::slotPrimary); + inst = GetBotItem(EQEmu::invslot::slotPrimary); if(inst) { item = inst->GetItem(); if(item) { @@ -3238,7 +3236,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { } } - inst = GetBotItem(EQEmu::inventory::slotSecondary); + inst = GetBotItem(EQEmu::invslot::slotSecondary); if(inst) { item = inst->GetItem(); if(item) { @@ -3492,17 +3490,21 @@ EQEmu::ItemInstance* Bot::GetBotItem(uint32 slotID) { // Adds the specified item it bot to the NPC equipment array and to the bot inventory collection. void Bot::BotAddEquipItem(int slot, uint32 id) { + // this is being called before bot is assigned an entity id.. + // ..causing packets to be sent out to zone with an id of '0' if(slot > 0 && id > 0) { uint8 materialFromSlot = EQEmu::InventoryProfile::CalcMaterialFromSlot(slot); if (materialFromSlot != EQEmu::textures::materialInvalid) { equipment[slot] = id; // npc has more than just material slots. Valid material should mean valid inventory index - SendWearChange(materialFromSlot); + if (GetID()) // temp hack fix + SendWearChange(materialFromSlot); } UpdateEquipmentLight(); if (UpdateActiveLight()) - SendAppearancePacket(AT_Light, GetActiveLightType()); + if (GetID()) // temp hack fix + SendAppearancePacket(AT_Light, GetActiveLightType()); } } @@ -3619,12 +3621,12 @@ void Bot::FinishTrade(Client* client, BotTradeType tradeType) if (tradeType == BotTradeClientNormal) { // Items being traded are found in the normal trade window used to trade between a Client and a Client or NPC // Items in this mode are found in slot ids 3000 thru 3003 - thought bots used the full 8-slot window..? - PerformTradeWithClient(EQEmu::legacy::TRADE_BEGIN, EQEmu::legacy::TRADE_END, client); // {3000..3007} + PerformTradeWithClient(EQEmu::invslot::TRADE_BEGIN, EQEmu::invslot::TRADE_END, client); // {3000..3007} } else if (tradeType == BotTradeClientNoDropNoTrade) { // Items being traded are found on the Client's cursor slot, slot id 30. This item can be either a single item or it can be a bag. // If it is a bag, then we have to search for items in slots 331 thru 340 - PerformTradeWithClient(EQEmu::inventory::slotCursor, EQEmu::inventory::slotCursor, client); + PerformTradeWithClient(EQEmu::invslot::slotCursor, EQEmu::invslot::slotCursor, client); // TODO: Add logic here to test if the item in SLOT_CURSOR is a container type, if it is then we need to call the following: // PerformTradeWithClient(331, 340, client); @@ -3643,7 +3645,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli int adjustStackSize; std::string acceptedItemName; - ClientTrade(const ItemInstance* item, int16 from, const char* name = "") : tradeItemInstance(item), fromClientSlot(from), toBotSlot(legacy::SLOT_INVALID), adjustStackSize(0), acceptedItemName(name) { } + ClientTrade(const ItemInstance* item, int16 from, const char* name = "") : tradeItemInstance(item), fromClientSlot(from), toBotSlot(invslot::SLOT_INVALID), adjustStackSize(0), acceptedItemName(name) { } }; struct ClientReturn { @@ -3653,18 +3655,18 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli int adjustStackSize; std::string failedItemName; - ClientReturn(const ItemInstance* item, int16 from, const char* name = "") : returnItemInstance(item), fromBotSlot(from), toClientSlot(legacy::SLOT_INVALID), adjustStackSize(0), failedItemName(name) { } + ClientReturn(const ItemInstance* item, int16 from, const char* name = "") : returnItemInstance(item), fromBotSlot(from), toClientSlot(invslot::SLOT_INVALID), adjustStackSize(0), failedItemName(name) { } }; static const int16 proxyPowerSource = 22; - static const int16 bot_equip_order[(legacy::EQUIPMENT_SIZE + 1)] = { - inventory::slotCharm, inventory::slotEar1, inventory::slotHead, inventory::slotFace, - inventory::slotEar2, inventory::slotNeck, inventory::slotShoulders, inventory::slotArms, - inventory::slotBack, inventory::slotWrist1, inventory::slotWrist2, inventory::slotRange, - inventory::slotHands, inventory::slotPrimary, inventory::slotSecondary, inventory::slotFinger1, - inventory::slotFinger2, inventory::slotChest, inventory::slotLegs, inventory::slotFeet, - inventory::slotWaist, inventory::slotAmmo, proxyPowerSource // inventory::slotPowerSource + static const int16 bot_equip_order[(invslot::CORPSE_BEGIN + 1)] = { + invslot::slotCharm, invslot::slotEar1, invslot::slotHead, invslot::slotFace, + invslot::slotEar2, invslot::slotNeck, invslot::slotShoulders, invslot::slotArms, + invslot::slotBack, invslot::slotWrist1, invslot::slotWrist2, invslot::slotRange, + invslot::slotHands, invslot::slotPrimary, invslot::slotSecondary, invslot::slotFinger1, + invslot::slotFinger2, invslot::slotChest, invslot::slotLegs, invslot::slotFeet, + invslot::slotWaist, invslot::slotAmmo, proxyPowerSource // invslot::SLOT_POWER_SOURCE }; enum { stageStackable = 0, stageEmpty, stageReplaceable }; @@ -3679,17 +3681,17 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli client->ResetTrade(); return; } - if ((beginSlotID != legacy::TRADE_BEGIN) && (beginSlotID != inventory::slotCursor)) { + if ((beginSlotID != invslot::TRADE_BEGIN) && (beginSlotID != invslot::slotCursor)) { client->Message(CC_Red, "Trade request processing from illegal 'begin' slot - Trade Canceled."); client->ResetTrade(); return; } - if ((endSlotID != legacy::TRADE_END) && (endSlotID != inventory::slotCursor)) { + if ((endSlotID != invslot::TRADE_END) && (endSlotID != invslot::slotCursor)) { client->Message(CC_Red, "Trade request processing from illegal 'end' slot - Trade Canceled."); client->ResetTrade(); return; } - if (((beginSlotID == inventory::slotCursor) && (endSlotID != inventory::slotCursor)) || ((beginSlotID != inventory::slotCursor) && (endSlotID == inventory::slotCursor))) { + if (((beginSlotID == invslot::slotCursor) && (endSlotID != invslot::slotCursor)) || ((beginSlotID != invslot::slotCursor) && (endSlotID == invslot::slotCursor))) { client->Message(CC_Red, "Trade request processing illegal slot range - Trade Canceled."); client->ResetTrade(); return; @@ -3720,7 +3722,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli client->ResetTrade(); return; } - if ((trade_index != inventory::slotCursor) && !trade_instance->IsDroppable()) { + if ((trade_index != invslot::slotCursor) && !trade_instance->IsDroppable()) { // TODO: add logging client->Message(CC_Red, "Trade hack detected - Trade Canceled."); client->ResetTrade(); @@ -3783,7 +3785,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli //for (unsigned stage_loop = stageStackable; stage_loop <= stageReplaceable; ++stage_loop) { // awaiting implementation for (unsigned stage_loop = stageEmpty; stage_loop <= stageReplaceable; ++stage_loop) { for (auto& trade_iterator : client_trade) { - if (trade_iterator.toBotSlot != legacy::SLOT_INVALID) + if (trade_iterator.toBotSlot != invslot::SLOT_INVALID) continue; auto trade_instance = trade_iterator.tradeItemInstance; @@ -3800,7 +3802,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli //} if (stage_loop != stageReplaceable) { - if ((index == proxyPowerSource) && m_inv[inventory::slotPowerSource]) + if ((index == proxyPowerSource) && m_inv[invslot::SLOT_POWER_SOURCE]) continue; else if (m_inv[index]) continue; @@ -3819,28 +3821,28 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli if (slot_taken) continue; - if (index == inventory::slotPrimary) { + if (index == invslot::slotPrimary) { if (trade_instance->GetItem()->IsType2HWeapon()) { if (!melee_secondary) { melee_2h_weapon = true; - auto equipped_secondary_weapon = m_inv[inventory::slotSecondary]; + auto equipped_secondary_weapon = m_inv[invslot::slotSecondary]; if (equipped_secondary_weapon) - client_return.push_back(ClientReturn(equipped_secondary_weapon, inventory::slotSecondary)); + client_return.push_back(ClientReturn(equipped_secondary_weapon, invslot::slotSecondary)); } else { continue; } } } - if (index == inventory::slotSecondary) { + if (index == invslot::slotSecondary) { if (!melee_2h_weapon) { if ((can_dual_wield && trade_instance->GetItem()->IsType1HWeapon()) || trade_instance->GetItem()->IsTypeShield() || !trade_instance->IsWeapon()) { melee_secondary = true; - auto equipped_primary_weapon = m_inv[inventory::slotPrimary]; + auto equipped_primary_weapon = m_inv[invslot::slotPrimary]; if (equipped_primary_weapon && equipped_primary_weapon->GetItem()->IsType2HWeapon()) - client_return.push_back(ClientReturn(equipped_primary_weapon, inventory::slotPrimary)); + client_return.push_back(ClientReturn(equipped_primary_weapon, invslot::slotPrimary)); } else { continue; @@ -3852,10 +3854,10 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli } if (index == proxyPowerSource) { - trade_iterator.toBotSlot = inventory::slotPowerSource; + trade_iterator.toBotSlot = invslot::SLOT_POWER_SOURCE; - if (m_inv[inventory::slotPowerSource]) - client_return.push_back(ClientReturn(m_inv[inventory::slotPowerSource], inventory::slotPowerSource)); + if (m_inv[invslot::SLOT_POWER_SOURCE]) + client_return.push_back(ClientReturn(m_inv[invslot::SLOT_POWER_SOURCE], invslot::SLOT_POWER_SOURCE)); } else { trade_iterator.toBotSlot = index; @@ -3871,7 +3873,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli // move unassignable items from trade list to return list for (std::list::iterator trade_iterator = client_trade.begin(); trade_iterator != client_trade.end();) { - if (trade_iterator->toBotSlot == legacy::SLOT_INVALID) { + if (trade_iterator->toBotSlot == invslot::SLOT_INVALID) { client_return.push_back(ClientReturn(trade_iterator->tradeItemInstance, trade_iterator->fromClientSlot, trade_iterator->tradeItemInstance->GetItem()->Name)); trade_iterator = client_trade.erase(trade_iterator); continue; @@ -3897,17 +3899,17 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli return; } - if (return_iterator.fromBotSlot == inventory::slotCursor) { - return_iterator.toClientSlot = inventory::slotCursor; + if (return_iterator.fromBotSlot == invslot::slotCursor) { + return_iterator.toClientSlot = invslot::slotCursor; } else { - int16 client_search_general = legacy::GENERAL_BEGIN; - uint8 client_search_bag = inventory::containerBegin; + int16 client_search_general = invslot::GENERAL_BEGIN; + uint8 client_search_bag = invbag::SLOT_BEGIN; bool run_search = true; while (run_search) { int16 client_test_slot = client->GetInv().FindFreeSlotForTradeItem(return_instance, client_search_general, client_search_bag); - if (client_test_slot == legacy::SLOT_INVALID) { + if (client_test_slot == invslot::SLOT_INVALID) { run_search = false; continue; } @@ -3917,26 +3919,26 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli if (check_iterator.fromBotSlot == return_iterator.fromBotSlot) continue; - if ((check_iterator.toClientSlot == client_test_slot) && (client_test_slot != inventory::slotCursor)) { + if ((check_iterator.toClientSlot == client_test_slot) && (client_test_slot != invslot::slotCursor)) { slot_taken = true; break; } } if (slot_taken) { - if ((client_test_slot >= legacy::GENERAL_BEGIN) && (client_test_slot <= legacy::GENERAL_END)) { + if ((client_test_slot >= invslot::GENERAL_BEGIN) && (client_test_slot <= invslot::GENERAL_END)) { ++client_search_general; - client_search_bag = inventory::containerBegin; + client_search_bag = invbag::SLOT_BEGIN; } else { client_search_general = InventoryProfile::CalcSlotId(client_test_slot); client_search_bag = InventoryProfile::CalcBagIdx(client_test_slot); ++client_search_bag; - if (client_search_bag >= inventory::ContainerCount) { + if (client_search_bag >= invbag::SLOT_COUNT) { // incrementing this past legacy::GENERAL_END triggers the (client_test_slot == legacy::SLOT_INVALID) at the beginning of the search loop // ideally, this will never occur because we always start fresh with each loop iteration and should receive SLOT_CURSOR as a return value ++client_search_general; - client_search_bag = inventory::containerBegin; + client_search_bag = invbag::SLOT_BEGIN; } } @@ -3948,7 +3950,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli } } - if (return_iterator.toClientSlot == legacy::SLOT_INVALID) { + if (return_iterator.toClientSlot == invslot::SLOT_INVALID) { client->Message(CC_Yellow, "You do not have room to complete this trade - Trade Canceled!"); client->ResetTrade(); return; @@ -3960,10 +3962,10 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli for (auto& return_iterator : client_return) { // TODO: code for stackables - if (return_iterator.fromBotSlot == inventory::slotCursor) { // failed trade return + if (return_iterator.fromBotSlot == invslot::slotCursor) { // failed trade return // no movement action required } - else if ((return_iterator.fromBotSlot >= legacy::TRADE_BEGIN) && (return_iterator.fromBotSlot <= legacy::TRADE_END)) { // failed trade returns + else if ((return_iterator.fromBotSlot >= invslot::TRADE_BEGIN) && (return_iterator.fromBotSlot <= invslot::TRADE_END)) { // failed trade returns client->PutItemInInventory(return_iterator.toClientSlot, *return_iterator.returnItemInstance); client->SendItemPacket(return_iterator.toClientSlot, return_iterator.returnItemInstance, ItemPacketTrade); client->DeleteItemInInventory(return_iterator.fromBotSlot); @@ -3994,7 +3996,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli m_inv.PutItem(trade_iterator.toBotSlot, *trade_iterator.tradeItemInstance); this->BotAddEquipItem(trade_iterator.toBotSlot, (trade_iterator.tradeItemInstance ? trade_iterator.tradeItemInstance->GetID() : 0)); - client->DeleteItemInInventory(trade_iterator.fromClientSlot, 0, true); + client->DeleteItemInInventory(trade_iterator.fromClientSlot, 0, (trade_iterator.fromClientSlot == EQEmu::invslot::slotCursor)); trade_iterator.tradeItemInstance = nullptr; } @@ -4176,13 +4178,13 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b FaceTarget(GetTarget()); EQEmu::ItemInstance* weapon = nullptr; - if (Hand == EQEmu::inventory::slotPrimary) { - weapon = GetBotItem(EQEmu::inventory::slotPrimary); + if (Hand == EQEmu::invslot::slotPrimary) { + weapon = GetBotItem(EQEmu::invslot::slotPrimary); OffHandAtk(false); } - if (Hand == EQEmu::inventory::slotSecondary) { - weapon = GetBotItem(EQEmu::inventory::slotSecondary); + if (Hand == EQEmu::invslot::slotSecondary) { + weapon = GetBotItem(EQEmu::invslot::slotSecondary); OffHandAtk(true); } @@ -4231,7 +4233,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b // This is not recommended for normal usage, as the damage bonus represents a non-trivial component of the DPS output // of weapons wielded by higher-level melee characters (especially for two-handed weapons). int ucDamageBonus = 0; - if (Hand == EQEmu::inventory::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) { + if (Hand == EQEmu::invslot::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) { // Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above // who belong to a melee class. If we're here, then all of these conditions apply. ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr); @@ -4240,7 +4242,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b } #endif //Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon. - if (Hand == EQEmu::inventory::slotSecondary) { + if (Hand == EQEmu::invslot::slotSecondary) { if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){ ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr); my_hit.min_damage = ucDamageBonus; @@ -4647,7 +4649,7 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) { int32 focus_max = 0; int32 focus_max_real = 0; //item focus - for (int x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::EQUIPMENT_END; x++) { + for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) { TempItem = nullptr; EQEmu::ItemInstance* ins = GetBotItem(x); if (!ins) @@ -4672,7 +4674,7 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) { } } - for (int y = EQEmu::inventory::socketBegin; y < EQEmu::inventory::SocketCount; ++y) { + for (int y = EQEmu::invaug::SOCKET_BEGIN; y <= EQEmu::invaug::SOCKET_END; ++y) { EQEmu::ItemInstance *aug = nullptr; aug = ins->GetAugment(y); if(aug) { @@ -5108,13 +5110,13 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) { float ProcChance = 0.0f; uint32 weapon_speed = 0; switch (hand) { - case EQEmu::inventory::slotPrimary: + case EQEmu::invslot::slotPrimary: weapon_speed = attack_timer.GetDuration(); break; - case EQEmu::inventory::slotSecondary: + case EQEmu::invslot::slotSecondary: weapon_speed = attack_dw_timer.GetDuration(); break; - case EQEmu::inventory::slotRange: + case EQEmu::invslot::slotRange: weapon_speed = ranged_timer.GetDuration(); break; } @@ -5204,11 +5206,11 @@ void Bot::DoRiposte(Mob* defender) { if (!defender) return; - defender->Attack(this, EQEmu::inventory::slotPrimary, true); + defender->Attack(this, EQEmu::invslot::slotPrimary, true); int32 DoubleRipChance = (defender->GetAABonuses().GiveDoubleRiposte[0] + defender->GetSpellBonuses().GiveDoubleRiposte[0] + defender->GetItemBonuses().GiveDoubleRiposte[0]); if(DoubleRipChance && (DoubleRipChance >= zone->random.Int(0, 100))) { Log(Logs::Detail, Logs::Combat, "Preforming a double riposte (%d percent chance)", DoubleRipChance); - defender->Attack(this, EQEmu::inventory::slotPrimary, true); + defender->Attack(this, EQEmu::invslot::slotPrimary, true); } DoubleRipChance = defender->GetAABonuses().GiveDoubleRiposte[1]; @@ -5238,7 +5240,7 @@ int Bot::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) base++; return base; case EQEmu::skills::SkillFrenzy: - if (GetBotItem(EQEmu::inventory::slotPrimary)) { + if (GetBotItem(EQEmu::invslot::slotPrimary)) { if (GetLevel() > 15) base += GetLevel() - 15; if (base > 23) @@ -5254,7 +5256,7 @@ int Bot::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) case EQEmu::skills::SkillFlyingKick: { float skill_bonus = skill_level / 9.0f; float ac_bonus = 0.0f; - auto inst = GetBotItem(EQEmu::inventory::slotFeet); + auto inst = GetBotItem(EQEmu::invslot::slotFeet); if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; if (ac_bonus > skill_bonus) @@ -5264,7 +5266,7 @@ int Bot::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) case EQEmu::skills::SkillKick: { float skill_bonus = skill_level / 10.0f; float ac_bonus = 0.0f; - auto inst = GetBotItem(EQEmu::inventory::slotFeet); + auto inst = GetBotItem(EQEmu::invslot::slotFeet); if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; if (ac_bonus > skill_bonus) @@ -5276,9 +5278,9 @@ int Bot::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) float ac_bonus = 0.0f; const EQEmu::ItemInstance *inst = nullptr; if (HasShieldEquiped()) - inst = GetBotItem(EQEmu::inventory::slotSecondary); + inst = GetBotItem(EQEmu::invslot::slotSecondary); else if (HasTwoHanderEquipped()) - inst = GetBotItem(EQEmu::inventory::slotPrimary); + inst = GetBotItem(EQEmu::invslot::slotPrimary); if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; if (ac_bonus > skill_bonus) @@ -5287,7 +5289,7 @@ int Bot::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) } case EQEmu::skills::SkillBackstab: { float skill_bonus = static_cast(skill_level) * 0.02f; - auto inst = GetBotItem(EQEmu::inventory::slotPrimary); + auto inst = GetBotItem(EQEmu::invslot::slotPrimary); if (inst && inst->GetItem() && inst->GetItem()->ItemType == EQEmu::item::ItemType1HPiercing) { base = inst->GetItemBackstabDamage(true); if (!inst->GetItemBackstabDamage()) @@ -5312,7 +5314,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 hate = hate_override; if (skill == EQEmu::skills::SkillBash) { - const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotSecondary); + const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::invslot::slotSecondary); const EQEmu::ItemData* botweapon = nullptr; if(inst) botweapon = inst->GetItem(); @@ -5333,10 +5335,10 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 my_hit.skill = skill; my_hit.offense = offense(my_hit.skill); my_hit.tohit = GetTotalToHit(my_hit.skill, 0); - my_hit.hand = EQEmu::inventory::slotPrimary; + my_hit.hand = EQEmu::invslot::slotPrimary; if (skill == EQEmu::skills::SkillThrowing || skill == EQEmu::skills::SkillArchery) - my_hit.hand = EQEmu::inventory::slotRange; + my_hit.hand = EQEmu::invslot::slotRange; DoAttack(who, my_hit); @@ -5373,7 +5375,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) { bool bIsBehind = false; bool bCanFrontalBS = false; - const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotPrimary); + const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::invslot::slotPrimary); const EQEmu::ItemData* botpiercer = nullptr; if(inst) botpiercer = inst->GetItem(); @@ -5416,7 +5418,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) { m_specialattacks = eSpecialAttacks::None; } else - Attack(other, EQEmu::inventory::slotPrimary); + Attack(other, EQEmu::invslot::slotPrimary); } void Bot::RogueBackstab(Mob *other, bool min_damage, int ReuseTime) @@ -5424,7 +5426,7 @@ void Bot::RogueBackstab(Mob *other, bool min_damage, int ReuseTime) if (!other) return; - EQEmu::ItemInstance *botweaponInst = GetBotItem(EQEmu::inventory::slotPrimary); + EQEmu::ItemInstance *botweaponInst = GetBotItem(EQEmu::invslot::slotPrimary); if (botweaponInst) { if (!GetWeaponDamage(other, botweaponInst)) return; @@ -5442,7 +5444,7 @@ void Bot::RogueBackstab(Mob *other, bool min_damage, int ReuseTime) } void Bot::RogueAssassinate(Mob* other) { - EQEmu::ItemInstance* botweaponInst = GetBotItem(EQEmu::inventory::slotPrimary); + EQEmu::ItemInstance* botweaponInst = GetBotItem(EQEmu::invslot::slotPrimary); if(botweaponInst) { if(GetWeaponDamage(other, botweaponInst)) other->Damage(this, 32000, SPELL_UNKNOWN, EQEmu::skills::SkillBackstab); @@ -5507,7 +5509,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { case WARRIOR: if(level >= RuleI(Combat, NPCBashKickLevel)){ bool canBash = false; - if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::inventory::slotSecondary) && m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::inventory::slotPrimary) && m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1)) + if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::invslot::slotSecondary) && m_inv.GetItem(EQEmu::invslot::slotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::invslot::slotPrimary) && m_inv.GetItem(EQEmu::invslot::slotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1)) canBash = true; if(!canBash || zone->random.Int(0, 100) > 25) @@ -5526,7 +5528,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { case SHADOWKNIGHT: case PALADIN: if(level >= RuleI(Combat, NPCBashKickLevel)){ - if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::inventory::slotSecondary) && m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::inventory::slotPrimary) && m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1)) + if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::invslot::slotSecondary) && m_inv.GetItem(EQEmu::invslot::slotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::invslot::slotPrimary) && m_inv.GetItem(EQEmu::invslot::slotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1)) skill_to_use = EQEmu::skills::SkillBash; } break; @@ -5557,7 +5559,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { if (skill_to_use == EQEmu::skills::SkillBash) { if (target != this) { DoAnim(animTailRake); - if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotShoulders)) <= 0) + if (GetWeaponDamage(target, GetBotItem(EQEmu::invslot::slotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQEmu::invslot::slotShoulders)) <= 0) dmg = DMG_INVULNERABLE; reuse = (BashReuseTime * 1000); @@ -5584,7 +5586,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { if (skill_to_use == EQEmu::skills::SkillKick) { if(target != this) { DoAnim(animKick); - if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotFeet)) <= 0) + if (GetWeaponDamage(target, GetBotItem(EQEmu::invslot::slotFeet)) <= 0) dmg = DMG_INVULNERABLE; reuse = (KickReuseTime * 1000); @@ -5722,7 +5724,7 @@ void Bot::EquipBot(std::string* errorMessage) { GetBotItems(m_inv, errorMessage); const EQEmu::ItemInstance* inst = nullptr; const EQEmu::ItemData* item = nullptr; - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; ++i) { inst = GetBotItem(i); if(inst) { item = inst->GetItem(); @@ -5849,12 +5851,12 @@ void Bot::SetAttackTimer() { attack_timer.SetAtTrigger(4000, true); Timer* TimerToUse = nullptr; const EQEmu::ItemData* PrimaryWeapon = nullptr; - for (int i = EQEmu::inventory::slotRange; i <= EQEmu::inventory::slotSecondary; i++) { - if (i == EQEmu::inventory::slotPrimary) + for (int i = EQEmu::invslot::slotRange; i <= EQEmu::invslot::slotSecondary; i++) { + if (i == EQEmu::invslot::slotPrimary) TimerToUse = &attack_timer; - else if (i == EQEmu::inventory::slotRange) + else if (i == EQEmu::invslot::slotRange) TimerToUse = &ranged_timer; - else if (i == EQEmu::inventory::slotSecondary) + else if (i == EQEmu::invslot::slotSecondary) TimerToUse = &attack_dw_timer; else continue; @@ -5864,7 +5866,7 @@ void Bot::SetAttackTimer() { if (ci) ItemToUse = ci->GetItem(); - if (i == EQEmu::inventory::slotSecondary) { + if (i == EQEmu::invslot::slotSecondary) { if (PrimaryWeapon != nullptr) { if (PrimaryWeapon->IsClassCommon() && PrimaryWeapon->IsType2HWeapon()) { attack_dw_timer.Disable(); @@ -5895,7 +5897,7 @@ void Bot::SetAttackTimer() { speed = (RuleB(Spells, Jun182014HundredHandsRevamp) ? static_cast(((delay / haste_mod) + ((hhe / 1000.0f) * (delay / haste_mod))) * 100) : static_cast(((delay / haste_mod) + ((hhe / 100.0f) * delay)) * 100)); TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true); - if (i == EQEmu::inventory::slotPrimary) + if (i == EQEmu::invslot::slotPrimary) PrimaryWeapon = ItemToUse; } } @@ -7605,7 +7607,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) { // Modded to display power source items (will only show up on SoF+ client inspect windows though.) // I don't think bots are currently coded to use them..but, you'll have to use '#bot inventory list' // to see them on a Titanium client when/if they are activated. - for (int16 L = EQEmu::legacy::EQUIPMENT_BEGIN; L <= EQEmu::inventory::slotWaist; L++) { + for (int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::slotWaist; L++) { inst = inspectedBot->GetBotItem(L); if(inst) { @@ -7619,28 +7621,28 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) { } } - inst = inspectedBot->GetBotItem(EQEmu::inventory::slotPowerSource); + inst = inspectedBot->GetBotItem(EQEmu::invslot::SLOT_POWER_SOURCE); if(inst) { item = inst->GetItem(); if(item) { - strcpy(insr->itemnames[SoF::invslot::PossessionsPowerSource], item->Name); - insr->itemicons[SoF::invslot::PossessionsPowerSource] = item->Icon; + strcpy(insr->itemnames[SoF::invslot::slotPowerSource], item->Name); + insr->itemicons[SoF::invslot::slotPowerSource] = item->Icon; } else - insr->itemicons[SoF::invslot::PossessionsPowerSource] = 0xFFFFFFFF; + insr->itemicons[SoF::invslot::slotPowerSource] = 0xFFFFFFFF; } - inst = inspectedBot->GetBotItem(EQEmu::inventory::slotAmmo); + inst = inspectedBot->GetBotItem(EQEmu::invslot::slotAmmo); if(inst) { item = inst->GetItem(); if(item) { - strcpy(insr->itemnames[SoF::invslot::PossessionsAmmo], item->Name); - insr->itemicons[SoF::invslot::PossessionsAmmo] = item->Icon; + strcpy(insr->itemnames[SoF::invslot::slotAmmo], item->Name); + insr->itemicons[SoF::invslot::slotAmmo] = item->Icon; } else - insr->itemicons[SoF::invslot::PossessionsAmmo] = 0xFFFFFFFF; + insr->itemicons[SoF::invslot::slotAmmo] = 0xFFFFFFFF; } strcpy(insr->text, inspectedBot->GetInspectMessage().text); @@ -7653,7 +7655,7 @@ void Bot::CalcItemBonuses(StatBonuses* newbon) { const EQEmu::ItemData* itemtmp = nullptr; - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= (EQEmu::invslot::EQUIPMENT_END + 1); ++i) { const EQEmu::ItemInstance* item = GetBotItem((i == 22 ? 9999 : i)); if(item) { AddItemBonuses(item, newbon); @@ -7966,7 +7968,7 @@ void Bot::AddItemBonuses(const EQEmu::ItemInstance *inst, StatBonuses* newbon, b if (!isAug) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) AddItemBonuses(inst->GetAugment(i),newbon,true, false, rec_level); } @@ -8475,12 +8477,12 @@ uint8 Bot::GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets) { int Bot::GetRawACNoShield(int &shield_ac) { int ac = itembonuses.AC + spellbonuses.AC; shield_ac = 0; - EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotSecondary); + EQEmu::ItemInstance* inst = GetBotItem(EQEmu::invslot::slotSecondary); if(inst) { if (inst->GetItem()->ItemType == EQEmu::item::ItemTypeShield) { ac -= inst->GetItem()->AC; shield_ac = inst->GetItem()->AC; - for (uint8 i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (uint8 i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { if(inst->GetAugment(i)) { ac -= inst->GetAugment(i)->GetItem()->AC; shield_ac += inst->GetAugment(i)->GetItem()->AC; @@ -8495,7 +8497,7 @@ uint32 Bot::CalcCurrentWeight() { const EQEmu::ItemData* TempItem = nullptr; EQEmu::ItemInstance* inst = nullptr; uint32 Total = 0; - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; ++i) { inst = GetBotItem(i); if(inst) { TempItem = inst->GetItem(); diff --git a/zone/bot.h b/zone/bot.h index c72e83f5c..0c48b6483 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -80,9 +80,9 @@ static const std::string bot_stance_name[BOT_STANCE_COUNT] = { static const char* GetBotStanceName(int stance_id) { return bot_stance_name[VALIDBOTSTANCE(stance_id)].c_str(); } -#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::legacy::EQUIPMENT_BEGIN && x <= EQEmu::legacy::EQUIPMENT_END) ? (x) : ((x == EQEmu::inventory::slotPowerSource) ? (22) : (23))) +#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::invslot::EQUIPMENT_BEGIN && x <= EQEmu::invslot::EQUIPMENT_END) ? (x) : ((x == EQEmu::invslot::SLOT_POWER_SOURCE) ? (22) : (23))) -static std::string bot_equip_slot_name[EQEmu::legacy::EQUIPMENT_SIZE + 2] = +static std::string bot_equip_slot_name[EQEmu::invslot::EQUIPMENT_COUNT + 2] = { "Charm", // MainCharm "Left Ear", // MainEar1 @@ -256,7 +256,7 @@ public: //abstract virtual function implementations requird by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill); virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None); - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr); virtual bool HasRaid() { return (GetRaid() ? true : false); } virtual bool HasGroup() { return (GetGroup() ? true : false); } diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 0a286e8f5..3344fd0fb 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -63,7 +63,6 @@ #include "guild_mgr.h" #include "map.h" #include "doors.h" -#include "pathing.h" #include "qglobals.h" #include "queryserv.h" #include "quest_parser_collection.h" @@ -2404,7 +2403,7 @@ namespace ActionableBots continue; mod_skill_value = base_skill_value; - for (int16 index = EQEmu::legacy::EQUIPMENT_BEGIN; index <= EQEmu::legacy::EQUIPMENT_END; ++index) { + for (int16 index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::EQUIPMENT_END; ++index) { const EQEmu::ItemInstance* indexed_item = bot_iter->GetBotItem(index); if (indexed_item && indexed_item->GetItem()->SkillModType == skill_type) mod_skill_value += (base_skill_value * (((float)indexed_item->GetItem()->SkillModValue) / 100.0f)); @@ -7138,23 +7137,23 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep) linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); uint32 inventory_count = 0; - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) { - if ((i == EQEmu::inventory::slotSecondary) && is2Hweapon) + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= (EQEmu::invslot::EQUIPMENT_END + 1); ++i) { + if ((i == EQEmu::invslot::slotSecondary) && is2Hweapon) continue; - inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::inventory::slotPowerSource : i); + inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i); if (!inst || !inst->GetItem()) { - c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i)); + c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), (i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i)); continue; } item = inst->GetItem(); - if ((i == EQEmu::inventory::slotPrimary) && item->IsType2HWeapon()) { + if ((i == EQEmu::invslot::slotPrimary) && item->IsType2HWeapon()) { is2Hweapon = true; } linker.SetItemInst(inst); - c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i)); + c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i)); ++inventory_count; } @@ -7193,7 +7192,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) } int slotId = atoi(sep->arg[1]); - if (!sep->IsNumber(1) || ((slotId > EQEmu::legacy::EQUIPMENT_END || slotId < EQEmu::legacy::EQUIPMENT_BEGIN) && slotId != EQEmu::inventory::slotPowerSource)) { + if (!sep->IsNumber(1) || ((slotId > EQEmu::invslot::EQUIPMENT_END || slotId < EQEmu::invslot::EQUIPMENT_BEGIN) && slotId != EQEmu::invslot::SLOT_POWER_SOURCE)) { c->Message(m_fail, "Valid slots are 0-21 or 9999"); return; } @@ -7208,7 +7207,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) return; } - for (int m = EQEmu::inventory::socketBegin; m < EQEmu::inventory::SocketCount; ++m) { + for (int m = EQEmu::invaug::SOCKET_BEGIN; m <= EQEmu::invaug::SOCKET_END; ++m) { if (!itminst) break; @@ -7225,7 +7224,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) std::string error_message; if (itm) { c->PushItemOnCursor(*itminst, true); - if ((slotId == EQEmu::inventory::slotRange) || (slotId == EQEmu::inventory::slotAmmo) || (slotId == EQEmu::inventory::slotPrimary) || (slotId == EQEmu::inventory::slotSecondary)) + if ((slotId == EQEmu::invslot::slotRange) || (slotId == EQEmu::invslot::slotAmmo) || (slotId == EQEmu::invslot::slotPrimary) || (slotId == EQEmu::invslot::slotSecondary)) my_bot->SetBotArcher(false); my_bot->RemoveBotItemBySlot(slotId, &error_message); @@ -7239,31 +7238,31 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) } switch (slotId) { - case EQEmu::inventory::slotCharm: - case EQEmu::inventory::slotEar1: - case EQEmu::inventory::slotHead: - case EQEmu::inventory::slotFace: - case EQEmu::inventory::slotEar2: - case EQEmu::inventory::slotNeck: - case EQEmu::inventory::slotBack: - case EQEmu::inventory::slotWrist1: - case EQEmu::inventory::slotWrist2: - case EQEmu::inventory::slotRange: - case EQEmu::inventory::slotPrimary: - case EQEmu::inventory::slotSecondary: - case EQEmu::inventory::slotFinger1: - case EQEmu::inventory::slotFinger2: - case EQEmu::inventory::slotChest: - case EQEmu::inventory::slotWaist: - case EQEmu::inventory::slotPowerSource: - case EQEmu::inventory::slotAmmo: + case EQEmu::invslot::slotCharm: + case EQEmu::invslot::slotEar1: + case EQEmu::invslot::slotHead: + case EQEmu::invslot::slotFace: + case EQEmu::invslot::slotEar2: + case EQEmu::invslot::slotNeck: + case EQEmu::invslot::slotBack: + case EQEmu::invslot::slotWrist1: + case EQEmu::invslot::slotWrist2: + case EQEmu::invslot::slotRange: + case EQEmu::invslot::slotPrimary: + case EQEmu::invslot::slotSecondary: + case EQEmu::invslot::slotFinger1: + case EQEmu::invslot::slotFinger2: + case EQEmu::invslot::slotChest: + case EQEmu::invslot::slotWaist: + case EQEmu::invslot::SLOT_POWER_SOURCE: + case EQEmu::invslot::slotAmmo: c->Message(m_message, "My %s is %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already"))); break; - case EQEmu::inventory::slotShoulders: - case EQEmu::inventory::slotArms: - case EQEmu::inventory::slotHands: - case EQEmu::inventory::slotLegs: - case EQEmu::inventory::slotFeet: + case EQEmu::invslot::slotShoulders: + case EQEmu::invslot::slotArms: + case EQEmu::invslot::slotHands: + case EQEmu::invslot::slotLegs: + case EQEmu::invslot::slotFeet: c->Message(m_message, "My %s are %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already"))); break; default: @@ -7300,14 +7299,14 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep) //EQEmu::SayLinkEngine linker; //linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= (EQEmu::invslot::EQUIPMENT_END + 1); ++i) { const EQEmu::ItemData* item = nullptr; - const EQEmu::ItemInstance* inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::inventory::slotPowerSource : i); + const EQEmu::ItemInstance* inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i); if (inst) item = inst->GetItem(); window_text.append(""); - window_text.append(GetBotEquipSlotName(i == 22 ? EQEmu::inventory::slotPowerSource : i)); + window_text.append(GetBotEquipSlotName(i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i)); window_text.append(": "); if (item) { //window_text.append(""); diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index 10449ab7a..a5e50fdec 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -1138,7 +1138,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQEmu::InventoryProfile& invent for (auto row = results.begin(); row != results.end(); ++row) { int16 slot_id = atoi(row[0]); - if ((slot_id < EQEmu::legacy::EQUIPMENT_BEGIN || slot_id > EQEmu::legacy::EQUIPMENT_END) && slot_id != EQEmu::inventory::slotPowerSource) + if ((slot_id < EQEmu::invslot::EQUIPMENT_BEGIN || slot_id > EQEmu::invslot::EQUIPMENT_END) && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE) continue; uint32 item_id = atoi(row[1]); @@ -1173,7 +1173,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQEmu::InventoryProfile& invent if (item_inst->GetItem()->Attuneable) { if (atoi(row[4])) item_inst->SetAttuned(true); - else if (((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::legacy::EQUIPMENT_END) || slot_id == EQEmu::inventory::slotPowerSource)) + else if (((slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::invslot::EQUIPMENT_END) || slot_id == EQEmu::invslot::SLOT_POWER_SOURCE)) item_inst->SetAttuned(true); } @@ -1241,7 +1241,7 @@ bool BotDatabase::LoadItemBySlot(Bot* bot_inst) bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint32& item_id) { - if (!bot_id || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::inventory::slotPowerSource)) + if (!bot_id || (slot_id > EQEmu::invslot::EQUIPMENT_END && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE)) return false; query = StringFormat("SELECT `item_id` FROM `bot_inventories` WHERE `bot_id` = '%i' AND `slot_id` = '%i' LIMIT 1", bot_id, slot_id); @@ -1259,7 +1259,7 @@ bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEmu::ItemInstance* item_inst) { - if (!bot_inst || !bot_inst->GetBotID() || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::inventory::slotPowerSource)) + if (!bot_inst || !bot_inst->GetBotID() || (slot_id > EQEmu::invslot::EQUIPMENT_END && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE)) return false; if (!DeleteItemBySlot(bot_inst->GetBotID(), slot_id)) @@ -1268,8 +1268,8 @@ bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEm if (!item_inst || !item_inst->GetID()) return true; - uint32 augment_id[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 }; - for (int augment_iter = EQEmu::inventory::socketBegin; augment_iter < EQEmu::inventory::SocketCount; ++augment_iter) + uint32 augment_id[EQEmu::invaug::SOCKET_COUNT] = { 0, 0, 0, 0, 0, 0 }; + for (int augment_iter = EQEmu::invaug::SOCKET_BEGIN; augment_iter <= EQEmu::invaug::SOCKET_END; ++augment_iter) augment_id[augment_iter] = item_inst->GetAugmentItemID(augment_iter); uint16 item_charges = 0; @@ -1343,7 +1343,7 @@ bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEm bool BotDatabase::DeleteItemBySlot(const uint32 bot_id, const uint32 slot_id) { - if (!bot_id || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::inventory::slotPowerSource)) + if (!bot_id || (slot_id > EQEmu::invslot::EQUIPMENT_END && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE)) return false; query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = '%u' AND `slot_id` = '%u'", bot_id, slot_id); @@ -1382,12 +1382,12 @@ bool BotDatabase::SaveEquipmentColor(const uint32 bot_id, const int16 slot_id, c return false; bool all_flag = (slot_id == -2); - if ((slot_id < EQEmu::legacy::EQUIPMENT_BEGIN || slot_id > EQEmu::legacy::EQUIPMENT_END) && slot_id != EQEmu::inventory::slotPowerSource && !all_flag) + if ((slot_id < EQEmu::invslot::EQUIPMENT_BEGIN || slot_id > EQEmu::invslot::EQUIPMENT_END) && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE && !all_flag) return false; std::string where_clause; if (all_flag) - where_clause = StringFormat(" AND `slot_id` IN ('%u', '%u', '%u', '%u', '%u', '%u', '%u')", EQEmu::inventory::slotHead, EQEmu::inventory::slotArms, EQEmu::inventory::slotWrist1, EQEmu::inventory::slotHands, EQEmu::inventory::slotChest, EQEmu::inventory::slotLegs, EQEmu::inventory::slotFeet); + where_clause = StringFormat(" AND `slot_id` IN ('%u', '%u', '%u', '%u', '%u', '%u', '%u')", EQEmu::invslot::slotHead, EQEmu::invslot::slotArms, EQEmu::invslot::slotWrist1, EQEmu::invslot::slotHands, EQEmu::invslot::slotChest, EQEmu::invslot::slotLegs, EQEmu::invslot::slotFeet); else where_clause = StringFormat(" AND `slot_id` = '%u'", slot_id); @@ -1658,8 +1658,8 @@ bool BotDatabase::LoadPetItems(const uint32 bot_id, uint32* pet_items) if (!results.RowCount()) return true; - int item_index = 0; - for (auto row = results.begin(); row != results.end() && item_index < EQEmu::legacy::EQUIPMENT_SIZE; ++row) { + int item_index = EQEmu::invslot::EQUIPMENT_BEGIN; + for (auto row = results.begin(); row != results.end() && item_index <= EQEmu::invslot::EQUIPMENT_END; ++row) { pet_items[item_index] = atoi(row[0]); ++item_index; } @@ -1683,7 +1683,7 @@ bool BotDatabase::SavePetItems(const uint32 bot_id, const uint32* pet_items, boo if (!saved_pet_index) return true; - for (int item_index = 0; item_index < EQEmu::legacy::EQUIPMENT_SIZE; ++item_index) { + for (int item_index = EQEmu::invslot::SLOT_BEGIN; item_index <= EQEmu::invslot::EQUIPMENT_END; ++item_index) { if (!pet_items[item_index]) continue; @@ -1832,7 +1832,7 @@ bool BotDatabase::SaveAllArmorColorBySlot(const uint32 owner_id, const int16 slo " AND bi.`slot_id` = '%i'", owner_id, rgb_value, - EQEmu::inventory::slotHead, EQEmu::inventory::slotChest, EQEmu::inventory::slotArms, EQEmu::inventory::slotWrist1, EQEmu::inventory::slotWrist2, EQEmu::inventory::slotHands, EQEmu::inventory::slotLegs, EQEmu::inventory::slotFeet, + EQEmu::invslot::slotHead, EQEmu::invslot::slotChest, EQEmu::invslot::slotArms, EQEmu::invslot::slotWrist1, EQEmu::invslot::slotWrist2, EQEmu::invslot::slotHands, EQEmu::invslot::slotLegs, EQEmu::invslot::slotFeet, slot_id ); auto results = QueryDatabase(query); @@ -1856,7 +1856,7 @@ bool BotDatabase::SaveAllArmorColors(const uint32 owner_id, const uint32 rgb_val " AND bi.`slot_id` IN ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", owner_id, rgb_value, - EQEmu::inventory::slotHead, EQEmu::inventory::slotChest, EQEmu::inventory::slotArms, EQEmu::inventory::slotWrist1, EQEmu::inventory::slotWrist2, EQEmu::inventory::slotHands, EQEmu::inventory::slotLegs, EQEmu::inventory::slotFeet + EQEmu::invslot::slotHead, EQEmu::invslot::slotChest, EQEmu::invslot::slotArms, EQEmu::invslot::slotWrist1, EQEmu::invslot::slotWrist2, EQEmu::invslot::slotHands, EQEmu::invslot::slotLegs, EQEmu::invslot::slotFeet ); auto results = QueryDatabase(query); if (!results.Success()) diff --git a/zone/client.cpp b/zone/client.cpp index 16157c807..6acd203f4 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -33,7 +33,6 @@ extern volatile bool RunLoops; #include "../common/eqemu_logsys.h" #include "../common/features.h" -#include "../common/emu_legacy.h" #include "../common/spdat.h" #include "../common/guilds.h" #include "../common/rulesys.h" @@ -326,9 +325,6 @@ Client::Client(EQStreamInterface* ieqs) initial_respawn_selection = 0; alternate_currency_loaded = false; - EngagedRaidTarget = false; - SavedRaidRestTimer = 0; - interrogateinv_flag = false; trapid = 0; @@ -631,7 +627,7 @@ bool Client::Save(uint8 iCommitNow) { /* Total Time Played */ TotalSecondsPlayed += (time(nullptr) - m_pp.lastlogin); m_pp.timePlayedMin = (TotalSecondsPlayed / 60); - m_pp.RestTimer = rest_timer.GetRemainingTime() / 1000; + m_pp.RestTimer = GetRestTimer(); /* Save Mercs */ if (GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS)) { @@ -1866,6 +1862,9 @@ void Client::CheckManaEndUpdate() { mana_change->stamina = current_endurance; mana_change->spell_id = casting_spell_id; mana_change->keepcasting = 1; + mana_change->padding[0] = 0; + mana_change->padding[1] = 0; + mana_change->padding[2] = 0; outapp->priority = 6; QueuePacket(outapp); safe_delete(outapp); @@ -1887,8 +1886,9 @@ void Client::CheckManaEndUpdate() { mana_update->cur_mana = GetMana(); mana_update->max_mana = GetMaxMana(); mana_update->spawn_id = GetID(); - QueuePacket(mana_packet); - entity_list.QueueClientsByXTarget(this, mana_packet, false); + if ((ClientVersionBit() & EQEmu::versions::ClientVersionBit::bit_SoDAndLater) != 0) + QueuePacket(mana_packet); // do we need this with the OP_ManaChange packet above? + entity_list.QueueClientsByXTarget(this, mana_packet, false, EQEmu::versions::ClientVersionBit::bit_SoDAndLater); safe_delete(mana_packet); last_reported_mana_percent = this->GetManaPercent(); @@ -1911,8 +1911,9 @@ void Client::CheckManaEndUpdate() { endurance_update->cur_end = GetEndurance(); endurance_update->max_end = GetMaxEndurance(); endurance_update->spawn_id = GetID(); - QueuePacket(endurance_packet); - entity_list.QueueClientsByXTarget(this, endurance_packet, false); + if ((ClientVersionBit() & EQEmu::versions::ClientVersionBit::bit_SoDAndLater) != 0) + QueuePacket(endurance_packet); // do we need this with the OP_ManaChange packet above? + entity_list.QueueClientsByXTarget(this, endurance_packet, false, EQEmu::versions::ClientVersionBit::bit_SoDAndLater); safe_delete(endurance_packet); last_reported_endurance_percent = this->GetEndurancePercent(); @@ -2108,7 +2109,7 @@ void Client::ReadBook(BookRequest_Struct *book) { const EQEmu::ItemInstance *inst = nullptr; - if (read_from_slot <= EQEmu::legacy::SLOT_PERSONAL_BAGS_END) + if (read_from_slot <= EQEmu::invbag::GENERAL_BAGS_END) { inst = m_inv[read_from_slot]; } @@ -2681,6 +2682,60 @@ void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 } } +void Client::Disarm(Client* disarmer, int chance) { + int16 slot = -1; + const EQEmu::ItemInstance *inst = this->GetInv().GetItem(EQEmu::invslot::slotPrimary); + if (inst && inst->IsWeapon()) { + slot = EQEmu::invslot::slotPrimary; + } + else { + inst = this->GetInv().GetItem(EQEmu::invslot::slotSecondary); + if (inst && inst->IsWeapon()) + slot = EQEmu::invslot::slotSecondary; + } + if (slot != -1 && inst->IsClassCommon()) { + // We have an item that can be disarmed. + if (zone->random.Int(0, 1000) <= chance) { + // Find a free inventory slot + int16 slot_id = -1; + slot_id = m_inv.FindFreeSlot(false, true, inst->GetItem()->Size, inst->GetItem()->ItemType); + if (slot_id != -1) + { + EQEmu::ItemInstance *InvItem = m_inv.PopItem(slot); + if (InvItem) { // there should be no way it is not there, but check anyway + EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct)); + MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer; + mi->from_slot = slot; + mi->to_slot = 0xFFFFFFFF; + if (inst->IsStackable()) // it should not be stackable + mi->number_in_stack = inst->GetCharges(); + else + mi->number_in_stack = 0; + FastQueuePacket(&outapp); // this deletes item from the weapon slot on the client + if (PutItemInInventory(slot_id, *InvItem, true)) + database.SaveInventory(this->CharacterID(), NULL, slot); + int matslot = slot == EQEmu::invslot::slotPrimary ? EQEmu::textures::weaponPrimary : EQEmu::textures::weaponSecondary; + if (matslot != -1) + SendWearChange(matslot); + } + Message_StringID(MT_Skills, DISARMED); + if (disarmer != this) + disarmer->Message_StringID(MT_Skills, DISARM_SUCCESS, this->GetCleanName()); + if (chance != 1000) + disarmer->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 4); + CalcBonuses(); + // CalcEnduranceWeightFactor(); + return; + } + disarmer->Message_StringID(MT_Skills, DISARM_FAILED); + if (chance != 1000) + disarmer->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 2); + return; + } + } + disarmer->Message_StringID(MT_Skills, DISARM_FAILED); +} + bool Client::BindWound(Mob *bindmob, bool start, bool fail) { EQApplicationPacket *outapp = nullptr; @@ -3322,28 +3377,28 @@ void Client::LinkDead() uint8 Client::SlotConvert(uint8 slot,bool bracer){ uint8 slot2 = 0; // why are we returning MainCharm instead of INVALID_INDEX? (must be a pre-charm segment...) if(bracer) - return EQEmu::inventory::slotWrist2; + return EQEmu::invslot::slotWrist2; switch(slot) { case EQEmu::textures::armorHead: - slot2 = EQEmu::inventory::slotHead; + slot2 = EQEmu::invslot::slotHead; break; case EQEmu::textures::armorChest: - slot2 = EQEmu::inventory::slotChest; + slot2 = EQEmu::invslot::slotChest; break; case EQEmu::textures::armorArms: - slot2 = EQEmu::inventory::slotArms; + slot2 = EQEmu::invslot::slotArms; break; case EQEmu::textures::armorWrist: - slot2 = EQEmu::inventory::slotWrist1; + slot2 = EQEmu::invslot::slotWrist1; break; case EQEmu::textures::armorHands: - slot2 = EQEmu::inventory::slotHands; + slot2 = EQEmu::invslot::slotHands; break; case EQEmu::textures::armorLegs: - slot2 = EQEmu::inventory::slotLegs; + slot2 = EQEmu::invslot::slotLegs; break; case EQEmu::textures::armorFeet: - slot2 = EQEmu::inventory::slotFeet; + slot2 = EQEmu::invslot::slotFeet; break; } return slot2; @@ -3352,25 +3407,25 @@ uint8 Client::SlotConvert(uint8 slot,bool bracer){ uint8 Client::SlotConvert2(uint8 slot){ uint8 slot2 = 0; // same as above... switch(slot){ - case EQEmu::inventory::slotHead: + case EQEmu::invslot::slotHead: slot2 = EQEmu::textures::armorHead; break; - case EQEmu::inventory::slotChest: + case EQEmu::invslot::slotChest: slot2 = EQEmu::textures::armorChest; break; - case EQEmu::inventory::slotArms: + case EQEmu::invslot::slotArms: slot2 = EQEmu::textures::armorArms; break; - case EQEmu::inventory::slotWrist1: + case EQEmu::invslot::slotWrist1: slot2 = EQEmu::textures::armorWrist; break; - case EQEmu::inventory::slotHands: + case EQEmu::invslot::slotHands: slot2 = EQEmu::textures::armorHands; break; - case EQEmu::inventory::slotLegs: + case EQEmu::invslot::slotLegs: slot2 = EQEmu::textures::armorLegs; break; - case EQEmu::inventory::slotFeet: + case EQEmu::invslot::slotFeet: slot2 = EQEmu::textures::armorFeet; break; } @@ -4425,14 +4480,14 @@ bool Client::GroupFollow(Client* inviter) { uint16 Client::GetPrimarySkillValue() { EQEmu::skills::SkillType skill = EQEmu::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill - bool equiped = m_inv.GetItem(EQEmu::inventory::slotPrimary); + bool equiped = m_inv.GetItem(EQEmu::invslot::slotPrimary); if (!equiped) skill = EQEmu::skills::SkillHandtoHand; else { - uint8 type = m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->ItemType; //is this the best way to do this? + uint8 type = m_inv.GetItem(EQEmu::invslot::slotPrimary)->GetItem()->ItemType; //is this the best way to do this? switch (type) { case EQEmu::item::ItemType1HSlash: // 1H Slashing @@ -4595,29 +4650,32 @@ int Client::GetAggroCount() { return AggroCount; } -void Client::IncrementAggroCount() { - +// we pass in for book keeping if RestRegen is enabled +void Client::IncrementAggroCount(bool raid_target) +{ // This method is called when a client is added to a mob's hate list. It turns the clients aggro flag on so // rest state regen is stopped, and for SoF, it sends the opcode to show the crossed swords in-combat indicator. - // - // AggroCount++; if(!RuleB(Character, RestRegenEnabled)) return; + uint32 newtimer = raid_target ? RuleI(Character, RestRegenRaidTimeToActivate) : RuleI(Character, RestRegenTimeToActivate); + + // save the new timer if it's higher + m_pp.RestTimer = std::max(m_pp.RestTimer, newtimer); + // If we already had aggro before this method was called, the combat indicator should already be up for SoF clients, // so we don't need to send it again. // if(AggroCount > 1) return; - // Pause the rest timer + // Pause the rest timer, it's possible the new timer is a non-raid timer we're currently ticking down on a raid timer if (AggroCount == 1) - SavedRaidRestTimer = rest_timer.GetRemainingTime(); + m_pp.RestTimer = std::max(m_pp.RestTimer, rest_timer.GetRemainingTime() / 1000); if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - auto outapp = new EQApplicationPacket(OP_RestState, 1); char *Buffer = (char *)outapp->pBuffer; VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0x01); @@ -4627,12 +4685,11 @@ void Client::IncrementAggroCount() { } -void Client::DecrementAggroCount() { - +void Client::DecrementAggroCount() +{ // This should be called when a client is removed from a mob's hate list (it dies or is memblurred). // It checks whether any other mob is aggro on the player, and if not, starts the rest timer. // For SoF, the opcode to start the rest state countdown timer in the UI is sent. - // // If we didn't have aggro before, this method should not have been called. if(!AggroCount) @@ -4644,34 +4701,51 @@ void Client::DecrementAggroCount() { return; // Something else is still aggro on us, can't rest yet. - if(AggroCount) return; + if (AggroCount) + return; - uint32 time_until_rest; - if (GetEngagedRaidTarget()) { - time_until_rest = RuleI(Character, RestRegenRaidTimeToActivate) * 1000; - SetEngagedRaidTarget(false); - } else { - if (SavedRaidRestTimer > (RuleI(Character, RestRegenTimeToActivate) * 1000)) { - time_until_rest = SavedRaidRestTimer; - SavedRaidRestTimer = 0; - } else { - time_until_rest = RuleI(Character, RestRegenTimeToActivate) * 1000; - } - } - - rest_timer.Start(time_until_rest); + rest_timer.Start(m_pp.RestTimer * 1000); if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - auto outapp = new EQApplicationPacket(OP_RestState, 5); char *Buffer = (char *)outapp->pBuffer; VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0x00); - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, (uint32)(time_until_rest / 1000)); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, m_pp.RestTimer); QueuePacket(outapp); safe_delete(outapp); } } +// when we cast a beneficial spell we need to steal our targets current timer +// That's what we use this for +void Client::UpdateRestTimer(uint32 new_timer) +{ + // their timer was 0, so we don't do anything + if (new_timer == 0) + return; + + if (!RuleB(Character, RestRegenEnabled)) + return; + + // so if we're currently on aggro, we check our saved timer + if (AggroCount) { + if (m_pp.RestTimer < new_timer) // our timer needs to be updated, don't need to update client here + m_pp.RestTimer = new_timer; + } else { // if we're not aggro, we need to check if current timer needs updating + if (rest_timer.GetRemainingTime() / 1000 < new_timer) { + rest_timer.Start(new_timer * 1000); + if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { + auto outapp = new EQApplicationPacket(OP_RestState, 5); + char *Buffer = (char *)outapp->pBuffer; + VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0x00); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, new_timer); + QueuePacket(outapp); + safe_delete(outapp); + } + } + } +} + void Client::SendPVPStats() { // This sends the data to the client to populate the PVP Stats Window. @@ -5596,7 +5670,7 @@ bool Client::TryReward(uint32 claim_id) // save uint32 free_slot = 0xFFFFFFFF; - for (int i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; ++i) { + for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; ++i) { EQEmu::ItemInstance *item = GetInv().GetItem(i); if (!item) { free_slot = i; @@ -5956,30 +6030,30 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) { } } - inst = requestee->GetInv().GetItem(EQEmu::inventory::slotPowerSource); + inst = requestee->GetInv().GetItem(EQEmu::invslot::SLOT_POWER_SOURCE); if(inst) { item = inst->GetItem(); if(item) { // we shouldn't do this..but, that's the way it's coded atm... // (this type of action should be handled exclusively in the client translator) - strcpy(insr->itemnames[SoF::invslot::PossessionsPowerSource], item->Name); - insr->itemicons[SoF::invslot::PossessionsPowerSource] = item->Icon; + strcpy(insr->itemnames[SoF::invslot::slotPowerSource], item->Name); + insr->itemicons[SoF::invslot::slotPowerSource] = item->Icon; } else - insr->itemicons[SoF::invslot::PossessionsPowerSource] = 0xFFFFFFFF; + insr->itemicons[SoF::invslot::slotPowerSource] = 0xFFFFFFFF; } - inst = requestee->GetInv().GetItem(EQEmu::inventory::slotAmmo); + inst = requestee->GetInv().GetItem(EQEmu::invslot::slotAmmo); if(inst) { item = inst->GetItem(); if(item) { - strcpy(insr->itemnames[SoF::invslot::PossessionsAmmo], item->Name); - insr->itemicons[SoF::invslot::PossessionsAmmo] = item->Icon; + strcpy(insr->itemnames[SoF::invslot::slotAmmo], item->Name); + insr->itemicons[SoF::invslot::slotAmmo] = item->Icon; } else - insr->itemicons[SoF::invslot::PossessionsAmmo] = 0xFFFFFFFF; + insr->itemicons[SoF::invslot::slotAmmo] = 0xFFFFFFFF; } strcpy(insr->text, requestee->GetInspectMessage().text); @@ -7035,7 +7109,7 @@ void Client::SendStatsWindow(Client* client, bool use_window) } EQEmu::skills::SkillType skill = EQEmu::skills::SkillHandtoHand; - auto *inst = GetInv().GetItem(EQEmu::inventory::slotPrimary); + auto *inst = GetInv().GetItem(EQEmu::invslot::slotPrimary); if (inst && inst->IsClassCommon()) { switch (inst->GetItem()->ItemType) { case EQEmu::item::ItemType1HSlash: @@ -7908,7 +7982,7 @@ void Client::GarbleMessage(char *message, uint8 variance) for (size_t i = 0; i < strlen(message); i++) { // Client expects hex values inside of a text link body if (message[i] == delimiter) { - if (!(delimiter_count & 1)) { i += EQEmu::constants::SayLinkBodySize; } + if (!(delimiter_count & 1)) { i += EQEmu::constants::SAY_LINK_BODY_SIZE; } ++delimiter_count; continue; } @@ -8333,17 +8407,17 @@ void Client::TickItemCheck() if(zone->tick_items.empty()) { return; } //Scan equip slots for items - for (i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; i++) + for (i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) { TryItemTick(i); } //Scan main inventory + cursor - for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::inventory::slotCursor; i++) + for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { TryItemTick(i); } //Scan bags - for (i = EQEmu::legacy::GENERAL_BAGS_BEGIN; i <= EQEmu::legacy::CURSOR_BAG_END; i++) + for (i = EQEmu::invbag::GENERAL_BAGS_BEGIN; i <= EQEmu::invbag::CURSOR_BAG_END; i++) { TryItemTick(i); } @@ -8359,7 +8433,7 @@ void Client::TryItemTick(int slot) if(zone->tick_items.count(iid) > 0) { - if (GetLevel() >= zone->tick_items[iid].level && zone->random.Int(0, 100) >= (100 - zone->tick_items[iid].chance) && (zone->tick_items[iid].bagslot || slot <= EQEmu::legacy::EQUIPMENT_END)) + if (GetLevel() >= zone->tick_items[iid].level && zone->random.Int(0, 100) >= (100 - zone->tick_items[iid].chance) && (zone->tick_items[iid].bagslot || slot <= EQEmu::invslot::EQUIPMENT_END)) { EQEmu::ItemInstance* e_inst = (EQEmu::ItemInstance*)inst; parse->EventItem(EVENT_ITEM_TICK, this, e_inst, nullptr, "", slot); @@ -8367,9 +8441,9 @@ void Client::TryItemTick(int slot) } //Only look at augs in main inventory - if (slot > EQEmu::legacy::EQUIPMENT_END) { return; } + if (slot > EQEmu::invslot::EQUIPMENT_END) { return; } - for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x) + for (int x = EQEmu::invaug::SOCKET_BEGIN; x <= EQEmu::invaug::SOCKET_END; ++x) { EQEmu::ItemInstance * a_inst = inst->GetAugment(x); if(!a_inst) { continue; } @@ -8390,17 +8464,17 @@ void Client::TryItemTick(int slot) void Client::ItemTimerCheck() { int i; - for (i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; i++) + for (i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) { TryItemTimer(i); } - for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::inventory::slotCursor; i++) + for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { TryItemTimer(i); } - for (i = EQEmu::legacy::GENERAL_BAGS_BEGIN; i <= EQEmu::legacy::CURSOR_BAG_END; i++) + for (i = EQEmu::invbag::GENERAL_BAGS_BEGIN; i <= EQEmu::invbag::CURSOR_BAG_END; i++) { TryItemTimer(i); } @@ -8422,11 +8496,11 @@ void Client::TryItemTimer(int slot) ++it_iter; } - if (slot > EQEmu::legacy::EQUIPMENT_END) { + if (slot > EQEmu::invslot::EQUIPMENT_END) { return; } - for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x) + for (int x = EQEmu::invaug::SOCKET_BEGIN; x <= EQEmu::invaug::SOCKET_END; ++x) { EQEmu::ItemInstance * a_inst = inst->GetAugment(x); if(!a_inst) { @@ -8715,12 +8789,12 @@ void Client::ShowNumHits() int Client::GetQuiverHaste(int delay) { const EQEmu::ItemInstance *pi = nullptr; - for (int r = EQEmu::legacy::GENERAL_BEGIN; r <= EQEmu::legacy::GENERAL_END; r++) { + for (int r = EQEmu::invslot::GENERAL_BEGIN; r <= EQEmu::invslot::GENERAL_END; r++) { pi = GetInv().GetItem(r); if (pi && pi->IsClassBag() && pi->GetItem()->BagType == EQEmu::item::BagTypeQuiver && pi->GetItem()->BagWR > 0) break; - if (r == EQEmu::legacy::GENERAL_END) + if (r == EQEmu::invslot::GENERAL_END) // we will get here if we don't find a valid quiver return 0; } @@ -8760,7 +8834,7 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold, AddMoneyToPP(copper, silver, gold, platinum, false); if (itemid > 0) - SummonItem(itemid, 0, 0, 0, 0, 0, 0, false, EQEmu::inventory::slotPowerSource); + SummonItem(itemid, 0, 0, 0, 0, 0, 0, false, EQEmu::invslot::slotCursor); if (faction) { diff --git a/zone/client.h b/zone/client.h index 039844f82..ead552f73 100644 --- a/zone/client.h +++ b/zone/client.h @@ -249,7 +249,7 @@ public: //abstract virtual function implementations required by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill); virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None); - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr); virtual bool HasRaid() { return (GetRaid() ? true : false); } virtual bool HasGroup() { return (GetGroup() ? true : false); } @@ -322,8 +322,8 @@ public: void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); bool ShouldISpawnFor(Client *c) { return !GMHideMe(c) && !IsHoveringForRespawn(); } virtual bool Process(); + void ProcessPackets(); void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemData* item, bool buying); - void SendPacketQueue(bool Block = true); void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone); void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL); void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname=nullptr); @@ -803,6 +803,7 @@ public: void NPCSpawn(NPC *target_npc, const char *identifier, uint32 extra = 0); + void Disarm(Client* disarmer, int chance); bool BindWound(Mob* bindmob, bool start, bool fail = false); void SetTradeskillObject(Object* object) { m_tradeskill_object = object; } Object* GetTradeskillObject() { return m_tradeskill_object; } @@ -816,7 +817,7 @@ public: void ChangeTributeSettings(TributeInfo_Struct *t); void SendTributeTimer(); void ToggleTribute(bool enabled); - void SendPathPacket(std::vector &path); + void SendPathPacket(const std::vector &path); inline PTimerList &GetPTimers() { return(p_timers); } @@ -871,7 +872,7 @@ public: void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false); void PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst, ServerLootItem_Struct** bag_item_data = 0); bool AutoPutLootInInventory(EQEmu::ItemInstance& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0); - bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = EQEmu::inventory::slotCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0); + bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = EQEmu::invslot::slotCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0); void SetStats(uint8 type,int16 set_val); void IncStats(uint8 type,int16 increase_val); void DropItem(int16 slot_id, bool recurse = true); @@ -1001,16 +1002,17 @@ public: // Task System Methods void LoadClientTaskState(); void RemoveClientTaskState(); - void SendTaskActivityComplete(int TaskID, int ActivityID, int TaskIndex, int TaskIncomplete=1); - void SendTaskFailed(int TaskID, int TaskIndex); + void SendTaskActivityComplete(int TaskID, int ActivityID, int TaskIndex, TaskType type, int TaskIncomplete=1); + void SendTaskFailed(int TaskID, int TaskIndex, TaskType type); void SendTaskComplete(int TaskIndex); + inline ClientTaskState *GetTaskState() const { return taskstate; } - inline void CancelTask(int TaskIndex) { if(taskstate) taskstate->CancelTask(this, TaskIndex); } + inline void CancelTask(int TaskIndex, TaskType type) { if(taskstate) taskstate->CancelTask(this, TaskIndex, type); } inline bool SaveTaskState() { return (taskmanager ? taskmanager->SaveClientState(this, taskstate) : false); } inline bool IsTaskStateLoaded() { return taskstate != nullptr; } inline bool IsTaskActive(int TaskID) { return (taskstate ? taskstate->IsTaskActive(TaskID) : false); } inline bool IsTaskActivityActive(int TaskID, int ActivityID) { return (taskstate ? taskstate->IsTaskActivityActive(TaskID, ActivityID) : false); } - inline ActivityState GetTaskActivityState(int index, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityState(index, ActivityID) : ActivityHidden); } + inline ActivityState GetTaskActivityState(TaskType type, int index, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityState(type, index, ActivityID) : ActivityHidden); } inline void UpdateTaskActivity(int TaskID, int ActivityID, int Count, bool ignore_quest_update = false) { if (taskstate) taskstate->UpdateTaskActivity(this, TaskID, ActivityID, Count, ignore_quest_update); } inline void ResetTaskActivity(int TaskID, int ActivityID) { if(taskstate) taskstate->ResetTaskActivity(this, TaskID, ActivityID); } inline void UpdateTasksOnKill(int NPCTypeID) { if(taskstate) taskstate->UpdateTasksOnKill(this, NPCTypeID); } @@ -1019,6 +1021,7 @@ public: inline bool UpdateTasksOnSpeakWith(int NPCTypeID) { if(taskstate) return taskstate->UpdateTasksOnSpeakWith(this, NPCTypeID); else return false; } inline bool UpdateTasksOnDeliver(std::list& Items, int Cash, int NPCTypeID) { if (taskstate) return taskstate->UpdateTasksOnDeliver(this, Items, Cash, NPCTypeID); else return false; } inline void TaskSetSelector(Mob *mob, int TaskSetID) { if(taskmanager) taskmanager->TaskSetSelector(this, taskstate, mob, TaskSetID); } + inline void TaskQuestSetSelector(Mob *mob, int count, int *tasks) { if(taskmanager) taskmanager->TaskQuestSetSelector(this, taskstate, mob, count, tasks); } inline void EnableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->EnableTask(CharacterID(), TaskCount, TaskList); } inline void DisableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->DisableTask(CharacterID(), TaskCount, TaskList); } inline bool IsTaskEnabled(int TaskID) { return (taskstate ? taskstate->IsTaskEnabled(TaskID) : false); } @@ -1034,9 +1037,9 @@ public: inline void CancelAllTasks() { if(taskstate) taskstate->CancelAllTasks(this); } inline int GetActiveTaskCount() { return (taskstate ? taskstate->GetActiveTaskCount() : 0); } inline int GetActiveTaskID(int index) { return (taskstate ? taskstate->GetActiveTaskID(index) : -1); } - inline int GetTaskStartTime(int index) { return (taskstate ? taskstate->GetTaskStartTime(index) : -1); } - inline bool IsTaskActivityCompleted(int index, int ActivityID) { return (taskstate ? taskstate->IsTaskActivityCompleted(index, ActivityID) : false); } - inline int GetTaskActivityDoneCount(int ClientTaskIndex, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID) :0); } + inline int GetTaskStartTime(TaskType type, int index) { return (taskstate ? taskstate->GetTaskStartTime(type, index) : -1); } + inline bool IsTaskActivityCompleted(TaskType type, int index, int ActivityID) { return (taskstate ? taskstate->IsTaskActivityCompleted(type, index, ActivityID) : false); } + inline int GetTaskActivityDoneCount(TaskType type, int ClientTaskIndex, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityDoneCount(type, ClientTaskIndex, ActivityID) :0); } inline int GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityDoneCountFromTaskID(TaskID, ActivityID) :0); } inline int ActiveTasksInSet(int TaskSet) { return (taskstate ? taskstate->ActiveTasksInSet(TaskSet) :0); } inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); } @@ -1072,7 +1075,7 @@ public: void ClearPendingAdventureData(); int GetAggroCount(); - void IncrementAggroCount(); + void IncrementAggroCount(bool raid_target = false); void DecrementAggroCount(); void SendPVPStats(); void SendDisciplineTimers(); @@ -1276,9 +1279,6 @@ public: int mod_food_value(const EQEmu::ItemData *item, int change); int mod_drink_value(const EQEmu::ItemData *item, int change); - void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; } - bool GetEngagedRaidTarget() const { return EngagedRaidTarget; } - void ShowNumHits(); // work around function for numhits not showing on buffs void TripInterrogateInvState() { interrogateinv_flag = true; } @@ -1396,6 +1396,9 @@ private: void DoManaRegen(); void DoStaminaHungerUpdate(); void CalcRestState(); + // if they have aggro (AggroCount != 0) their timer is saved in m_pp.RestTimer, else we need to get current timer + inline uint32 GetRestTimer() const { return AggroCount ? m_pp.RestTimer : rest_timer.GetRemainingTime() / 1000; } + void UpdateRestTimer(uint32 new_timer); uint32 pLastUpdate; uint32 pLastUpdateWZ; @@ -1563,9 +1566,6 @@ private: float AreaManaRegen; float AreaEndRegen; - bool EngagedRaidTarget; - uint32 SavedRaidRestTimer; - std::set zone_flags; ClientTaskState *taskstate; diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 696214113..f342fff9f 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -552,7 +552,7 @@ int32 Client::GetRawItemAC() { int32 Total = 0; // this skips MainAmmo..add an '=' conditional if that slot is required (original behavior) - for (int16 slot_id = EQEmu::legacy::EQUIPMENT_BEGIN; slot_id < EQEmu::legacy::EQUIPMENT_END; slot_id++) { + for (int16 slot_id = EQEmu::invslot::BONUS_BEGIN; slot_id <= EQEmu::invslot::BONUS_STAT_END; slot_id++) { const EQEmu::ItemInstance* inst = m_inv[slot_id]; if (inst && inst->IsClassCommon()) { Total += inst->GetItem()->AC; @@ -1319,7 +1319,7 @@ uint32 Client::CalcCurrentWeight() EQEmu::ItemInstance* ins = nullptr; uint32 Total = 0; int x; - for (x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::inventory::slotCursor; x++) { // include cursor or not? + for (x = EQEmu::invslot::POSSESSIONS_BEGIN; x <= EQEmu::invslot::POSSESSIONS_END; x++) { TempItem = 0; ins = GetInv().GetItem(x); if (ins) { @@ -1329,7 +1329,7 @@ uint32 Client::CalcCurrentWeight() Total += TempItem->Weight; } } - for (x = EQEmu::legacy::GENERAL_BAGS_BEGIN; x <= EQEmu::legacy::GENERAL_BAGS_END; x++) { // include cursor bags or not? + for (x = EQEmu::invbag::GENERAL_BAGS_BEGIN; x <= EQEmu::invbag::CURSOR_BAG_END; x++) { int TmpWeight = 0; TempItem = 0; ins = GetInv().GetItem(x); @@ -1342,9 +1342,9 @@ uint32 Client::CalcCurrentWeight() if (TmpWeight > 0) { // this code indicates that weight redux bags can only be in the first general inventory slot to be effective... // is this correct? or can we scan for the highest weight redux and use that? (need client verifications) - int bagslot = EQEmu::inventory::slotGeneral1; + int bagslot = EQEmu::invslot::slotGeneral1; int reduction = 0; - for (int m = EQEmu::legacy::GENERAL_BAGS_BEGIN + 10; m <= EQEmu::legacy::GENERAL_BAGS_END; m += 10) { // include cursor bags or not? + for (int m = EQEmu::invbag::GENERAL_BAGS_BEGIN + EQEmu::invbag::SLOT_COUNT; m <= EQEmu::invbag::CURSOR_BAG_END; m += EQEmu::invbag::SLOT_COUNT) { if (x >= m) { bagslot += 1; } @@ -2293,12 +2293,12 @@ int Client::GetRawACNoShield(int &shield_ac) const { int ac = itembonuses.AC + spellbonuses.AC + aabonuses.AC; shield_ac = 0; - const EQEmu::ItemInstance *inst = m_inv.GetItem(EQEmu::inventory::slotSecondary); + const EQEmu::ItemInstance *inst = m_inv.GetItem(EQEmu::invslot::slotSecondary); if (inst) { if (inst->GetItem()->ItemType == EQEmu::item::ItemTypeShield) { ac -= inst->GetItem()->AC; shield_ac = inst->GetItem()->AC; - for (uint8 i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (uint8 i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { if (inst->GetAugment(i)) { ac -= inst->GetAugment(i)->GetItem()->AC; shield_ac += inst->GetAugment(i)->GetItem()->AC; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 2c5d5f5f6..5cafbaee2 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -181,6 +181,7 @@ void MapOpcodes() ConnectedOpcodes[OP_DeleteItem] = &Client::Handle_OP_DeleteItem; ConnectedOpcodes[OP_DeleteSpawn] = &Client::Handle_OP_DeleteSpawn; ConnectedOpcodes[OP_DeleteSpell] = &Client::Handle_OP_DeleteSpell; + ConnectedOpcodes[OP_Disarm] = &Client::Handle_OP_Disarm; ConnectedOpcodes[OP_DisarmTraps] = &Client::Handle_OP_DisarmTraps; ConnectedOpcodes[OP_DoGroupLeadershipAbility] = &Client::Handle_OP_DoGroupLeadershipAbility; ConnectedOpcodes[OP_DuelResponse] = &Client::Handle_OP_DuelResponse; @@ -1731,7 +1732,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) if (iter == m_inv.cursor_cbegin()) continue; const EQEmu::ItemInstance *inst = *iter; - SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo); } } @@ -2069,7 +2070,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) EQEmu::ItemInstance *inst = database.CreateItem(item, charges); if (!AutoPutLootInInventory(*inst, true, true)) { - PutLootInInventory(EQEmu::inventory::slotCursor, *inst); + PutLootInInventory(EQEmu::invslot::slotCursor, *inst); } Save(1); } @@ -2603,7 +2604,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) EQEmu::ItemInstance *inst = database.CreateItem(item, charges); if (!AutoPutLootInInventory(*inst, true, true)) { - PutLootInInventory(EQEmu::inventory::slotCursor, *inst); + PutLootInInventory(EQEmu::invslot::slotCursor, *inst); } Save(1); @@ -2653,7 +2654,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) SetAlternateCurrencyValue(reclaim->currency_id, 0); } else { - SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, EQEmu::inventory::slotCursor); + SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, EQEmu::invslot::slotCursor); AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count)); } /* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */ @@ -2866,8 +2867,8 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) uint32 ApplyPoisonSuccessResult = 0; ApplyPoison_Struct* ApplyPoisonData = (ApplyPoison_Struct*)app->pBuffer; - const EQEmu::ItemInstance* PrimaryWeapon = GetInv().GetItem(EQEmu::inventory::slotPrimary); - const EQEmu::ItemInstance* SecondaryWeapon = GetInv().GetItem(EQEmu::inventory::slotSecondary); + const EQEmu::ItemInstance* PrimaryWeapon = GetInv().GetItem(EQEmu::invslot::slotPrimary); + const EQEmu::ItemInstance* SecondaryWeapon = GetInv().GetItem(EQEmu::invslot::slotSecondary); const EQEmu::ItemInstance* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot]; const EQEmu::ItemData* poison=PoisonItemInstance->GetItem(); const EQEmu::ItemData* primary=nullptr; @@ -3001,14 +3002,14 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) bool deleteItems = false; if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF) { - if ((in_augment->container_slot < 0 || in_augment->container_slot >= EQEmu::legacy::SLOT_CURSOR) && - in_augment->container_slot != EQEmu::legacy::SLOT_POWER_SOURCE && - (in_augment->container_slot < EQEmu::legacy::SLOT_PERSONAL_BAGS_BEGIN || in_augment->container_slot > EQEmu::legacy::SLOT_PERSONAL_BAGS_END)) + if ((in_augment->container_slot < 0 || in_augment->container_slot >= EQEmu::invslot::slotCursor) && + in_augment->container_slot != EQEmu::invslot::SLOT_POWER_SOURCE && + (in_augment->container_slot < EQEmu::invbag::GENERAL_BAGS_BEGIN || in_augment->container_slot > EQEmu::invbag::GENERAL_BAGS_END)) { Message(13, "The server does not allow augmentation actions from this slot."); - auto cursor_item = m_inv[EQEmu::legacy::SLOT_CURSOR]; + auto cursor_item = m_inv[EQEmu::invslot::slotCursor]; auto augmented_item = m_inv[in_augment->container_slot]; - SendItemPacket(EQEmu::legacy::SLOT_CURSOR, cursor_item, ItemPacketCharInventory); + SendItemPacket(EQEmu::invslot::slotCursor, cursor_item, ItemPacketCharInventory); // this may crash clients on certain slots SendItemPacket(in_augment->container_slot, augmented_item, ItemPacketCharInventory); return; @@ -3083,7 +3084,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) { case 0: // Adding an augment case 2: // Swapping augment - new_aug = user_inv.GetItem(EQEmu::inventory::slotCursor); + new_aug = user_inv.GetItem(EQEmu::invslot::slotCursor); if (!new_aug) // Shouldn't get the OP code without the augment on the user's cursor, but maybe it's h4x. { @@ -3141,7 +3142,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (itemOneToPush) { DeleteItemInInventory(item_slot, 0, true); - DeleteItemInInventory(EQEmu::inventory::slotCursor, new_aug->IsStackable() ? 1 : 0, true); + DeleteItemInInventory(EQEmu::invslot::slotCursor, new_aug->IsStackable() ? 1 : 0, true); if (solvent) { @@ -3152,7 +3153,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (itemTwoToPush) { // This is a swap. Return the old aug to the player's cursor. - if (!PutItemInInventory(EQEmu::inventory::slotCursor, *itemTwoToPush, true)) + if (!PutItemInInventory(EQEmu::invslot::slotCursor, *itemTwoToPush, true)) { Log(Logs::General, Logs::Error, "Problem returning old augment to player's cursor after augmentation swap."); Message(15, "Error: Failed to retrieve old augment after augmentation swap!"); @@ -3237,7 +3238,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) } // Drop the removed augment on the player's cursor - if (!PutItemInInventory(EQEmu::inventory::slotCursor, *itemTwoToPush, true)) + if (!PutItemInInventory(EQEmu::invslot::slotCursor, *itemTwoToPush, true)) { Log(Logs::General, Logs::Error, "Problem returning augment to player's cursor after safe removal."); Message(15, "Error: Failed to return augment after removal from item!"); @@ -4031,7 +4032,7 @@ void Client::Handle_OP_CancelTask(const EQApplicationPacket *app) CancelTask_Struct *cts = (CancelTask_Struct*)app->pBuffer; if (RuleB(TaskSystem, EnableTaskSystem) && taskstate) - taskstate->CancelTask(this, cts->SequenceNumber); + taskstate->CancelTask(this, cts->SequenceNumber, static_cast(cts->type)); } void Client::Handle_OP_CancelTrade(const EQApplicationPacket *app) @@ -4175,7 +4176,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) } else { - Message(0, "Error: castspell->inventoryslot >= %i (0x%04x)", EQEmu::inventory::slotCursor, castspell->inventoryslot); + Message(0, "Error: castspell->inventoryslot >= %i (0x%04x)", EQEmu::invslot::slotCursor, castspell->inventoryslot); InterruptSpell(castspell->spell_id); } } @@ -4407,8 +4408,7 @@ void Client::Handle_OP_ClientTimeStamp(const EQApplicationPacket *app) return; } -void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) -{ +void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { if (IsAIControlled()) return; @@ -4418,17 +4418,19 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) /* Invalid size check */ if (app->size != sizeof(PlayerPositionUpdateClient_Struct) && app->size != (sizeof(PlayerPositionUpdateClient_Struct) + 1) - ) { - Log(Logs::General, Logs::Error, "OP size error: OP_ClientUpdate expected:%i got:%i", sizeof(PlayerPositionUpdateClient_Struct), app->size); + ) { + Log(Logs::General, Logs::Error, "OP size error: OP_ClientUpdate expected:%i got:%i", + sizeof(PlayerPositionUpdateClient_Struct), app->size); return; } - PlayerPositionUpdateClient_Struct* ppu = (PlayerPositionUpdateClient_Struct*)app->pBuffer; + + PlayerPositionUpdateClient_Struct *ppu = (PlayerPositionUpdateClient_Struct *) app->pBuffer; /* Boat handling */ if (ppu->spawn_id != GetID()) { /* If player is controlling boat */ if (ppu->spawn_id == controlling_boat_id) { - Mob* boat = entity_list.GetMob(controlling_boat_id); + Mob *boat = entity_list.GetMob(controlling_boat_id); if (boat == 0) { controlling_boat_id = 0; return; @@ -4436,9 +4438,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading)); boat->SetDelta(boat_delta); - + auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; + PlayerPositionUpdateServer_Struct *ppus = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer; boat->MakeSpawnUpdate(ppus); entity_list.QueueCloseClients(boat, outapp, true, 300, this, false); safe_delete(outapp); @@ -4446,16 +4448,15 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) /* Update the boat's position on the server, without sending an update */ boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false); return; - } - else return; + } else return; } float dist = 0; float tmp; tmp = m_Position.x - ppu->x_pos; - dist += tmp*tmp; + dist += tmp * tmp; tmp = m_Position.y - ppu->y_pos; - dist += tmp*tmp; + dist += tmp * tmp; dist = sqrt(dist); /* Hack checks */ @@ -4463,29 +4464,28 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) if (m_DistanceSinceLastPositionCheck > 0.0) { uint32 cur_time = Timer::GetCurrentTime(); if ((cur_time - m_TimeSinceLastPositionCheck) > 0) { - float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); + float speed = + (m_DistanceSinceLastPositionCheck * 100) / (float) (cur_time - m_TimeSinceLastPositionCheck); int runs = GetRunspeed(); if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) { - if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { + if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || + (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { if (IsShadowStepExempted()) { if (m_DistanceSinceLastPositionCheck > 800) { CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos); } - } - else if (IsKnockBackExempted()) { + } else if (IsKnockBackExempted()) { if (speed > 30.0f) { CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos); } - } - else if (!IsPortExempted()) { + } else if (!IsPortExempted()) { if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) { if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) { m_TimeSinceLastPositionCheck = cur_time; m_DistanceSinceLastPositionCheck = 0.0f; CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos); //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - } - else { + } else { CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } @@ -4499,43 +4499,39 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) m_DistanceSinceLastPositionCheck = 0.0f; m_CheatDetectMoved = false; } - } - else { + } else { m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); m_CheatDetectMoved = false; } - } - else { + } else { m_DistanceSinceLastPositionCheck += dist; m_CheatDetectMoved = true; if (m_TimeSinceLastPositionCheck == 0) { m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); - } - else { + } else { uint32 cur_time = Timer::GetCurrentTime(); if ((cur_time - m_TimeSinceLastPositionCheck) > 2500) { - float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); + float speed = + (m_DistanceSinceLastPositionCheck * 100) / (float) (cur_time - m_TimeSinceLastPositionCheck); int runs = GetRunspeed(); if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) { - if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { + if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || + (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { if (IsShadowStepExempted()) { if (m_DistanceSinceLastPositionCheck > 800) { CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos); } - } - else if (IsKnockBackExempted()) { + } else if (IsKnockBackExempted()) { if (speed > 30.0f) { CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos); } - } - else if (!IsPortExempted()) { + } else if (!IsPortExempted()) { if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) { if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) { m_TimeSinceLastPositionCheck = cur_time; m_DistanceSinceLastPositionCheck = 0.0f; CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - else { + } else { CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } @@ -4603,8 +4599,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) improved_hidden = false; if (!invisible) { auto outapp = - new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct)); - SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer; + new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct)); + SpawnAppearance_Struct *sa_out = (SpawnAppearance_Struct *) outapp->pBuffer; sa_out->spawn_id = GetID(); sa_out->type = 0x03; sa_out->parameter = 0; @@ -4619,7 +4615,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) is_client_moving = (ppu->y_pos == m_Position.y && ppu->x_pos == m_Position.x) ? false : true; if (is_client_moving) { - Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is moving - scan timer is: %u", client_scan_npc_aggro_timer.GetDuration()); + Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is moving - scan timer is: %u", + client_scan_npc_aggro_timer.GetDuration()); if (client_scan_npc_aggro_timer.GetDuration() > 1000) { npc_close_scan_timer.Disable(); @@ -4629,9 +4626,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) client_scan_npc_aggro_timer.Start(500); } - } - else { - Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is NOT moving - scan timer is: %u", client_scan_npc_aggro_timer.GetDuration()); + } else { + Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is NOT moving - scan timer is: %u", + client_scan_npc_aggro_timer.GetDuration()); if (client_scan_npc_aggro_timer.GetDuration() < 1000) { npc_close_scan_timer.Disable(); @@ -4641,7 +4638,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) client_scan_npc_aggro_timer.Start(3000); } } - + float new_heading = EQ12toFloat(ppu->heading); int32 new_animation = ppu->animation; @@ -4649,10 +4646,11 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) m_Position.x = ppu->x_pos; m_Position.y = ppu->y_pos; m_Position.z = ppu->z_pos; - + /* Visual Debugging */ if (RuleB(Character, OPClientUpdateVisualDebug)) { - Log(Logs::General, Logs::Debug, "ClientUpdate: ppu x: %f y: %f z: %f h: %u", ppu->x_pos, ppu->y_pos, ppu->z_pos, ppu->heading); + Log(Logs::General, Logs::Debug, "ClientUpdate: ppu x: %f y: %f z: %f h: %u", ppu->x_pos, ppu->y_pos, ppu->z_pos, + ppu->heading); this->SendAppearanceEffect(78, 0, 0, 0, 0); this->SendAppearanceEffect(41, 0, 0, 0, 0); } @@ -4665,14 +4663,13 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) /* Broadcast update to other clients */ auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* position_update = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; + PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer; MakeSpawnUpdate(position_update); if (gm_hide_me) { entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250); - } - else { + } else { entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true); } @@ -4683,8 +4680,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) if (raid) { raid->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); - } - else if (group) { + } else if (group) { group->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); } @@ -4692,11 +4688,17 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) } if (zone->watermap) { - if (zone->watermap->InLiquid(glm::vec3(m_Position))) + if (zone->watermap->InLiquid(glm::vec3(m_Position))) { CheckIncreaseSkill(EQEmu::skills::SkillSwimming, nullptr, -17); + + // Dismount horses when entering water + if (GetHorseId() && RuleB(Character, DismountWater)) { + SetHorseId(0); + BuffFadeByEffect(SE_SummonHorse); + } + } CheckRegionTypeChanges(); } - return; } @@ -5122,7 +5124,7 @@ void Client::Handle_OP_CreateObject(const EQApplicationPacket *app) if (LogSys.log_settings[Logs::Inventory].is_category_enabled) Log(Logs::Detail, Logs::Inventory, "Handle_OP_CreateObject() [psize: %u] %s", app->size, DumpPacketToString(app).c_str()); - DropItem(EQEmu::inventory::slotCursor); + DropItem(EQEmu::invslot::slotCursor); return; } @@ -5323,6 +5325,97 @@ void Client::Handle_OP_DeleteSpawn(const EQApplicationPacket *app) return; } +void Client::Handle_OP_Disarm(const EQApplicationPacket *app) { + if (dead || bZoning) return; + if (!HasSkill(EQEmu::skills::SkillDisarm)) + return; + + if (app->size != sizeof(Disarm_Struct)) { + Log(Logs::General, Logs::Skills, "Size mismatch for Disarm_Struct packet"); + return; + } + + Disarm_Struct *disarm = (Disarm_Struct *)app->pBuffer; + + if (!p_timers.Expired(&database, pTimerCombatAbility2, false)) { + Message(13, "Ability recovery time not yet met."); + return; + } + + p_timers.Start(pTimerCombatAbility2, 8); + + BreakInvis(); + Mob* pmob = entity_list.GetMob(disarm->source); + Mob* tmob = entity_list.GetMob(disarm->target); + if (!pmob || !tmob) + return; + if (pmob->GetID() != GetID()) { + // Client sent a disarm request with an originator ID not matching their own ID. + char *hack_str = NULL; + MakeAnyLenString(&hack_str, "Player %s (%d) sent OP_Disarm with source ID of: %d", GetCleanName(), GetID(), pmob->GetID()); + database.SetMQDetectionFlag(this->account_name, this->name, hack_str, zone->GetShortName()); + safe_delete_array(hack_str); + return; + } + // No disarm on corpses + if (tmob->IsCorpse()) + return; + // No target + if (!GetTarget()) + return; + // Targets don't match (possible hack, but not flagging) + if (GetTarget() != tmob) { + return; + } + // Too far away + if (pmob->CalculateDistance(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ()) > 400) + return; + + // Can't see mob + //if (tmob->BehindMob(pmob)) + // return; + // How can we disarm someone if we are feigned. + if (GetFeigned()) + return; + // We can't disarm someone who is feigned. + if (tmob->IsClient() && tmob->CastToClient()->GetFeigned()) + return; + if (GetTarget() == tmob && pmob == this->CastToMob() && + disarm->skill == GetSkill(EQEmu::skills::SkillDisarm) && IsAttackAllowed(tmob)) { + int p_level = pmob->GetLevel() ? pmob->GetLevel() : 1; + int t_level = tmob->GetLevel() ? tmob->GetLevel() : 1; + // We have a disarmable target - sucess or fail, we always aggro the mob + if (tmob->IsNPC()) { + if (!tmob->CheckAggro(pmob)) { + zone->AddAggroMob(); + tmob->AddToHateList(pmob, p_level); + } + else { + tmob->AddToHateList(pmob, p_level / 3); + } + } + int chance = GetSkill(EQEmu::skills::SkillDisarm); // (1% @ 0 skill) (11% @ 200 skill) - against even con + chance /= 2; + chance += 10; + // Modify chance based on level difference + float lvl_mod = p_level / t_level; + chance *= lvl_mod; + if (chance > 300) + chance = 300; // max chance of 30% + if (tmob->IsNPC()) { + tmob->CastToNPC()->Disarm(this, chance); + } + else if (tmob->IsClient()) { + tmob->CastToClient()->Disarm(this, chance); + } + return; + } + // Trying to disarm something we can't disarm + Message_StringID(MT_Skills, DISARM_NO_TARGET); + + return; +} + void Client::Handle_OP_DeleteSpell(const EQApplicationPacket *app) { if (app->size != sizeof(DeleteSpell_Struct)) @@ -5761,124 +5854,107 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app) printf("Error in FindPersonRequest_Struct. Expected size of: %zu, but got: %i\n", sizeof(FindPersonRequest_Struct), app->size); else { FindPersonRequest_Struct* t = (FindPersonRequest_Struct*)app->pBuffer; - + std::vector points; Mob* target = entity_list.GetMob(t->npc_id); - + if (target == nullptr) { //empty length packet == not found. EQApplicationPacket outapp(OP_FindPersonReply, 0); QueuePacket(&outapp); return; } - + if (!RuleB(Pathing, Find) && RuleB(Bazaar, EnableWarpToTrader) && target->IsClient() && (target->CastToClient()->Trader || target->CastToClient()->Buyer)) { Message(15, "Moving you to Trader %s", target->GetName()); MovePC(zone->GetZoneID(), zone->GetInstanceID(), target->GetX(), target->GetY(), target->GetZ(), 0.0f); } - + if (!RuleB(Pathing, Find) || !zone->pathing) { //fill in the path array... // - points.resize(2); - points[0].x = GetX(); - points[0].y = GetY(); - points[0].z = GetZ(); - points[1].x = target->GetX(); - points[1].y = target->GetY(); - points[1].z = target->GetZ(); + points.clear(); + FindPerson_Point a; + FindPerson_Point b; + + a.x = GetX(); + a.y = GetY(); + a.z = GetZ(); + b.x = target->GetX(); + b.y = target->GetY(); + b.z = target->GetZ(); + + points.push_back(a); + points.push_back(b); } else { glm::vec3 Start(GetX(), GetY(), GetZ() + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION); glm::vec3 End(target->GetX(), target->GetY(), target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION); - - if (!zone->zonemap->LineIntersectsZone(Start, End, 1.0f, nullptr) && zone->pathing->NoHazards(Start, End)) + + bool partial = false; + bool stuck = false; + auto pathlist = zone->pathing->FindRoute(Start, End, partial, stuck); + + if (pathlist.empty() || partial) { - points.resize(2); - points[0].x = Start.x; - points[0].y = Start.y; - points[0].z = Start.z; - - points[1].x = End.x; - points[1].y = End.y; - points[1].z = End.z; - + EQApplicationPacket outapp(OP_FindPersonReply, 0); + QueuePacket(&outapp); + return; } - else + + // Live appears to send the points in this order: + // Final destination. + // Current Position. + // rest of the points. + FindPerson_Point p; + + int PointNumber = 0; + + bool LeadsToTeleporter = false; + + auto v = pathlist.back(); + + p.x = v.pos.x; + p.y = v.pos.y; + p.z = v.pos.z; + points.push_back(p); + + p.x = GetX(); + p.y = GetY(); + p.z = GetZ(); + points.push_back(p); + + for (auto Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator) { - std::deque pathlist = zone->pathing->FindRoute(Start, End); - - if (pathlist.empty()) + if ((*Iterator).teleport) // Teleporter { - EQApplicationPacket outapp(OP_FindPersonReply, 0); - QueuePacket(&outapp); - return; + LeadsToTeleporter = true; + break; } - - //the client seems to have issues with packets larger than this - if (pathlist.size() > 36) - { - EQApplicationPacket outapp(OP_FindPersonReply, 0); - QueuePacket(&outapp); - return; - } - - // Live appears to send the points in this order: - // Final destination. - // Current Position. - // rest of the points. - FindPerson_Point p; - - int PointNumber = 0; - - bool LeadsToTeleporter = false; - - glm::vec3 v = zone->pathing->GetPathNodeCoordinates(pathlist.back()); - + + glm::vec3 v = (*Iterator).pos; p.x = v.x; p.y = v.y; p.z = v.z; points.push_back(p); - - p.x = GetX(); - p.y = GetY(); - p.z = GetZ(); + ++PointNumber; + } + + if (!LeadsToTeleporter) + { + p.x = target->GetX(); + p.y = target->GetY(); + p.z = target->GetZ(); + points.push_back(p); - - for (auto Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator) - { - if ((*Iterator) == -1) // Teleporter - { - LeadsToTeleporter = true; - break; - } - - glm::vec3 v = zone->pathing->GetPathNodeCoordinates((*Iterator), false); - p.x = v.x; - p.y = v.y; - p.z = v.z; - points.push_back(p); - ++PointNumber; - } - - if (!LeadsToTeleporter) - { - p.x = target->GetX(); - p.y = target->GetY(); - p.z = target->GetZ(); - - points.push_back(p); - } - } } - + SendPathPacket(points); } - return; } void Client::Handle_OP_Fishing(const EQApplicationPacket *app) @@ -7065,7 +7141,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) return; } - EQEmu::ItemInstance *CursorItemInst = GetInv().GetItem(EQEmu::inventory::slotCursor); + EQEmu::ItemInstance *CursorItemInst = GetInv().GetItem(EQEmu::invslot::slotCursor); bool Allowed = true; @@ -7113,7 +7189,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { GuildBankDepositAck(false, sentAction); - DeleteItemInInventory(EQEmu::inventory::slotCursor, 0, false); + DeleteItemInInventory(EQEmu::invslot::slotCursor, 0, false); } break; @@ -7134,7 +7210,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) case GuildBankWithdraw: { - if (GetInv()[EQEmu::inventory::slotCursor]) + if (GetInv()[EQEmu::invslot::slotCursor]) { Message_StringID(13, GUILD_BANK_EMPTY_HANDS); @@ -7180,7 +7256,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { PushItemOnCursor(*inst); - SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo); GuildBanks->DeleteItem(GuildID(), gbwis->Area, gbwis->SlotID, gbwis->Quantity); } @@ -8163,7 +8239,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) const EQEmu::ItemData* item = nullptr; int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - for (int16 L = EQEmu::legacy::EQUIPMENT_BEGIN; L <= EQEmu::inventory::slotWaist; L++) { + for (int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::slotWaist; L++) { const EQEmu::ItemInstance* inst = GetInv().GetItem(L); item = inst ? inst->GetItem() : nullptr; @@ -8183,15 +8259,15 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) else { insr->itemicons[L] = 0xFFFFFFFF; } } - const EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::inventory::slotAmmo); + const EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::invslot::slotAmmo); item = inst ? inst->GetItem() : nullptr; if (item) { // another one..I did these, didn't I!!? - strcpy(insr->itemnames[SoF::invslot::PossessionsAmmo], item->Name); - insr->itemicons[SoF::invslot::PossessionsAmmo] = item->Icon; + strcpy(insr->itemnames[SoF::invslot::slotAmmo], item->Name); + insr->itemicons[SoF::invslot::slotAmmo] = item->Icon; } - else { insr->itemicons[SoF::invslot::PossessionsAmmo] = 0xFFFFFFFF; } + else { insr->itemicons[SoF::invslot::slotAmmo] = 0xFFFFFFFF; } InspectMessage_Struct* newmessage = (InspectMessage_Struct*)insr->text; InspectMessage_Struct& playermessage = this->GetInspectMessage(); @@ -8264,7 +8340,6 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) return; } - DumpPacket(app); ItemViewRequest_Struct *ivrs = (ItemViewRequest_Struct *)app->pBuffer; // todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data @@ -8654,7 +8729,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) EQEmu::ItemInstance* clickaug = nullptr; EQEmu::ItemData* augitem = nullptr; - for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) { + for (r = EQEmu::invaug::SOCKET_BEGIN; r <= EQEmu::invaug::SOCKET_END; r++) { const EQEmu::ItemInstance* aug_i = inst->GetAugment(r); if (!aug_i) continue; @@ -9834,7 +9909,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer; if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id)) { - if (mi->from_slot != mi->to_slot && (mi->from_slot <= EQEmu::legacy::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) + if (mi->from_slot != mi->to_slot && (mi->from_slot <= EQEmu::invslot::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) { char *detect = nullptr; const EQEmu::ItemInstance *itm_from = GetInv().GetItem(mi->from_slot); @@ -9855,8 +9930,8 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) // Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered. bool mi_hack = false; - if (mi->from_slot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && mi->from_slot <= EQEmu::legacy::CURSOR_BAG_END) { - if (mi->from_slot >= EQEmu::legacy::CURSOR_BAG_BEGIN) { mi_hack = true; } + if (mi->from_slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && mi->from_slot <= EQEmu::invbag::CURSOR_BAG_END) { + if (mi->from_slot >= EQEmu::invbag::CURSOR_BAG_BEGIN) { mi_hack = true; } else { int16 from_parent = m_inv.CalcSlotId(mi->from_slot); if (!m_inv[from_parent]) { mi_hack = true; } @@ -9865,8 +9940,8 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) } } - if (mi->to_slot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && mi->to_slot <= EQEmu::legacy::CURSOR_BAG_END) { - if (mi->to_slot >= EQEmu::legacy::CURSOR_BAG_BEGIN) { mi_hack = true; } + if (mi->to_slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && mi->to_slot <= EQEmu::invbag::CURSOR_BAG_END) { + if (mi->to_slot >= EQEmu::invbag::CURSOR_BAG_BEGIN) { mi_hack = true; } else { int16 to_parent = m_inv.CalcSlotId(mi->to_slot); if (!m_inv[to_parent]) { mi_hack = true; } @@ -12492,7 +12567,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) Shielding_Struct* shield = (Shielding_Struct*)app->pBuffer; shield_target = entity_list.GetMob(shield->target_id); bool ack = false; - EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::inventory::slotSecondary); + EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::invslot::slotSecondary); if (!shield_target) return; if (inst) @@ -12704,8 +12779,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) // shouldn't we be reimbursing if these two fail? //make sure we are not completely full... - if (freeslotid == EQEmu::inventory::slotCursor) { - if (m_inv.GetItem(EQEmu::inventory::slotCursor) != nullptr) { + if (freeslotid == EQEmu::invslot::slotCursor) { + if (m_inv.GetItem(EQEmu::invslot::slotCursor) != nullptr) { Message(13, "You do not have room for any more items."); safe_delete(outapp); safe_delete(inst); @@ -13328,13 +13403,13 @@ void Client::Handle_OP_Split(const EQApplicationPacket *app) //Per the note above, Im not exactly sure what to do on error //to notify the client of the error... if (!isgrouped) { - Message(13, "You can not split money if your not in a group."); + Message(13, "You can not split money if you're not in a group."); return; } Group *cgroup = GetGroup(); if (cgroup == nullptr) { //invalid group, not sure if we should say more... - Message(13, "You can not split money if your not in a group."); + Message(13, "You can not split money if you're not in a group."); return; } diff --git a/zone/client_packet.h b/zone/client_packet.h index 4f9902599..9605dc8cf 100644 --- a/zone/client_packet.h +++ b/zone/client_packet.h @@ -94,6 +94,7 @@ void Handle_OP_DeleteItem(const EQApplicationPacket *app); void Handle_OP_DeleteSpawn(const EQApplicationPacket *app); void Handle_OP_DeleteSpell(const EQApplicationPacket *app); + void Handle_OP_Disarm(const EQApplicationPacket *app); void Handle_OP_DisarmTraps(const EQApplicationPacket *app); void Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app); void Handle_OP_DuelResponse(const EQApplicationPacket *app); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index c5801044f..bd14dc70a 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -310,7 +310,7 @@ bool Client::Process() { } if (AutoFireEnabled()) { - EQEmu::ItemInstance *ranged = GetInv().GetItem(EQEmu::inventory::slotRange); + EQEmu::ItemInstance *ranged = GetInv().GetItem(EQEmu::invslot::slotRange); if (ranged) { if (ranged->GetItem() && ranged->GetItem()->ItemType == EQEmu::item::ItemTypeBow) { @@ -405,11 +405,11 @@ bool Client::Process() { } else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP { - EQEmu::ItemInstance *wpn = GetInv().GetItem(EQEmu::inventory::slotPrimary); - TryWeaponProc(wpn, auto_attack_target, EQEmu::inventory::slotPrimary); - TriggerDefensiveProcs(auto_attack_target, EQEmu::inventory::slotPrimary, false); + EQEmu::ItemInstance *wpn = GetInv().GetItem(EQEmu::invslot::slotPrimary); + TryWeaponProc(wpn, auto_attack_target, EQEmu::invslot::slotPrimary); + TriggerDefensiveProcs(auto_attack_target, EQEmu::invslot::slotPrimary, false); - DoAttackRounds(auto_attack_target, EQEmu::inventory::slotPrimary); + DoAttackRounds(auto_attack_target, EQEmu::invslot::slotPrimary); if (CheckAATimer(aaTimerRampage)) entity_list.AEAttack(this, 30); } @@ -445,10 +445,10 @@ bool Client::Process() { else if (auto_attack_target->GetHP() > -10) { CheckIncreaseSkill(EQEmu::skills::SkillDualWield, auto_attack_target, -10); if (CheckDualWield()) { - EQEmu::ItemInstance *wpn = GetInv().GetItem(EQEmu::inventory::slotSecondary); - TryWeaponProc(wpn, auto_attack_target, EQEmu::inventory::slotSecondary); + EQEmu::ItemInstance *wpn = GetInv().GetItem(EQEmu::invslot::slotSecondary); + TryWeaponProc(wpn, auto_attack_target, EQEmu::invslot::slotSecondary); - DoAttackRounds(auto_attack_target, EQEmu::inventory::slotSecondary); + DoAttackRounds(auto_attack_target, EQEmu::invslot::slotSecondary); } } } @@ -622,9 +622,8 @@ bool Client::Process() { EQApplicationPacket *app = nullptr; if (!eqs->CheckState(CLOSING)) { - while (ret && (app = (EQApplicationPacket *)eqs->PopPacket())) { - if (app) - ret = HandlePacket(app); + while (app = eqs->PopPacket()) { + HandlePacket(app); safe_delete(app); } } @@ -777,7 +776,7 @@ void Client::BulkSendInventoryItems() { // LINKDEAD TRADE ITEMS // Move trade slot items back into normal inventory..need them there now for the proceeding validity checks - for (int16 slot_id = EQEmu::legacy::TRADE_BEGIN; slot_id <= EQEmu::legacy::TRADE_END; slot_id++) { + for (int16 slot_id = EQEmu::invslot::TRADE_BEGIN; slot_id <= EQEmu::invslot::TRADE_END; slot_id++) { EQEmu::ItemInstance* inst = m_inv.PopItem(slot_id); if(inst) { bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false; @@ -803,7 +802,7 @@ void Client::BulkSendInventoryItems() EQEmu::OutBuffer::pos_type last_pos = ob.tellp(); // Possessions items - for (int16 slot_id = EQEmu::inventory::slotBegin; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) { + for (int16 slot_id = EQEmu::invslot::POSSESSIONS_BEGIN; slot_id <= EQEmu::invslot::POSSESSIONS_END; slot_id++) { const EQEmu::ItemInstance* inst = m_inv[slot_id]; if (!inst) continue; @@ -818,19 +817,19 @@ void Client::BulkSendInventoryItems() // PowerSource item if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - const EQEmu::ItemInstance* inst = m_inv[EQEmu::inventory::slotPowerSource]; + const EQEmu::ItemInstance* inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]; if (inst) { - inst->Serialize(ob, EQEmu::inventory::slotPowerSource); + inst->Serialize(ob, EQEmu::invslot::SLOT_POWER_SOURCE); if (ob.tellp() == last_pos) - Log(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::inventory::slotPowerSource); + Log(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::invslot::SLOT_POWER_SOURCE); last_pos = ob.tellp(); } } // Bank items - for (int16 slot_id = EQEmu::legacy::BANK_BEGIN; slot_id <= EQEmu::legacy::BANK_END; slot_id++) { + for (int16 slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; slot_id++) { const EQEmu::ItemInstance* inst = m_inv[slot_id]; if (!inst) continue; @@ -844,7 +843,7 @@ void Client::BulkSendInventoryItems() } // SharedBank items - for (int16 slot_id = EQEmu::legacy::SHARED_BANK_BEGIN; slot_id <= EQEmu::legacy::SHARED_BANK_END; slot_id++) { + for (int16 slot_id = EQEmu::invslot::SHARED_BANK_BEGIN; slot_id <= EQEmu::invslot::SHARED_BANK_END; slot_id++) { const EQEmu::ItemInstance* inst = m_inv[slot_id]; if (!inst) continue; @@ -1134,7 +1133,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) switch(memspell->scribing) { case memSpellScribing: { // scribing spell to book - const EQEmu::ItemInstance* inst = m_inv[EQEmu::inventory::slotCursor]; + const EQEmu::ItemInstance* inst = m_inv[EQEmu::invslot::slotCursor]; if (inst && inst->IsClassCommon()) { @@ -1148,7 +1147,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) if(item && item->Scroll.Effect == (int32)(memspell->spell_id)) { ScribeSpell(memspell->spell_id, memspell->slot); - DeleteItemInInventory(EQEmu::inventory::slotCursor, 1, true); + DeleteItemInInventory(EQEmu::invslot::slotCursor, 1, true); } else Message(0,"Scribing spell: inst exists but item does not or spell ids do not match."); @@ -1541,9 +1540,11 @@ void Client::OPGMTraining(const EQApplicationPacket *app) return; //you can only use your own trainer, client enforces this, but why trust it - int trains_class = pTrainer->GetClass() - (WARRIORGM - WARRIOR); - if(GetClass() != trains_class) - return; + if (!RuleB(Character, AllowCrossClassTrainers)) { + int trains_class = pTrainer->GetClass() - (WARRIORGM - WARRIOR); + if (GetClass() != trains_class) + return; + } //you have to be somewhat close to a trainer to be properly using them if(DistanceSquared(m_Position,pTrainer->GetPosition()) > USE_NPC_RANGE2) @@ -1594,9 +1595,11 @@ void Client::OPGMEndTraining(const EQApplicationPacket *app) return; //you can only use your own trainer, client enforces this, but why trust it - int trains_class = pTrainer->GetClass() - (WARRIORGM - WARRIOR); - if(GetClass() != trains_class) - return; + if (!RuleB(Character, AllowCrossClassTrainers)) { + int trains_class = pTrainer->GetClass() - (WARRIORGM - WARRIOR); + if (GetClass() != trains_class) + return; + } //you have to be somewhat close to a trainer to be properly using them if(DistanceSquared(m_Position, pTrainer->GetPosition()) > USE_NPC_RANGE2) @@ -1623,9 +1626,11 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) return; //you can only use your own trainer, client enforces this, but why trust it - int trains_class = pTrainer->GetClass() - (WARRIORGM - WARRIOR); - if(GetClass() != trains_class) - return; + if (!RuleB(Character, AllowCrossClassTrainers)) { + int trains_class = pTrainer->GetClass() - (WARRIORGM - WARRIOR); + if (GetClass() != trains_class) + return; + } //you have to be somewhat close to a trainer to be properly using them if(DistanceSquared(m_Position, pTrainer->GetPosition()) > USE_NPC_RANGE2) @@ -1928,12 +1933,11 @@ void Client::DoEnduranceUpkeep() { SetEndurUpkeep(false); } -void Client::CalcRestState() { - +void Client::CalcRestState() +{ // This method calculates rest state HP and mana regeneration. // The client must have been out of combat for RuleI(Character, RestRegenTimeToActivate) seconds, // must be sitting down, and must not have any detrimental spells affecting them. - // if(!RuleB(Character, RestRegenEnabled)) return; @@ -1945,6 +1949,9 @@ void Client::CalcRestState() { if(!rest_timer.Check(false)) return; + // so we don't have aggro, our timer has expired, we do not want this to cause issues + m_pp.RestTimer = 0; + uint32 buff_count = GetMaxTotalSlots(); for (unsigned int j = 0; j < buff_count; j++) { if(buffs[j].spellid != SPELL_UNKNOWN) { @@ -1955,7 +1962,6 @@ void Client::CalcRestState() { } ooc_regen = true; - } void Client::DoTracking() diff --git a/zone/command.cpp b/zone/command.cpp index ea1681566..8fe816fe0 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -59,7 +59,6 @@ #include "command.h" #include "guild_mgr.h" #include "map.h" -#include "pathing.h" #include "qglobals.h" #include "queryserv.h" #include "quest_parser_collection.h" @@ -2010,10 +2009,68 @@ void command_setlsinfo(Client *c, const Seperator *sep) void command_grid(Client *c, const Seperator *sep) { - if (strcasecmp("max", sep->arg[1]) == 0) - c->Message(0, "Highest grid ID in this zone: %d", database.GetHighestGrid(zone->GetZoneID())); - else if (strcasecmp("add", sep->arg[1]) == 0) - database.ModifyGrid(c, false,atoi(sep->arg[2]),atoi(sep->arg[3]), atoi(sep->arg[4]),zone->GetZoneID()); + if (strcasecmp("max", sep->arg[1]) == 0) { + c->Message(0, "Highest grid ID in this zone: %d", database.GetHighestGrid(zone->GetZoneID())); + } + else if (strcasecmp("add", sep->arg[1]) == 0) { + database.ModifyGrid(c, false, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), zone->GetZoneID()); + } + else if (strcasecmp("show", sep->arg[1]) == 0) { + + Mob *target = c->GetTarget(); + + if (!target || !target->IsNPC()) { + c->Message(0, "You need a NPC target!"); + return; + } + + std::string query = StringFormat( + "SELECT `x`, `y`, `z`, `heading`, `number`, `pause` " + "FROM `grid_entries` " + "WHERE `zoneid` = %u and `gridid` = %i " + "ORDER BY `number` ", + zone->GetZoneID(), + target->CastToNPC()->GetGrid() + ); + + auto results = database.QueryDatabase(query); + if (!results.Success()) { + c->Message(0, "Error querying database."); + c->Message(0, query.c_str()); + } + + if (results.RowCount() == 0) { + c->Message(0, "No grid found"); + return; + } + + /** + * Depop any node npc's already spawned + */ + auto &mob_list = entity_list.GetMobList(); + for (auto itr = mob_list.begin(); itr != mob_list.end(); ++itr) { + Mob *mob = itr->second; + if (mob->IsNPC() && mob->GetRace() == 2254) + mob->Depop(); + } + + /** + * Spawn grid nodes + */ + for (auto row = results.begin(); row != results.end(); ++row) { + auto node_position = glm::vec4(atof(row[0]), atof(row[1]), atof(row[2]), atof(row[3])); + + NPC *npc = NPC::SpawnGridNodeNPC( + target->GetCleanName(), + node_position, + static_cast(target->CastToNPC()->GetGrid()), + static_cast(atoi(row[4])), + static_cast(atoi(row[5])) + ); + npc->SetFlyMode(1); + npc->GMMove(node_position.x, node_position.y, node_position.z, node_position.w); + } + } else if (strcasecmp("delete", sep->arg[1]) == 0) database.ModifyGrid(c, true,atoi(sep->arg[2]),0,0,zone->GetZoneID()); else { @@ -2535,21 +2592,21 @@ void command_peekinv(Client *c, const Seperator *sep) peekOutOfScope = (peekWorld * 2) // less than }; - static char* scope_prefix[] = { "Equip", "Gen", "Cursor", "Limbo", "Trib", "Bank", "ShBank", "Trade", "World" }; + static const char* scope_prefix[] = { "equip", "gen", "cursor", "limbo", "trib", "bank", "shbank", "trade", "world" }; - static int16 scope_range[][2] = { - { EQEmu::legacy::EQUIPMENT_BEGIN, EQEmu::legacy::EQUIPMENT_END }, - { EQEmu::legacy::GENERAL_BEGIN, EQEmu::legacy::GENERAL_END }, - { EQEmu::legacy::SLOT_CURSOR, EQEmu::legacy::SLOT_CURSOR }, - { EQEmu::legacy::SLOT_INVALID, EQEmu::legacy::SLOT_INVALID }, - { EQEmu::legacy::TRIBUTE_BEGIN, EQEmu::legacy::TRIBUTE_END }, - { EQEmu::legacy::BANK_BEGIN, EQEmu::legacy::BANK_END }, - { EQEmu::legacy::SHARED_BANK_BEGIN, EQEmu::legacy::SHARED_BANK_END }, - { EQEmu::legacy::TRADE_BEGIN, EQEmu::legacy::TRADE_END }, - { EQEmu::inventory::slotBegin, (EQEmu::legacy::WORLD_SIZE - 1) } + static const int16 scope_range[][2] = { + { EQEmu::invslot::EQUIPMENT_BEGIN, EQEmu::invslot::EQUIPMENT_END }, + { EQEmu::invslot::GENERAL_BEGIN, EQEmu::invslot::GENERAL_END }, + { EQEmu::invslot::slotCursor, EQEmu::invslot::slotCursor }, + { EQEmu::invslot::SLOT_INVALID, EQEmu::invslot::SLOT_INVALID }, + { EQEmu::invslot::TRIBUTE_BEGIN, EQEmu::invslot::TRIBUTE_END }, + { EQEmu::invslot::BANK_BEGIN, EQEmu::invslot::BANK_END }, + { EQEmu::invslot::SHARED_BANK_BEGIN, EQEmu::invslot::SHARED_BANK_END }, + { EQEmu::invslot::TRADE_BEGIN, EQEmu::invslot::TRADE_END }, + { EQEmu::invslot::SLOT_BEGIN, (EQEmu::invtype::WORLD_SIZE - 1) } }; - static bool scope_bag[] = { false, true, true, true, false, true, true, true, true }; + static const bool scope_bag[] = { false, true, true, true, false, true, true, true, true }; if (!c) return; @@ -2615,7 +2672,7 @@ void command_peekinv(Client *c, const Seperator *sep) } for (int16 indexMain = scope_range[scopeIndex][0]; indexMain <= scope_range[scopeIndex][1]; ++indexMain) { - if (indexMain == EQEmu::legacy::SLOT_INVALID) + if (indexMain == EQEmu::invslot::SLOT_INVALID) continue; inst_main = ((scopeBit & peekWorld) ? objectTradeskill->GetItem(indexMain) : targetClient->GetInv().GetItem(indexMain)); @@ -2633,14 +2690,14 @@ void command_peekinv(Client *c, const Seperator *sep) (item_data == nullptr), "%sSlot: %i, Item: %i (%s), Charges: %i", scope_prefix[scopeIndex], - ((scopeBit & peekWorld) ? (EQEmu::legacy::WORLD_BEGIN + indexMain) : indexMain), + ((scopeBit & peekWorld) ? (EQEmu::invslot::WORLD_BEGIN + indexMain) : indexMain), ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()) ); if (inst_main && inst_main->IsClassCommon()) { - for (uint8 indexAug = EQEmu::inventory::socketBegin; indexAug < EQEmu::inventory::SocketCount; ++indexAug) { + for (uint8 indexAug = EQEmu::invaug::SOCKET_BEGIN; indexAug <= EQEmu::invaug::SOCKET_END; ++indexAug) { inst_aug = inst_main->GetItem(indexAug); if (!inst_aug) // extant only continue; @@ -2653,7 +2710,7 @@ void command_peekinv(Client *c, const Seperator *sep) ".%sAugSlot: %i (Slot #%i, Aug idx #%i), Item: %i (%s), Charges: %i", scope_prefix[scopeIndex], INVALID_INDEX, - ((scopeBit & peekWorld) ? (EQEmu::legacy::WORLD_BEGIN + indexMain) : indexMain), + ((scopeBit & peekWorld) ? (EQEmu::invslot::WORLD_BEGIN + indexMain) : indexMain), indexAug, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), @@ -2665,7 +2722,7 @@ void command_peekinv(Client *c, const Seperator *sep) if (!scope_bag[scopeIndex] || !(inst_main && inst_main->IsClassBag())) continue; - for (uint8 indexSub = EQEmu::inventory::containerBegin; indexSub < EQEmu::inventory::ContainerCount; ++indexSub) { + for (uint8 indexSub = EQEmu::invbag::SLOT_BEGIN; indexSub <= EQEmu::invbag::SLOT_END; ++indexSub) { inst_sub = inst_main->GetItem(indexSub); if (!inst_sub) // extant only continue; @@ -2678,7 +2735,7 @@ void command_peekinv(Client *c, const Seperator *sep) "..%sBagSlot: %i (Slot #%i, Bag idx #%i), Item: %i (%s), Charges: %i", scope_prefix[scopeIndex], ((scopeBit & peekWorld) ? INVALID_INDEX : EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub)), - ((scopeBit & peekWorld) ? (EQEmu::legacy::WORLD_BEGIN + indexMain) : indexMain), + ((scopeBit & peekWorld) ? (EQEmu::invslot::WORLD_BEGIN + indexMain) : indexMain), indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), @@ -2686,7 +2743,7 @@ void command_peekinv(Client *c, const Seperator *sep) ); if (inst_sub->IsClassCommon()) { - for (uint8 indexAug = EQEmu::inventory::socketBegin; indexAug < EQEmu::inventory::SocketCount; ++indexAug) { + for (uint8 indexAug = EQEmu::invaug::SOCKET_BEGIN; indexAug <= EQEmu::invaug::SOCKET_END; ++indexAug) { inst_aug = inst_sub->GetItem(indexAug); if (!inst_aug) // extant only continue; @@ -2712,7 +2769,7 @@ void command_peekinv(Client *c, const Seperator *sep) } if ((scopeBit & peekEquip) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) { - inst_main = targetClient->GetInv().GetItem(EQEmu::inventory::slotPowerSource); + inst_main = targetClient->GetInv().GetItem(EQEmu::invslot::SLOT_POWER_SOURCE); if (inst_main) { itemsFound = true; item_data = inst_main->GetItem(); @@ -2727,14 +2784,14 @@ void command_peekinv(Client *c, const Seperator *sep) (item_data == nullptr), "%sSlot: %i, Item: %i (%s), Charges: %i", scope_prefix[scopeIndex], - EQEmu::inventory::slotPowerSource, + EQEmu::invslot::SLOT_POWER_SOURCE, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()) ); if (inst_main && inst_main->IsClassCommon()) { - for (uint8 indexAug = EQEmu::inventory::socketBegin; indexAug < EQEmu::inventory::SocketCount; ++indexAug) { + for (uint8 indexAug = EQEmu::invaug::SOCKET_BEGIN; indexAug <= EQEmu::invaug::SOCKET_END; ++indexAug) { inst_aug = inst_main->GetItem(indexAug); if (!inst_aug) // extant only continue; @@ -2747,7 +2804,7 @@ void command_peekinv(Client *c, const Seperator *sep) ".%sAugSlot: %i (Slot #%i, Aug idx #%i), Item: %i (%s), Charges: %i", scope_prefix[scopeIndex], INVALID_INDEX, - EQEmu::inventory::slotPowerSource, + EQEmu::invslot::SLOT_POWER_SOURCE, indexAug, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), @@ -2785,7 +2842,7 @@ void command_peekinv(Client *c, const Seperator *sep) ); if (inst_main && inst_main->IsClassCommon()) { - for (uint8 indexAug = EQEmu::inventory::socketBegin; indexAug < EQEmu::inventory::SocketCount; ++indexAug) { + for (uint8 indexAug = EQEmu::invaug::SOCKET_BEGIN; indexAug <= EQEmu::invaug::SOCKET_END; ++indexAug) { inst_aug = inst_main->GetItem(indexAug); if (!inst_aug) // extant only continue; @@ -2810,7 +2867,7 @@ void command_peekinv(Client *c, const Seperator *sep) if (!scope_bag[scopeIndex] || !(inst_main && inst_main->IsClassBag())) continue; - for (uint8 indexSub = EQEmu::inventory::containerBegin; indexSub < EQEmu::inventory::ContainerCount; ++indexSub) { + for (uint8 indexSub = EQEmu::invbag::SLOT_BEGIN; indexSub <= EQEmu::invbag::SLOT_END; ++indexSub) { inst_sub = inst_main->GetItem(indexSub); if (!inst_sub) continue; @@ -2832,7 +2889,7 @@ void command_peekinv(Client *c, const Seperator *sep) ); if (inst_sub->IsClassCommon()) { - for (uint8 indexAug = EQEmu::inventory::socketBegin; indexAug < EQEmu::inventory::SocketCount; ++indexAug) { + for (uint8 indexAug = EQEmu::invaug::SOCKET_BEGIN; indexAug <= EQEmu::invaug::SOCKET_END; ++indexAug) { inst_aug = inst_sub->GetItem(indexAug); if (!inst_aug) // extant only continue; @@ -3267,8 +3324,8 @@ void command_listpetition(Client *c, const Seperator *sep) void command_equipitem(Client *c, const Seperator *sep) { uint32 slot_id = atoi(sep->arg[1]); - if (sep->IsNumber(1) && ((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::legacy::EQUIPMENT_END) || (slot_id == EQEmu::inventory::slotPowerSource))) { - const EQEmu::ItemInstance* from_inst = c->GetInv().GetItem(EQEmu::inventory::slotCursor); + if (sep->IsNumber(1) && ((slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::invslot::EQUIPMENT_END) || (slot_id == EQEmu::invslot::SLOT_POWER_SOURCE))) { + const EQEmu::ItemInstance* from_inst = c->GetInv().GetItem(EQEmu::invslot::slotCursor); const EQEmu::ItemInstance* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack) bool partialmove = false; int16 movecount; @@ -3276,7 +3333,7 @@ void command_equipitem(Client *c, const Seperator *sep) if (from_inst && from_inst->IsClassCommon()) { auto outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct)); MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer; - mi->from_slot = EQEmu::inventory::slotCursor; + mi->from_slot = EQEmu::invslot::slotCursor; mi->to_slot = slot_id; // mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking @@ -4517,12 +4574,12 @@ void command_goto(Client *c, const Seperator *sep) else if (!(sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3))) c->Message(0, "Usage: #goto [x y z]"); else - c->MovePC(zone->GetZoneID(), zone->GetInstanceID(), atof(sep->arg[1]), atof(sep->arg[2]), atof(sep->arg[3]), 0.0f); + c->MovePC(zone->GetZoneID(), zone->GetInstanceID(), atof(sep->arg[1]), atof(sep->arg[2]), atof(sep->arg[3]), c->GetHeading()); } void command_iteminfo(Client *c, const Seperator *sep) { - auto inst = c->GetInv()[EQEmu::inventory::slotCursor]; + auto inst = c->GetInv()[EQEmu::invslot::slotCursor]; if (!inst) { c->Message(13, "Error: You need an item on your cursor for this command"); return; @@ -5682,9 +5739,9 @@ void command_summonitem(Client *c, const Seperator *sep) std::string cmd_msg = sep->msg; size_t link_open = cmd_msg.find('\x12'); size_t link_close = cmd_msg.find_last_of('\x12'); - if (link_open != link_close && (cmd_msg.length() - link_open) > EQEmu::constants::SayLinkBodySize) { + if (link_open != link_close && (cmd_msg.length() - link_open) > EQEmu::constants::SAY_LINK_BODY_SIZE) { EQEmu::SayLinkBody_Struct link_body; - EQEmu::saylink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EQEmu::constants::SayLinkBodySize)); + EQEmu::saylink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EQEmu::constants::SAY_LINK_BODY_SIZE)); itemid = link_body.item_id; } else if (!sep->IsNumber(1)) { @@ -6991,312 +7048,9 @@ void command_qglobal(Client *c, const Seperator *sep) { void command_path(Client *c, const Seperator *sep) { - if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) - { - c->Message(0, "Syntax: #path shownodes: Spawns a npc to represent every npc node."); - c->Message(0, "#path info node_id: Gives information about node info (requires shownode target)."); - c->Message(0, "#path dump file_name: Dumps the current zone->pathing to a file of your naming."); - c->Message(0, "#path add [requested_id]: Adds a node at your current location will try to take the requested id if possible."); - c->Message(0, "#path connect connect_to_id [is_teleport] [door_id]: Connects the currently targeted node to connect_to_id's node and connects that node back (requires shownode target)."); - c->Message(0, "#path sconnect connect_to_id [is_teleport] [door_id]: Connects the currently targeted node to connect_to_id's node (requires shownode target)."); - c->Message(0, "#path qconnect [set]: short cut connect, connects the targeted node to the node you set with #path qconnect set (requires shownode target)."); - c->Message(0, "#path disconnect [all]/disconnect_from_id: Disconnects the currently targeted node to disconnect from disconnect from id's node (requires shownode target), if passed all as the second argument it will disconnect this node from every other node."); - c->Message(0, "#path move: Moves your targeted node to your current position"); - c->Message(0, "#path process file_name: processes the map file and tries to automatically generate a rudimentary path setup and then dumps the current zone->pathing to a file of your naming."); - c->Message(0, "#path resort [nodes]: resorts the connections/nodes after you've manually altered them so they'll work."); - return; + if (zone->pathing) { + zone->pathing->DebugCommand(c, sep); } - if(!strcasecmp(sep->arg[1], "shownodes")) - { - if(zone->pathing) - zone->pathing->SpawnPathNodes(); - - return; - } - - if(!strcasecmp(sep->arg[1], "info")) - { - if(zone->pathing) - { - zone->pathing->NodeInfo(c); - } - return; - } - - if(!strcasecmp(sep->arg[1], "dump")) - { - if(zone->pathing) - { - if(sep->arg[2][0] == '\0') - return; - - zone->pathing->DumpPath(sep->arg[2]); - } - return; - } - - if(!strcasecmp(sep->arg[1], "add")) - { - if(zone->pathing) - { - float px = c->GetX(); - float py = c->GetY(); - float pz = c->GetZ(); - float best_z; - - if(zone->zonemap) - { - glm::vec3 loc(px, py, pz); - best_z = zone->zonemap->FindBestZ(loc, nullptr); - } - else - { - best_z = pz; - } - int32 res = zone->pathing->AddNode(px, py, pz, best_z, atoi(sep->arg[2])); - if(res >= 0) - { - c->Message(0, "Added Path Node: %i", res); - } - else - { - c->Message(0, "Failed to add Path Node"); - } - } - else - { - zone->pathing = new PathManager(); - float px = c->GetX(); - float py = c->GetY(); - float pz = c->GetZ(); - float best_z; - - if(zone->zonemap) - { - glm::vec3 loc(px, py, pz); - best_z = zone->zonemap->FindBestZ(loc, nullptr); - } - else - { - best_z = pz; - } - int32 res = zone->pathing->AddNode(px, py, pz, best_z, atoi(sep->arg[2])); - if(res >= 0) - { - c->Message(0, "Added Path Node: %i", res); - } - else - { - c->Message(0, "Failed to add Path Node"); - } - } - return; - } - - if(!strcasecmp(sep->arg[1], "remove")) - { - if(zone->pathing) - { - if(zone->pathing->DeleteNode(c)) - { - c->Message(0, "Removed Node."); - } - else - { - c->Message(0, "Unable to Remove Node."); - } - } - return; - } - - if(!strcasecmp(sep->arg[1], "connect")) - { - if(zone->pathing) - { - zone->pathing->ConnectNodeToNode(c, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); - } - return; - } - - if(!strcasecmp(sep->arg[1], "sconnect")) - { - if(zone->pathing) - { - zone->pathing->ConnectNode(c, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); - } - return; - } - - if(!strcasecmp(sep->arg[1], "qconnect")) - { - if(zone->pathing) - { - if(!strcasecmp(sep->arg[2], "set")) - { - zone->pathing->QuickConnect(c, true); - } - else - { - zone->pathing->QuickConnect(c, false); - } - } - return; - } - - if(!strcasecmp(sep->arg[1], "disconnect")) - { - if(zone->pathing) - { - if(!strcasecmp(sep->arg[2], "all")) - { - zone->pathing->DisconnectAll(c); - } - else - { - zone->pathing->DisconnectNodeToNode(c, atoi(sep->arg[2])); - } - } - return; - } - - - if(!strcasecmp(sep->arg[1], "move")) - { - if(zone->pathing) - { - zone->pathing->MoveNode(c); - } - return; - } - - if(!strcasecmp(sep->arg[1], "process")) - { - if(zone->pathing) - { - if(sep->arg[2][0] == '\0') - return; - - zone->pathing->ProcessNodesAndSave(sep->arg[2]); - c->Message(0, "Path processed..."); - } - return; - } - - if(!strcasecmp(sep->arg[1], "resort")) - { - if(zone->pathing) - { - if(!strcasecmp(sep->arg[2], "nodes")) - { - zone->pathing->SortNodes(); - c->Message(0, "Nodes resorted..."); - } - else - { - zone->pathing->ResortConnections(); - c->Message(0, "Connections resorted..."); - } - } - return; - } - - if(!strcasecmp(sep->arg[1], "hazard")) - { - if(zone->pathing) - { - if(c && c->GetTarget()) - { - if (zone->pathing->NoHazardsAccurate(glm::vec3(c->GetX(), c->GetY(), c->GetZ()), - glm::vec3(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()))) - { - c->Message(0, "No hazards."); - } - else - { - c->Message(0, "Hazard Detected..."); - } - } - } - return; - } - - if(!strcasecmp(sep->arg[1], "print")) - { - if(zone->pathing) - { - zone->pathing->PrintPathing(); - } - return; - } - - if(!strcasecmp(sep->arg[1], "showneighbours") || !strcasecmp(sep->arg[1], "showneighbors")) - { - if(!c->GetTarget()) - { - c->Message(0, "First #path shownodes to spawn the pathnodes, and then target one of them."); - return; - } - if(zone->pathing) - { - zone->pathing->ShowPathNodeNeighbours(c); - return; - } - } - if(!strcasecmp(sep->arg[1], "meshtest")) - { - if(zone->pathing) - { - if(!strcasecmp(sep->arg[2], "simple")) - { - c->Message(0, "You may go linkdead. Results will be in the log file."); - zone->pathing->SimpleMeshTest(); - return; - } - else - { - c->Message(0, "You may go linkdead. Results will be in the log file."); - zone->pathing->MeshTest(); - return; - } - } - } - - if(!strcasecmp(sep->arg[1], "allspawns")) - { - if(zone->pathing) - { - c->Message(0, "You may go linkdead. Results will be in the log file."); - entity_list.FindPathsToAllNPCs(); - return; - } - } - - if(!strcasecmp(sep->arg[1], "nearest")) - { - if(!c->GetTarget() || !c->GetTarget()->IsMob()) - { - c->Message(0, "You must target something."); - return; - } - - if(zone->pathing) - { - Mob *m = c->GetTarget(); - - glm::vec3 Position(m->GetX(), m->GetY(), m->GetZ()); - - int Node = zone->pathing->FindNearestPathNode(Position); - - if(Node == -1) - c->Message(0, "Unable to locate a path node within range."); - else - c->Message(0, "Nearest path node is %i", Node); - - return; - } - } - - c->Message(0, "Unknown path command."); } void Client::Undye() { diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 63031ec45..586789f0f 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -322,12 +322,12 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( // to go into the regular slots on the player, out of bags std::list removed_list; - for (i = EQEmu::inventory::slotBegin; i < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; ++i) { - if (i == EQEmu::inventory::slotAmmo && client->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { - item = client->GetInv().GetItem(EQEmu::inventory::slotPowerSource); + for (i = EQEmu::invslot::POSSESSIONS_BEGIN; i <= EQEmu::invslot::POSSESSIONS_END; ++i) { + if (i == EQEmu::invslot::slotAmmo && client->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { + item = client->GetInv().GetItem(EQEmu::invslot::SLOT_POWER_SOURCE); if (item != nullptr) { if (!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent)) - MoveItemToCorpse(client, item, EQEmu::inventory::slotPowerSource, removed_list); + MoveItemToCorpse(client, item, EQEmu::invslot::SLOT_POWER_SOURCE, removed_list); } } @@ -404,9 +404,9 @@ void Corpse::MoveItemToCorpse(Client *client, EQEmu::ItemInstance *inst, int16 e while (true) { if (!inst->IsClassBag()) { break; } - if (equipSlot < EQEmu::legacy::GENERAL_BEGIN || equipSlot > EQEmu::inventory::slotCursor) { break; } + if (equipSlot < EQEmu::invslot::GENERAL_BEGIN || equipSlot > EQEmu::invslot::slotCursor) { break; } - for (int16 sub_index = EQEmu::inventory::containerBegin; sub_index < EQEmu::inventory::ContainerCount; ++sub_index) { + for (int16 sub_index = EQEmu::invbag::SLOT_BEGIN; sub_index <= EQEmu::invbag::SLOT_END; ++sub_index) { int16 real_bag_slot = EQEmu::InventoryProfile::CalcSlotId(equipSlot, sub_index); auto bag_inst = client->GetInv().GetItem(real_bag_slot); if (bag_inst == nullptr) { continue; } @@ -684,7 +684,7 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** } if (sitem && bag_item_data && EQEmu::InventoryProfile::SupportsContainers(sitem->equip_slot)) { - int16 bagstart = EQEmu::InventoryProfile::CalcSlotId(sitem->equip_slot, EQEmu::inventory::containerBegin); + int16 bagstart = EQEmu::InventoryProfile::CalcSlotId(sitem->equip_slot, EQEmu::invbag::SLOT_BEGIN); cur = itemlist.begin(); end = itemlist.end(); @@ -983,7 +983,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(inst) { if (item->RecastDelay) inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0); - client->SendItemPacket(EQEmu::legacy::CORPSE_BEGIN, inst, ItemPacketLoot); + client->SendItemPacket(EQEmu::invslot::CORPSE_BEGIN, inst, ItemPacketLoot); safe_delete(inst); } else { client->Message(13, "Could not find item number %i to send!!", GetPlayerKillItem()); } @@ -998,7 +998,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a cur = itemlist.begin(); end = itemlist.end(); - int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(client->ClientVersion()))->InventoryTypeSize[EQEmu::inventory::typeCorpse]; + int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(client->ClientVersion()))->InventoryTypeSize[EQEmu::invtype::typeCorpse]; for(; cur != end; ++cur) { ServerLootItem_Struct* item_data = *cur; @@ -1007,7 +1007,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a // Dont display the item if it's in a bag // Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse. - if (!IsPlayerCorpse() || item_data->equip_slot <= EQEmu::inventory::slotCursor || item_data->equip_slot == EQEmu::inventory::slotPowerSource || Loot_Request_Type >= 3 || + if (!IsPlayerCorpse() || item_data->equip_slot <= EQEmu::invslot::slotCursor || item_data->equip_slot == EQEmu::invslot::SLOT_POWER_SOURCE || Loot_Request_Type >= 3 || (item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) { if(i < corpselootlimit) { item = database.GetItem(item_data->item_id); @@ -1017,7 +1017,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if (item->RecastDelay) inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0); // SlotGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = SlotGeneral1 + SlotCursor - client->SendItemPacket(i + EQEmu::legacy::CORPSE_BEGIN, inst, ItemPacketLoot); + client->SendItemPacket(i + EQEmu::invslot::CORPSE_BEGIN, inst, ItemPacketLoot); safe_delete(inst); } @@ -1126,9 +1126,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) } else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1) { item_data = GetItem(lootitem->slot_id - - EQEmu::legacy::CORPSE_BEGIN); // dont allow them to loot entire bags of items as pvp reward + EQEmu::invslot::CORPSE_BEGIN); // dont allow them to loot entire bags of items as pvp reward } else { - item_data = GetItem(lootitem->slot_id - EQEmu::legacy::CORPSE_BEGIN, bag_item_data); + item_data = GetItem(lootitem->slot_id - EQEmu::invslot::CORPSE_BEGIN, bag_item_data); } if (GetPlayerKillItem() <= 1 && item_data != 0) { @@ -1156,7 +1156,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) } if (inst->IsAugmented()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { EQEmu::ItemInstance *itm = inst->GetAugment(i); if (itm) { if (client->CheckLoreConflict(itm->GetItem())) { @@ -1210,9 +1210,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) /* First add it to the looter - this will do the bag contents too */ if (lootitem->auto_loot > 0) { if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data)) - client->PutLootInInventory(EQEmu::inventory::slotCursor, *inst, bag_item_data); + client->PutLootInInventory(EQEmu::invslot::slotCursor, *inst, bag_item_data); } else { - client->PutLootInInventory(EQEmu::inventory::slotCursor, *inst, bag_item_data); + client->PutLootInInventory(EQEmu::invslot::slotCursor, *inst, bag_item_data); } /* Update any tasks that have an activity to loot this item */ @@ -1231,7 +1231,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) /* Remove Bag Contents */ if (item->IsClassBag() && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) { - for (int i = EQEmu::inventory::containerBegin; i < EQEmu::inventory::ContainerCount; i++) { + for (int i = EQEmu::invbag::SLOT_BEGIN; i <= EQEmu::invbag::SLOT_END; i++) { if (bag_item_data[i]) { /* Delete needs to be before RemoveItem because its deletes the pointer for * item_data/bag_item_data */ @@ -1317,13 +1317,13 @@ void Corpse::QueryLoot(Client* to) { cur = itemlist.begin(); end = itemlist.end(); - int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(to->ClientVersion()))->InventoryTypeSize[EQEmu::inventory::typeCorpse]; + int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(to->ClientVersion()))->InventoryTypeSize[EQEmu::invtype::typeCorpse]; for(; cur != end; ++cur) { ServerLootItem_Struct* sitem = *cur; if (IsPlayerCorpse()) { - if (sitem->equip_slot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && sitem->equip_slot <= EQEmu::legacy::CURSOR_BAG_END) + if (sitem->equip_slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && sitem->equip_slot <= EQEmu::invbag::CURSOR_BAG_END) sitem->lootslot = 0xFFFF; else x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF; @@ -1457,8 +1457,8 @@ void Corpse::UpdateEquipmentLight() m_Light.Level[EQEmu::lightsource::LightEquipment] = 0; for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) { - if (((*iter)->equip_slot < EQEmu::legacy::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::legacy::EQUIPMENT_END) && (*iter)->equip_slot != EQEmu::inventory::slotPowerSource) { continue; } - if ((*iter)->equip_slot == EQEmu::inventory::slotAmmo) { continue; } + if (((*iter)->equip_slot < EQEmu::invslot::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::invslot::EQUIPMENT_END) && (*iter)->equip_slot != EQEmu::invslot::SLOT_POWER_SOURCE) { continue; } + if ((*iter)->equip_slot == EQEmu::invslot::slotAmmo) { continue; } auto item = database.GetItem((*iter)->item_id); if (item == nullptr) { continue; } @@ -1469,7 +1469,7 @@ void Corpse::UpdateEquipmentLight() uint8 general_light_type = 0; for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) { - if ((*iter)->equip_slot < EQEmu::legacy::GENERAL_BEGIN || (*iter)->equip_slot > EQEmu::legacy::GENERAL_END) { continue; } + if ((*iter)->equip_slot < EQEmu::invslot::GENERAL_BEGIN || (*iter)->equip_slot > EQEmu::invslot::GENERAL_END) { continue; } auto item = database.GetItem((*iter)->item_id); if (item == nullptr) { continue; } diff --git a/zone/corpse.h b/zone/corpse.h index e601f2aa3..84bce15fa 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -53,7 +53,7 @@ class Corpse : public Mob { /* Corpse: General */ virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; } virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; } - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } virtual bool HasRaid() { return false; } virtual bool HasGroup() { return false; } virtual Raid* GetRaid() { return 0; } diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp new file mode 100644 index 000000000..d1bdcd83c --- /dev/null +++ b/zone/data_bucket.cpp @@ -0,0 +1,150 @@ +#include "data_bucket.h" +#include +#include "../common/string_util.h" +#include "zonedb.h" +#include +#include +#include + +/** + * Persists data via bucket_name as key + * @param bucket_key + * @param bucket_value + * @param expires_time + */ +void DataBucket::SetData(std::string bucket_key, std::string bucket_value, std::string expires_time) { + uint64 bucket_id = DataBucket::DoesBucketExist(bucket_key); + + std::string query; + long long expires_time_unix = 0; + + if (!expires_time.empty()) { + if (isalpha(expires_time[0]) || isalpha(expires_time[expires_time.length() - 1])) { + expires_time_unix = (long long) std::time(nullptr) + DataBucket::ParseStringTimeToInt(expires_time); + } else { + expires_time_unix = (long long) std::time(nullptr) + atoi(expires_time.c_str()); + } + } + + if (bucket_id > 0) { + std::string update_expired_time; + if (expires_time_unix > 0) { + update_expired_time = StringFormat(", `expires` = %lld ", expires_time_unix); + } + + query = StringFormat( + "UPDATE `data_buckets` SET `value` = '%s' %s WHERE `id` = %i", + EscapeString(bucket_value).c_str(), + EscapeString(update_expired_time).c_str(), + bucket_id + ); + } + else { + query = StringFormat( + "INSERT INTO `data_buckets` (`key`, `value`, `expires`) VALUES ('%s', '%s', '%lld')", + EscapeString(bucket_key).c_str(), + EscapeString(bucket_value).c_str(), + expires_time_unix + ); + } + + database.QueryDatabase(query); +} + +/** + * Retrieves data via bucket_name as key + * @param bucket_key + * @return + */ +std::string DataBucket::GetData(std::string bucket_key) { + std::string query = StringFormat( + "SELECT `value` from `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0) LIMIT 1", + bucket_key.c_str(), + (long long) std::time(nullptr) + ); + + auto results = database.QueryDatabase(query); + if (!results.Success()) { + return std::string(); + } + + if (results.RowCount() != 1) + return std::string(); + + auto row = results.begin(); + + return std::string(row[0]); +} + +/** + * Checks for bucket existence by bucket_name key + * @param bucket_key + * @return + */ +uint64 DataBucket::DoesBucketExist(std::string bucket_key) { + std::string query = StringFormat( + "SELECT `id` from `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0) LIMIT 1", + EscapeString(bucket_key).c_str(), + (long long) std::time(nullptr) + ); + + auto results = database.QueryDatabase(query); + if (!results.Success()) { + return 0; + } + + auto row = results.begin(); + if (results.RowCount() != 1) + return 0; + + return std::stoull(row[0]); +} + +/** + * Deletes data bucket by key + * @param bucket_key + * @return + */ +bool DataBucket::DeleteData(std::string bucket_key) { + std::string query = StringFormat( + "DELETE FROM `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0)", + EscapeString(bucket_key).c_str() + ); + + auto results = database.QueryDatabase(query); + + return results.Success(); +} + +/** + * Converts string to integer for use when setting expiration times + * @param time_string + * @return + */ +uint32 DataBucket::ParseStringTimeToInt(std::string time_string) +{ + uint32 duration = 0; + + std::transform(time_string.begin(), time_string.end(), time_string.begin(), ::tolower); + + if (time_string.length() < 1) + return 0; + + std::string time_unit = time_string; + time_unit.erase(remove_if(time_unit.begin(), time_unit.end(), [](char c) { return !isdigit(c); }), time_unit.end()); + + uint32 unit = static_cast(atoi(time_unit.c_str())); + + if (time_string.find('s') != std::string::npos) + duration = unit; + if (time_string.find('m') != std::string::npos) + duration = unit * 60; + if (time_string.find('h') != std::string::npos) + duration = unit * 3600; + if (time_string.find('d') != std::string::npos) + duration = unit * 86400; + if (time_string.find('y') != std::string::npos) + duration = unit * 31556926; + + return duration; +} \ No newline at end of file diff --git a/zone/data_bucket.h b/zone/data_bucket.h new file mode 100644 index 000000000..87d3ab0b3 --- /dev/null +++ b/zone/data_bucket.h @@ -0,0 +1,23 @@ +// +// Created by Akkadius on 7/7/18. +// + +#ifndef EQEMU_DATABUCKET_H +#define EQEMU_DATABUCKET_H + + +#include +#include "../common/types.h" + +class DataBucket { +public: + static void SetData(std::string bucket_key, std::string bucket_value, std::string expires_time = ""); + static bool DeleteData(std::string bucket_key); + static std::string GetData(std::string bucket_key); +private: + static uint64 DoesBucketExist(std::string bucket_key); + static uint32 ParseStringTimeToInt(std::string time_string); +}; + + +#endif //EQEMU_DATABUCKET_H diff --git a/zone/doors.cpp b/zone/doors.cpp index 97aaa1088..9561757df 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -40,72 +40,71 @@ extern EntityList entity_list; extern WorldServer worldserver; -Doors::Doors(const Door* door) : -close_timer(5000), -m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading), -m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) -{ - db_id = door->db_id; - door_id = door->door_id; +Doors::Doors(const Door *door) : + close_timer(5000), + m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading), + m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) { + strn0cpy(zone_name, door->zone_name, 32); strn0cpy(door_name, door->door_name, 32); - incline = door->incline; - opentype = door->opentype; - guild_id = door->guild_id; - lockpick = door->lock_pick; - keyitem = door->keyitem; - nokeyring = door->nokeyring; - trigger_door = door->trigger_door; - trigger_type = door->trigger_type; - triggered = false; - door_param = door->door_param; - size = door->size; - invert_state = door->invert_state; + strn0cpy(destination_zone_name, door->dest_zone, 16); + + this->database_id = door->db_id; + this->door_id = door->door_id; + this->incline = door->incline; + this->open_type = door->opentype; + this->guild_id = door->guild_id; + this->lockpick = door->lock_pick; + this->key_item_id = door->keyitem; + this->no_key_ring = door->nokeyring; + this->trigger_door = door->trigger_door; + this->trigger_type = door->trigger_type; + this->triggered = false; + this->door_param = door->door_param; + this->size = door->size; + this->invert_state = door->invert_state; + this->destination_instance_id = door->dest_instance_id; + this->is_ldon_door = door->is_ldon_door; + this->client_version_mask = door->client_version_mask; + SetOpenState(false); close_timer.Disable(); - strn0cpy(dest_zone, door->dest_zone, 16); - dest_instance_id = door->dest_instance_id; - - is_ldon_door = door->is_ldon_door; - client_version_mask = door->client_version_mask; - disable_timer = (door->disable_timer == 1 ? true : false); } -Doors::Doors(const char *dmodel, const glm::vec4& position, uint8 dopentype, uint16 dsize) : -close_timer(5000), -m_Position(position), -m_Destination(glm::vec4()) -{ - db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); - door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); +Doors::Doors(const char *model, const glm::vec4 &position, uint8 open_type, uint16 size) : + close_timer(5000), + m_Position(position), + m_Destination(glm::vec4()){ + strn0cpy(zone_name, zone->GetShortName(), 32); - strn0cpy(door_name, dmodel, 32); - incline = 0; - opentype = dopentype; - guild_id = 0; - lockpick = 0; - keyitem = 0; - nokeyring = 0; - trigger_door = 0; - trigger_type = 0; - triggered = false; - door_param = 0; - size = dsize; - invert_state = 0; + strn0cpy(door_name, model, 32); + strn0cpy(destination_zone_name, "NONE", 32); + + this->database_id = (uint32) database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); + this->door_id = (uint8) database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); + + this->open_type = open_type; + this->size = size; + this->incline = 0; + this->guild_id = 0; + this->lockpick = 0; + this->key_item_id = 0; + this->no_key_ring = 0; + this->trigger_door = 0; + this->trigger_type = 0; + this->triggered = false; + this->door_param = 0; + this->invert_state = 0; + this->is_ldon_door = 0; + this->client_version_mask = 4294967295u; + this->disable_timer = 0; + this->destination_instance_id = 0; + SetOpenState(false); - close_timer.Disable(); - - strn0cpy(dest_zone, "NONE", 32); - dest_instance_id = 0; - - is_ldon_door = 0; - client_version_mask = 4294967295u; - - disable_timer = 0; } @@ -115,71 +114,89 @@ Doors::~Doors() bool Doors::Process() { - if(close_timer.Enabled() && close_timer.Check() && IsDoorOpen()) - { - if (opentype == 40 || GetTriggerType() == 1) - { + if (close_timer.Enabled() && close_timer.Check() && IsDoorOpen()) { + if (open_type == 40 || GetTriggerType() == 1) { auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; + MoveDoor_Struct *md = (MoveDoor_Struct *) outapp->pBuffer; md->doorid = door_id; md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; entity_list.QueueClients(0, outapp); safe_delete(outapp); } - triggered=false; + triggered = false; close_timer.Disable(); SetOpenState(false); } return true; } -void Doors::HandleClick(Client* sender, uint8 trigger) -{ - //door debugging info dump - Log(Logs::Detail, Logs::Doors, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str()); - Log(Logs::Detail, Logs::Doors, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param); - Log(Logs::Detail, Logs::Doors, " disable_timer '%s',size %d, invert %d, dest: %s %s", (disable_timer?"true":"false"), size, invert_state, dest_zone, to_string(m_Destination).c_str()); +void Doors::HandleClick(Client* sender, uint8 trigger) { + Log(Logs::Detail, Logs::Doors, + "%s clicked door %s (dbid %d, eqid %d) at %s", + sender->GetName(), + this->door_name, + this->database_id, + this->door_id, + to_string(m_Position).c_str() + ); + + Log(Logs::Detail, Logs::Doors, + "incline %d, open_type %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", + this->incline, + this->open_type, + this->lockpick, + this->key_item_id, + this->no_key_ring, + this->trigger_door, + this->trigger_type, + this->door_param + ); + + Log(Logs::Detail, Logs::Doors, + "disable_timer '%s',size %d, invert %d, dest: %s %s", + (this->disable_timer ? "true" : "false"), + this->size, + this->invert_state, + this->destination_zone_name, + to_string(m_Destination).c_str() + ); auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; - md->doorid = door_id; - ///////////////////////////////////////////////////////////////// - //used_pawn: Locked doors! Rogue friendly too =) - //TODO: add check for other lockpick items - ////////////////////////////////////////////////////////////////// + auto *move_door_packet = (MoveDoor_Struct *) outapp->pBuffer; + move_door_packet->doorid = door_id; - //TODO: ADVENTURE DOOR - if(IsLDoNDoor()) - { - if(sender) - { - if(RuleI(Adventure, ItemIDToEnablePorts) != 0) - { - if(!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts))) - { - if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX) - { + if (this->IsLDoNDoor()) { + if (sender) { + if (RuleI(Adventure, ItemIDToEnablePorts) != 0) { + if (!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts))) { + if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX) { sender->Message_StringID(13, DUNGEON_SEALED); safe_delete(outapp); return; - } - else - { + } else { sender->KeyRingAdd(RuleI(Adventure, ItemIDToEnablePorts)); } } } - if(!sender->GetPendingAdventureDoorClick()) - { + if (!sender->GetPendingAdventureDoorClick()) { sender->PendingAdventureDoorClick(); - auto pack = new ServerPacket(ServerOP_AdventureClickDoor, - sizeof(ServerPlayerClickedAdventureDoor_Struct)); - ServerPlayerClickedAdventureDoor_Struct *ads = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer; - strcpy(ads->player, sender->GetName()); - ads->zone_id = zone->GetZoneID(); - ads->id = GetDoorDBID(); + auto pack = new ServerPacket( + ServerOP_AdventureClickDoor, + sizeof(ServerPlayerClickedAdventureDoor_Struct) + ); + + /** + * Adventure door + */ + ServerPlayerClickedAdventureDoor_Struct *adventure_door_click; + adventure_door_click = (ServerPlayerClickedAdventureDoor_Struct *) pack->pBuffer; + strcpy(adventure_door_click->player, sender->GetName()); + + adventure_door_click->zone_id = zone->GetZoneID(); + adventure_door_click->id = this->GetDoorDBID(); + worldserver.SendPacket(pack); safe_delete(pack); } @@ -188,166 +205,169 @@ void Doors::HandleClick(Client* sender, uint8 trigger) } } - uint32 keyneeded = GetKeyItem(); - uint8 keepoffkeyring = GetNoKeyring(); - uint32 haskey = 0; - uint32 playerkey = 0; - const EQEmu::ItemInstance *lockpicks = sender->GetInv().GetItem(EQEmu::inventory::slotCursor); + uint32 required_key_item = GetKeyItem(); + uint8 disable_add_to_key_ring = GetNoKeyring(); + uint32 player_has_key = 0; + uint32 player_key = 0; - haskey = sender->GetInv().HasItem(keyneeded, 1); + const EQEmu::ItemInstance *lock_pick_item = sender->GetInv().GetItem(EQEmu::invslot::slotCursor); + player_has_key = static_cast(sender->GetInv().HasItem(required_key_item, 1)); - if (haskey != INVALID_INDEX) - { - playerkey = keyneeded; + if (player_has_key != INVALID_INDEX) { + player_key = required_key_item; } - if(GetTriggerType() == 255) - { // this object isnt triggered - if(trigger == 1) - { // this door is only triggered by an object - if(!IsDoorOpen() || (opentype == 58)) - { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; + /** + * Object is not triggered + */ + if (this->GetTriggerType() == 255) { + + /** + * Door is only triggered by an object + */ + if (trigger == 1) { + if (!this->IsDoorOpen() || (open_type == 58)) { + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); + } else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; - } - } - else - { + } else { safe_delete(outapp); return; } } - // guild doors - if(((keyneeded == 0) && (GetLockpick() == 0) && (guild_id == 0)) || - (IsDoorOpen() && (opentype == 58)) || - ((guild_id > 0) && (guild_id == sender->GuildID()))) - { //door not locked - if(!IsDoorOpen() || (opentype == 58)) - { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; + /** + * Guild Doors + * + * Door is not locked + */ + bool is_guild_door = (this->GetGuildID() > 0) && (this->GetGuildID() == sender->GuildID()); + bool is_door_not_locked = ((required_key_item == 0) && (this->GetLockpick() == 0) && (this->GetGuildID() == 0)); + bool is_door_open_and_open_able = (this->IsDoorOpen() && (open_type == 58)); + + if (is_door_not_locked || is_door_open_and_open_able || is_guild_door) { + if (!this->IsDoorOpen() || (this->GetOpenType() == 58)) { + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); + } else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; - } - } - else - { // guild doors - if((guild_id > 0) && !sender->GetGM()) - { - std::string tmp; - char tmpmsg[240]; // guild doors msgs - if(guild_mgr.GetGuildNameByID(guild_id, tmp)) - { - sprintf(tmpmsg, "Only members of the <%s> guild may enter here", tmp.c_str()); + } else { + + /** + * Guild Doors + */ + if ((this->GetGuildID() > 0) && !sender->GetGM()) { + std::string guild_name; + char door_message[240]; + + if (guild_mgr.GetGuildNameByID(guild_id, guild_name)) { + sprintf(door_message, "Only members of the <%s> guild may enter here", guild_name.c_str()); + } else { + strcpy(door_message, "Door is locked by an unknown guild"); } - else - { - strcpy(tmpmsg, "Door is locked by an unknown guild"); - } - sender->Message(4, tmpmsg); + + sender->Message(4, door_message); safe_delete(outapp); return; } - // a key is required or the door is locked but can be picked or both - sender->Message(4, "This is locked..."); // debug spam - should probably go - if(sender->GetGM()) // GM can always open locks - should probably be changed to require a key - { - sender->Message_StringID(4,DOORS_GM); - if(!IsDoorOpen() || (opentype == 58)) - { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; - } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; + + /** + * Key required + */ + sender->Message(4, "This is locked..."); + + /** + * GM can always open locks + */ + if (sender->GetGM()) { + sender->Message_StringID(4, DOORS_GM); + + if (!IsDoorOpen() || (open_type == 58)) { + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); + } else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } + } - else if(playerkey) - { // they have something they are trying to open it with - if(keyneeded && (keyneeded == playerkey)) - { // key required and client is using the right key - if(!keepoffkeyring) - { - sender->KeyRingAdd(playerkey); + + /** + * Player has something they are trying to open it with + */ + else if (player_key) { + + /** + * Key required and client is using the right key + */ + if (required_key_item && + (required_key_item == player_key)) { + + if (!disable_add_to_key_ring) { + sender->KeyRingAdd(player_key); } + sender->Message(4, "You got it open!"); - if(!IsDoorOpen() || (opentype == 58)) - { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; - } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; + + if (!IsDoorOpen() || (open_type == 58)) { + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); + } else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } } - else if(lockpicks != nullptr) - { - if (sender->GetSkill(EQEmu::skills::SkillPickLock)) - { - if(lockpicks->GetItem()->ItemType == EQEmu::item::ItemTypeLockPick) - { - float modskill = sender->GetSkill(EQEmu::skills::SkillPickLock); + + /** + * Try Lock pick + */ + else if (lock_pick_item != nullptr) { + if (sender->GetSkill(EQEmu::skills::SkillPickLock)) { + if (lock_pick_item->GetItem()->ItemType == EQEmu::item::ItemTypeLockPick) { + float player_pick_lock_skill = sender->GetSkill(EQEmu::skills::SkillPickLock); sender->CheckIncreaseSkill(EQEmu::skills::SkillPickLock, nullptr, 1); - Log(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill); + Log(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", player_pick_lock_skill); - if(GetLockpick() <= modskill) - { - if(!IsDoorOpen()) - { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; - } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; + if (GetLockpick() <= player_pick_lock_skill) { + if (!IsDoorOpen()) { + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); + } else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } sender->Message_StringID(4, DOORS_SUCCESSFUL_PICK); - } - else - { + } else { sender->Message_StringID(4, DOORS_INSUFFICIENT_SKILL); safe_delete(outapp); return; } - } - else - { + } else { sender->Message_StringID(4, DOORS_NO_PICK); safe_delete(outapp); return; } - } - else - { + } else { sender->Message_StringID(4, DOORS_CANT_PICK); safe_delete(outapp); return; } } - else - { // locked door and nothing to open it with - // search for key on keyring - if(sender->KeyRingCheck(keyneeded)) - { - playerkey = keyneeded; + + /** + * Locked door and nothing to open it with + */ + else { + + /** + * Search for key on keyring + */ + if (sender->KeyRingCheck(required_key_item)) { + player_key = required_key_item; sender->Message(4, "You got it open!"); // more debug spam - if(!IsDoorOpen() || (opentype == 58)) - { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; + if (!IsDoorOpen() || (open_type == 58)) { + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); + } else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; - } - } - else - { + } else { sender->Message_StringID(4, DOORS_LOCKED); safe_delete(outapp); return; @@ -356,92 +376,121 @@ void Doors::HandleClick(Client* sender, uint8 trigger) } entity_list.QueueClients(sender, outapp, false); - if(!IsDoorOpen() || (opentype == 58)) - { + if (!IsDoorOpen() || (open_type == 58)) { if (!disable_timer) close_timer.Start(); SetOpenState(true); - } - else - { + } else { close_timer.Disable(); if (!disable_timer) SetOpenState(false); } - //everything past this point assumes we opened the door - //and met all the reqs for opening - //everything to do with closed doors has already been taken care of - //we return because we don't want people using teleports on an unlocked door (exploit!) - if((md->action == CLOSE_DOOR && invert_state == 0) || (md->action == CLOSE_INVDOOR && invert_state == 1)) - { + /* + * Everything past this point assumes we opened the door + * and met all the requirements for opening + * everything to do with closed doors has already been taken care of + * we return because we don't want people using teleports on an unlocked door (exploit!) + */ + + if ((move_door_packet->action == CLOSE_DOOR && invert_state == 0) || (move_door_packet->action == CLOSE_INVDOOR && invert_state == 1)) { safe_delete(outapp); return; } safe_delete(outapp); - if((GetTriggerDoorID() != 0) && (GetTriggerType() == 1)) - { - Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID()); - if(triggerdoor && !triggerdoor->triggered) - { - triggered=true; - triggerdoor->HandleClick(sender, 1); + if ((GetTriggerDoorID() != 0) && (GetTriggerType() == 1)) { + Doors *trigger_door_entity = entity_list.FindDoor(GetTriggerDoorID()); + if (trigger_door_entity && !trigger_door_entity->triggered) { + triggered = true; + trigger_door_entity->HandleClick(sender, 1); + } else { + triggered = false; } - else - { - triggered=false; - } - } - else if((GetTriggerDoorID() != 0) && (GetTriggerType() != 1)) - { - Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID()); - if(triggerdoor && !triggerdoor->triggered) - { - triggered=true; - triggerdoor->HandleClick(sender, 0); - } - else - { - triggered=false; + } else if ((GetTriggerDoorID() != 0) && (GetTriggerType() != 1)) { + Doors *trigger_door_entity = entity_list.FindDoor(GetTriggerDoorID()); + if (trigger_door_entity && !trigger_door_entity->triggered) { + triggered = true; + trigger_door_entity->HandleClick(sender, 0); + } else { + triggered = false; } } - if(((opentype == 57) || (opentype == 58)) && (strncmp(dest_zone, "NONE", strlen("NONE")) != 0)) - { // Teleport door! - if (( strncmp(dest_zone,zone_name,strlen(zone_name)) == 0) && (!keyneeded)) - { - if(!keepoffkeyring) - { - sender->KeyRingAdd(playerkey); + /** + * Teleport door + */ + if (((open_type == 57) || (open_type == 58)) && + (strncmp(destination_zone_name, "NONE", strlen("NONE")) != 0)) { + + /** + * If click destination is same zone and doesn't require a key + */ + if ((strncmp(destination_zone_name, zone_name, strlen(zone_name)) == 0) && (!required_key_item)) { + if (!disable_add_to_key_ring) { + sender->KeyRingAdd(player_key); } - sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); + sender->MovePC( + zone->GetZoneID(), + zone->GetInstanceID(), + m_Destination.x, + m_Destination.y, + m_Destination.z, + m_Destination.w + ); } - else if (( !IsDoorOpen() || opentype == 58 ) && (keyneeded && ((keyneeded == playerkey) || sender->GetGM()))) - { - if(!keepoffkeyring) - { - sender->KeyRingAdd(playerkey); + /** + * If requires a key + */ + else if ( + (!IsDoorOpen() || open_type == 58) && + (required_key_item && ((required_key_item == player_key) || sender->GetGM())) + ) { + + if (!disable_add_to_key_ring) { + sender->KeyRingAdd(player_key); } - if(database.GetZoneID(dest_zone) == zone->GetZoneID()) - { - sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); - } - else - { - sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); + if (database.GetZoneID(destination_zone_name) == zone->GetZoneID()) { + sender->MovePC( + zone->GetZoneID(), + zone->GetInstanceID(), + m_Destination.x, + m_Destination.y, + m_Destination.z, + m_Destination.w + ); + } else { + sender->MovePC( + database.GetZoneID(destination_zone_name), + static_cast(destination_instance_id), + m_Destination.x, + m_Destination.y, + m_Destination.z, + m_Destination.w + ); } } - if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded)) - { - if(database.GetZoneID(dest_zone) == zone->GetZoneID()) - { - sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); - } - else - { - sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); + + if ((!IsDoorOpen() || open_type == 58) && (!required_key_item)) { + if (database.GetZoneID(destination_zone_name) == zone->GetZoneID()) { + sender->MovePC( + zone->GetZoneID(), + zone->GetInstanceID(), + m_Destination.x, + m_Destination.y, + m_Destination.z, + m_Destination.w + ); + } else { + sender->MovePC( + database.GetZoneID(destination_zone_name), + static_cast(this->destination_instance_id), + m_Destination.x, + m_Destination.y, + m_Destination.z, + m_Destination.w + ); } } } @@ -450,7 +499,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) void Doors::NPCOpen(NPC* sender, bool alt_mode) { if (sender) { - if (GetTriggerType() == 255 || GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || opentype == 59 || opentype == 58 || !sender->IsNPC()) { // this object isnt triggered or door is locked - NPCs should not open locked doors! + if (GetTriggerType() == 255 || GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || open_type == 59 || open_type == 58 || !sender->IsNPC()) { // this object isnt triggered or door is locked - NPCs should not open locked doors! return; } @@ -509,12 +558,12 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode) } } -void Doors::ForceClose(Mob *sender, bool alt_mode) -{ +void Doors::ForceClose(Mob *sender, bool alt_mode) { auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; - md->doorid = door_id; - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; // change from original (open to close) + MoveDoor_Struct *move_door_packet; + move_door_packet = (MoveDoor_Struct *) outapp->pBuffer; + move_door_packet->doorid = door_id; + move_door_packet->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; // change from original (open to close) entity_list.QueueClients(sender, outapp, false); safe_delete(outapp); @@ -523,13 +572,11 @@ void Doors::ForceClose(Mob *sender, bool alt_mode) if (!disable_timer) close_timer.Start(); is_open = true; - } - else { + } else { close_timer.Disable(); is_open = false; } - } - else { // alternative function + } else { // alternative function if (is_open) close_timer.Trigger(); } @@ -537,21 +584,21 @@ void Doors::ForceClose(Mob *sender, bool alt_mode) void Doors::ToggleState(Mob *sender) { - if(GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || opentype == 58 || opentype == 40) { // borrowed some NPCOpen criteria + if(GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || open_type == 58 || open_type == 40) { // borrowed some NPCOpen criteria return; } auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; - md->doorid = door_id; + MoveDoor_Struct* move_door_packet; + move_door_packet = (MoveDoor_Struct*)outapp->pBuffer; + move_door_packet->doorid = door_id; if(!is_open) { - md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; + move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); is_open=true; } - else - { - md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; + else { + move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); is_open=false; } @@ -559,18 +606,6 @@ void Doors::ToggleState(Mob *sender) safe_delete(outapp); } -void Doors::DumpDoor(){ - Log(Logs::General, Logs::None, - "db_id:%i door_id:%i zone_name:%s door_name:%s %s", - db_id, door_id, zone_name, door_name, to_string(m_Position).c_str()); - Log(Logs::General, Logs::None, - "opentype:%i guild_id:%i lockpick:%i keyitem:%i nokeyring:%i trigger_door:%i trigger_type:%i door_param:%i open:%s", - opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (is_open) ? "open":"closed"); - Log(Logs::General, Logs::None, - "dest_zone:%s destination:%s ", - dest_zone, to_string(m_Destination).c_str()); -} - int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) { std::string query = StringFormat("SELECT MAX(id), count(*) FROM doors " @@ -599,9 +634,11 @@ int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 v } int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) { - - std::string query = StringFormat("SELECT MAX(id) FROM doors " - "WHERE zone = '%s' AND version = %u", zone_name, version); + std::string query = StringFormat( + "SELECT MAX(id) FROM doors WHERE zone = '%s' AND version = %u", + zone_name, + version + ); auto results = QueryDatabase(query); if (!results.Success()) { return -1; @@ -641,68 +678,97 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) return atoi(row[0]) + 1; } -bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) { +bool ZoneDatabase::LoadDoors(int32 door_count, Door *into, const char *zone_name, int16 version) { Log(Logs::General, Logs::Status, "Loading Doors from database..."); - - // Door tmpDoor; - std::string query = StringFormat("SELECT id, doorid, zone, name, pos_x, pos_y, pos_z, heading, " - "opentype, guild, lockpick, keyitem, nokeyring, triggerdoor, triggertype, " - "dest_zone, dest_instance, dest_x, dest_y, dest_z, dest_heading, " - "door_param, invert_state, incline, size, is_ldon_door, client_version_mask, disable_timer " - "FROM doors WHERE zone = '%s' AND (version = %u OR version = -1) " - "ORDER BY doorid asc", zone_name, version); + std::string query = StringFormat( + " SELECT " + " id, " + " doorid, " + " zone, " + " NAME, " + " pos_x, " + " pos_y, " + " pos_z, " + " heading, " + " opentype, " + " guild, " + " lockpick, " + " keyitem, " + " nokeyring, " + " triggerdoor, " + " triggertype, " + " dest_zone, " + " dest_instance, " + " dest_x, " + " dest_y, " + " dest_z, " + " dest_heading, " + " door_param, " + " invert_state, " + " incline, " + " size, " + " is_ldon_door, " + " client_version_mask, " + " disable_timer " + " FROM " + " doors " + " WHERE " + " zone = '%s' " + " AND ( version = % u OR version = - 1 ) " + " ORDER BY " + " doorid ASC ", + zone_name, + version + ); auto results = QueryDatabase(query); if (!results.Success()) { return false; } - int32 rowIndex = 0; - for (auto row = results.begin(); row != results.end(); ++row, ++rowIndex) { - if (rowIndex >= iDoorCount) { - std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl; + int32 row_index = 0; + for (auto row = results.begin(); row != results.end(); ++row, ++row_index) { + if (row_index >= door_count) { + std::cerr << "Error, Door Count of " << door_count << " exceeded." << std::endl; break; } - memset(&into[rowIndex], 0, sizeof(Door)); + memset(&into[row_index], 0, sizeof(Door)); - into[rowIndex].db_id = atoi(row[0]); - into[rowIndex].door_id = atoi(row[1]); + strn0cpy(into[row_index].zone_name, row[2], 32); + strn0cpy(into[row_index].door_name, row[3], 32); + strn0cpy(into[row_index].dest_zone, row[15], 32); - strn0cpy(into[rowIndex].zone_name, row[2], 32); - strn0cpy(into[rowIndex].door_name, row[3], 32); - - into[rowIndex].pos_x = (float)atof(row[4]); - into[rowIndex].pos_y = (float)atof(row[5]); - into[rowIndex].pos_z = (float)atof(row[6]); - into[rowIndex].heading = (float)atof(row[7]); - into[rowIndex].opentype = atoi(row[8]); - into[rowIndex].guild_id = atoi(row[9]); - into[rowIndex].lock_pick = atoi(row[10]); - into[rowIndex].keyitem = atoi(row[11]); - into[rowIndex].nokeyring = atoi(row[12]); - into[rowIndex].trigger_door = atoi(row[13]); - into[rowIndex].trigger_type = atoi(row[14]); - - strn0cpy(into[rowIndex].dest_zone, row[15], 32); - - into[rowIndex].dest_instance_id = atoi(row[16]); - into[rowIndex].dest_x = (float)atof(row[17]); - into[rowIndex].dest_y = (float)atof(row[18]); - into[rowIndex].dest_z = (float)atof(row[19]); - into[rowIndex].dest_heading = (float)atof(row[20]); - into[rowIndex].door_param = atoi(row[21]); - into[rowIndex].invert_state = atoi(row[22]); - into[rowIndex].incline = atoi(row[23]); - into[rowIndex].size = atoi(row[24]); - into[rowIndex].is_ldon_door = atoi(row[25]); - into[rowIndex].client_version_mask = (uint32)strtoul(row[26], nullptr, 10); - into[rowIndex].disable_timer = atoi(row[27]); + into[row_index].db_id = static_cast(atoi(row[0])); + into[row_index].door_id = static_cast(atoi(row[1])); + into[row_index].pos_x = (float) atof(row[4]); + into[row_index].pos_y = (float) atof(row[5]); + into[row_index].pos_z = (float) atof(row[6]); + into[row_index].heading = (float) atof(row[7]); + into[row_index].opentype = static_cast(atoi(row[8])); + into[row_index].guild_id = static_cast(atoi(row[9])); + into[row_index].lock_pick = static_cast(atoi(row[10])); + into[row_index].keyitem = static_cast(atoi(row[11])); + into[row_index].nokeyring = static_cast(atoi(row[12])); + into[row_index].trigger_door = static_cast(atoi(row[13])); + into[row_index].trigger_type = static_cast(atoi(row[14])); + into[row_index].dest_instance_id = static_cast(atoi(row[16])); + into[row_index].dest_x = (float) atof(row[17]); + into[row_index].dest_y = (float) atof(row[18]); + into[row_index].dest_z = (float) atof(row[19]); + into[row_index].dest_heading = (float) atof(row[20]); + into[row_index].door_param = static_cast(atoi(row[21])); + into[row_index].invert_state = atoi(row[22]); + into[row_index].incline = atoi(row[23]); + into[row_index].size = static_cast(atoi(row[24])); + into[row_index].is_ldon_door = static_cast(atoi(row[25])); + into[row_index].client_version_mask = (uint32) strtoul(row[26], nullptr, 10); + into[row_index].disable_timer = static_cast(atoi(row[27])); Log(Logs::Detail, Logs::Doors, "Door Load: db id: %u, door_id %u disable_timer: %i", - into[rowIndex].db_id, - into[rowIndex].door_id, - into[rowIndex].disable_timer + into[row_index].db_id, + into[row_index].door_id, + into[row_index].disable_timer ); } @@ -731,7 +797,7 @@ void Doors::SetIncline(int in) { void Doors::SetOpenType(uint8 in) { entity_list.DespawnAllDoors(); - opentype = in; + open_type = in; entity_list.RespawnAllDoors(); } @@ -754,10 +820,26 @@ void Doors::SetDisableTimer(bool flag) { void Doors::CreateDatabaseEntry() { - if(database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()) - 1 >= 255) - { + if(database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()) - 1 >= 255) { return; } - database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), m_Position, GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize()); + + /** + * Persist + */ + database.InsertDoor( + GetDoorDBID(), + GetDoorID(), + GetDoorName(), + m_Position, + GetOpenType(), + static_cast(GetGuildID()), + GetLockpick(), + GetKeyItem(), + static_cast(GetDoorParam()), + static_cast(GetInvertState()), + GetIncline(), + GetSize() + ); } diff --git a/zone/doors.h b/zone/doors.h index 80af306b8..f112f84f1 100644 --- a/zone/doors.h +++ b/zone/doors.h @@ -16,92 +16,80 @@ struct Door; class Doors : public Entity { public: - Doors(const Door* door); - Doors(const char *dmodel, const glm::vec4& position, uint8 dopentype = 58, uint16 dsize = 100); ~Doors(); - bool IsDoor() const { return true; } - void HandleClick(Client* sender, uint8 trigger); - bool Process(); - uint8 GetDoorID() { return door_id; } - uint32 GetDoorDBID() { return db_id; } - uint32 GetGuildID() { return guild_id; } - uint8 GetOpenType() { return opentype; } - char* GetDoorName() { return door_name; } - uint32 GetDoorParam() { return door_param; } - int GetInvertState() { return invert_state; } - const glm::vec4& GetPosition() const{ return m_Position; } - int GetIncline() { return incline; } - bool triggered; - void SetOpenState(bool st) { is_open = st; } - bool IsDoorOpen() { return is_open; } - uint8 GetTriggerDoorID() { return trigger_door; } - uint8 GetTriggerType() { return trigger_type; } + Doors(const char *model, const glm::vec4& position, uint8 open_type = 58, uint16 size = 100); + Doors(const Door* door); - uint32 GetKeyItem() { return keyitem; } - void SetKeyItem(uint32 in) { keyitem = in; } - uint8 GetNoKeyring() { return nokeyring; } - void SetNoKeyring(uint8 in) { nokeyring = in; } - uint16 GetLockpick() { return lockpick; } - void SetLockpick(uint16 in) { lockpick = in; } - uint16 GetSize() { return size; } - void SetGuildID(uint32 guild_id) { this->guild_id = guild_id; } - - uint32 GetEntityID() { return entity_id; } - void SetEntityID(uint32 entity) { entity_id = entity; } - - void DumpDoor(); + bool GetDisableTimer() { return disable_timer; } + bool IsDoor() const { return true; } + bool IsDoorOpen() { return is_open; } + bool Process(); + bool triggered; + char *GetDoorName() { return door_name; } const glm::vec4 GetDestination() const { return m_Destination; } - - uint8 IsLDoNDoor() { return is_ldon_door; } - uint32 GetClientVersionMask() { return client_version_mask; } - - void NPCOpen(NPC* sender, bool alt_mode=false); - void ForceOpen(Mob *sender, bool alt_mode=false); - void ForceClose(Mob *sender, bool alt_mode=false); - void ToggleState(Mob *sender); - - void SetPosition(const glm::vec4& position); - void SetLocation(float x, float y, float z); - void SetIncline(int in); - void SetDoorName(const char* name); - void SetOpenType(uint8 in); - void SetSize(uint16 size); - - void SetDisableTimer(bool flag); - bool GetDisableTimer() { return disable_timer; } - - void CreateDatabaseEntry(); + const glm::vec4 &GetPosition() const { return m_Position; } + int GetIncline() { return incline; } + int GetInvertState() { return invert_state; } + uint8 GetDoorID() { return door_id; } + uint8 GetNoKeyring() { return no_key_ring; } + uint8 GetOpenType() { return open_type; } + uint8 GetTriggerDoorID() { return trigger_door; } + uint8 GetTriggerType() { return trigger_type; } + uint8 IsLDoNDoor() { return is_ldon_door; } + uint16 GetLockpick() { return lockpick; } + uint16 GetSize() { return size; } + uint32 GetClientVersionMask() { return client_version_mask; } + uint32 GetDoorDBID() { return database_id; } + uint32 GetDoorParam() { return door_param; } + uint32 GetEntityID() { return entity_id; } + uint32 GetGuildID() { return guild_id; } + uint32 GetKeyItem() { return key_item_id; } + void CreateDatabaseEntry(); + void ForceClose(Mob *sender, bool alt_mode = false); + void ForceOpen(Mob *sender, bool alt_mode = false); + void HandleClick(Client *sender, uint8 trigger); + void NPCOpen(NPC *sender, bool alt_mode = false); + void SetDisableTimer(bool flag); + void SetDoorName(const char *name); + void SetEntityID(uint32 entity) { entity_id = entity; } + void SetIncline(int in); + void SetKeyItem(uint32 in) { key_item_id = in; } + void SetLocation(float x, float y, float z); + void SetLockpick(uint16 in) { lockpick = in; } + void SetNoKeyring(uint8 in) { no_key_ring = in; } + void SetOpenState(bool st) { is_open = st; } + void SetOpenType(uint8 in); + void SetPosition(const glm::vec4 &position); + void SetSize(uint16 size); + void ToggleState(Mob *sender); private: - uint32 db_id; - uint8 door_id; - char zone_name[32]; - char door_name[32]; + uint32 database_id; + uint8 door_id; + char zone_name[32]; + char door_name[32]; glm::vec4 m_Position; - int incline; - uint8 opentype; - uint32 guild_id; - uint16 lockpick; - uint32 keyitem; - uint8 nokeyring; - uint8 trigger_door; - uint8 trigger_type; - uint32 door_param; - uint16 size; - int invert_state; - uint32 entity_id; - bool disable_timer; - bool is_open; - Timer close_timer; - //Timer trigger_timer; - - char dest_zone[16]; - int dest_instance_id; + int incline; + uint8 open_type; + uint32 guild_id; + uint16 lockpick; + uint32 key_item_id; + uint8 no_key_ring; + uint8 trigger_door; + uint8 trigger_type; + uint32 door_param; + uint16 size; + int invert_state; + uint32 entity_id; + bool disable_timer; + bool is_open; + Timer close_timer; + char destination_zone_name[16]; + int destination_instance_id; glm::vec4 m_Destination; - - uint8 is_ldon_door; - uint32 client_version_mask; + uint8 is_ldon_door; + uint32 client_version_mask; }; #endif diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index aacedcf2d..18c84ccdd 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -31,9 +31,10 @@ #include "queryserv.h" #include "questmgr.h" #include "zone.h" +#include "data_bucket.h" -extern Zone* zone; -extern QueryServ* QServ; +extern Zone *zone; +extern QueryServ *QServ; /* @@ -50,90 +51,85 @@ SvPV_nolen == string with no length restriction //Any creation of new Client objects gets the current quest Client XS(XS_Client_new); -XS(XS_Client_new) -{ +XS(XS_Client_new) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: Client::new()"); + Perl_croak(aTHX_ "Usage: quest::Client::new()"); { - Client * RETVAL; + Client *RETVAL; RETVAL = quest_manager.GetInitiator(); ST(0) = sv_newmortal(); - if(RETVAL) - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + if (RETVAL) + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } //Any creation of new NPC objects gets the current quest NPC XS(XS_NPC_new); -XS(XS_NPC_new) -{ +XS(XS_NPC_new) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: NPC::new()"); + Perl_croak(aTHX_ "Usage: quest::NPC::new()"); { - NPC * RETVAL; + NPC *RETVAL; RETVAL = quest_manager.GetNPC(); ST(0) = sv_newmortal(); - if(RETVAL) - sv_setref_pv(ST(0), "NPC", (void*)RETVAL); + if (RETVAL) + sv_setref_pv(ST(0), "NPC", (void *) RETVAL); } XSRETURN(1); } //Any creation of new NPC objects gets the current quest NPC XS(XS_EntityList_new); -XS(XS_EntityList_new) -{ +XS(XS_EntityList_new) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: EntityList::new()"); + Perl_croak(aTHX_ "Usage: quest::EntityList::new()"); { - EntityList * RETVAL; + EntityList *RETVAL; RETVAL = &entity_list; ST(0) = sv_newmortal(); - if(RETVAL) - sv_setref_pv(ST(0), "EntityList", (void*)RETVAL); + if (RETVAL) + sv_setref_pv(ST(0), "EntityList", (void *) RETVAL); } XSRETURN(1); } //Any creation of new quest items gets the current quest item XS(XS_QuestItem_new); -XS(XS_QuestItem_new) -{ +XS(XS_QuestItem_new) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: QuestItem::new()"); + Perl_croak(aTHX_ "Usage: quest::QuestItem::new()"); - EQEmu::ItemInstance* RETVAL; + EQEmu::ItemInstance *RETVAL; RETVAL = quest_manager.GetQuestItem(); ST(0) = sv_newmortal(); - if(RETVAL) - sv_setref_pv(ST(0), "QuestItem", (void*)RETVAL); + if (RETVAL) + sv_setref_pv(ST(0), "QuestItem", (void *) RETVAL); XSRETURN(1); } //Any creation of new quest items gets the current quest item XS(XS_MobList_new); -XS(XS_MobList_new) -{ +XS(XS_MobList_new) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: MobList::new()"); + Perl_croak(aTHX_ "Usage: quest::MobList::new()"); - ListElement* RETVAL; + ListElement *RETVAL; RETVAL = nullptr; ST(0) = sv_newmortal(); - if(RETVAL) - sv_setref_pv(ST(0), "MobList", (void*)RETVAL); + if (RETVAL) + sv_setref_pv(ST(0), "MobList", (void *) RETVAL); XSRETURN(1); } @@ -145,8 +141,8 @@ XS(XS__echo); // prototype to pass -Wmissing-prototypes XS(XS__echo) { dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: echo(color_id, message)"); + if (items != 2) + Perl_croak(aTHX_ "Usage: quest::echo(int emote_color_id, string message)"); quest_manager.echo(SvUV(ST(0)), SvPV_nolen(ST(1))); @@ -160,9 +156,9 @@ XS(XS__say) { if (items == 1) quest_manager.say(SvPV_nolen(ST(0))); else if (items == 2) - quest_manager.say(SvPV_nolen(ST(0)), (int)SvIV(ST(1))); + quest_manager.say(SvPV_nolen(ST(0)), (int) SvIV(ST(1))); else - Perl_croak(aTHX_ "Usage: say(message [, language_id])"); + Perl_croak(aTHX_ "Usage: quest::say(string message, int language_id])"); XSRETURN_EMPTY; } @@ -172,7 +168,7 @@ XS(XS__me) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: %s(message)", "me"); + Perl_croak(aTHX_ "Usage: quest::me(string message)"); quest_manager.me(SvPV_nolen(ST(0))); @@ -180,27 +176,25 @@ XS(XS__me) { } XS(XS__summonitem); // prototype to pass -Wmissing-prototypes -XS(XS__summonitem) -{ +XS(XS__summonitem) { dXSARGS; if (items == 1) quest_manager.summonitem(SvUV(ST(0))); - else if(items == 2) + else if (items == 2) quest_manager.summonitem(SvUV(ST(0)), SvUV(ST(1))); else - Perl_croak(aTHX_ "Usage: summonitem(item_id, [charges])"); + Perl_croak(aTHX_ "Usage: quest::summonitem(int item_id, [int charges])"); XSRETURN_EMPTY; } XS(XS__write); -XS(XS__write) -{ +XS(XS__write) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: write(file, message)"); + Perl_croak(aTHX_ "Usage: quest::write(string file_name, string message)"); - char * file = (char *)SvPV_nolen(ST(0)); - char * message = (char *)SvPV_nolen(ST(1)); + char *file = (char *) SvPV_nolen(ST(0)); + char *message = (char *) SvPV_nolen(ST(1)); quest_manager.write(file, message); @@ -208,132 +202,132 @@ XS(XS__write) } XS(XS__spawn); -XS(XS__spawn) -{ +XS(XS__spawn) { dXSARGS; if (items != 6) - Perl_croak(aTHX_ "Usage: spawn(npc_type_id, grid_id, int_unused, x, y, z)"); + Perl_croak(aTHX_ + "Usage: quest::spawn(int npc_type_id, int grid_id, int int_unused, float x, float y, float z)"); - uint16 RETVAL; + uint16 RETVAL; dXSTARG; - int npc_type_id = (int)SvIV(ST(0)); - int grid_id = (int)SvIV(ST(1)); - int int_unused = (int)SvIV(ST(2)); - auto position = glm::vec4((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), 0.0f); + int npc_type_id = (int) SvIV(ST(0)); + int grid_id = (int) SvIV(ST(1)); + int int_unused = (int) SvIV(ST(2)); + auto position = glm::vec4((float) SvNV(ST(3)), (float) SvNV(ST(4)), (float) SvNV(ST(5)), 0.0f); Mob *r = quest_manager.spawn2(npc_type_id, grid_id, int_unused, position); RETVAL = (r != nullptr) ? r->GetID() : 0; - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); XSRETURN(1); } XS(XS__spawn2); -XS(XS__spawn2) -{ +XS(XS__spawn2) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: spawn2(npc_type_id, grid_id, int_unused, x, y, z, heading)"); + Perl_croak(aTHX_ + "Usage: quest::spawn2(int npc_type_id, int grid_id, int int_unused, float x, float y, float z, float heading)"); - uint16 RETVAL; + uint16 RETVAL; dXSTARG; - int npc_type_id = (int)SvIV(ST(0)); - int grid_id = (int)SvIV(ST(1)); - int int_unused = (int)SvIV(ST(2)); - auto position = glm::vec4((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), (float)SvNV(ST(6))); + int npc_type_id = (int) SvIV(ST(0)); + int grid_id = (int) SvIV(ST(1)); + int int_unused = (int) SvIV(ST(2)); + auto position = glm::vec4((float) SvNV(ST(3)), (float) SvNV(ST(4)), (float) SvNV(ST(5)), (float) SvNV(ST(6))); Mob *r = quest_manager.spawn2(npc_type_id, grid_id, int_unused, position); RETVAL = (r != nullptr) ? r->GetID() : 0; - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); XSRETURN(1); } XS(XS__unique_spawn); -XS(XS__unique_spawn) -{ +XS(XS__unique_spawn) { dXSARGS; if (items != 6 && items != 7) - Perl_croak(aTHX_ "Usage: unique_spawn(npc_type_id, grid_id, int_unused, x, y, z, [heading])"); + Perl_croak(aTHX_ + "Usage: quest::unique_spawn(int npc_type_id, int grid_id, int int_unused, float x, float y, float z, [float heading])"); - uint16 RETVAL; + uint16 RETVAL; dXSTARG; - int npc_type_id = (int)SvIV(ST(0)); - int grid_id = (int)SvIV(ST(1)); - int int_unused = (int)SvIV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); - float heading = 0; - if(items == 7) - heading = (float)SvNV(ST(6)); + int npc_type_id = (int) SvIV(ST(0)); + int grid_id = (int) SvIV(ST(1)); + int int_unused = (int) SvIV(ST(2)); + float x = (float) SvNV(ST(3)); + float y = (float) SvNV(ST(4)); + float z = (float) SvNV(ST(5)); + float heading = 0; + if (items == 7) + heading = (float) SvNV(ST(6)); - Mob *r = quest_manager.unique_spawn(npc_type_id, grid_id, int_unused, glm::vec4(x, y, z, heading)); + Mob *r = quest_manager.unique_spawn(npc_type_id, grid_id, int_unused, glm::vec4(x, y, z, heading)); RETVAL = (r != nullptr) ? r->GetID() : 0; - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); XSRETURN(1); } XS(XS__spawn_from_spawn2); -XS(XS__spawn_from_spawn2) -{ +XS(XS__spawn_from_spawn2) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: spawn_from_spawn2(spawn2_id)"); + Perl_croak(aTHX_ "Usage: quest::spawn_from_spawn2(int spawn2_id)"); - uint16 RETVAL; + uint16 RETVAL; dXSTARG; - int spawn2_id = (int)SvIV(ST(0)); + int spawn2_id = (int) SvIV(ST(0)); - Mob *r = quest_manager.spawn_from_spawn2(spawn2_id); + Mob *r = quest_manager.spawn_from_spawn2(spawn2_id); RETVAL = (r != nullptr) ? r->GetID() : 0; - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); XSRETURN(1); } XS(XS__enable_spawn2); -XS(XS__enable_spawn2) -{ +XS(XS__enable_spawn2) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: enable_spawn2(spawn2_id)"); + Perl_croak(aTHX_ "Usage: quest::enable_spawn2(int spawn2_id)"); - int spawn2_id = (int)SvIV(ST(0)); + int spawn2_id = (int) SvIV(ST(0)); quest_manager.enable_spawn2(spawn2_id); XSRETURN_EMPTY; } XS(XS__disable_spawn2); -XS(XS__disable_spawn2) -{ +XS(XS__disable_spawn2) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: disable_spawn2(spawn2_id)"); + Perl_croak(aTHX_ "Usage: quest::disable_spawn2(int spawn2_id)"); - int spawn2_id = (int)SvIV(ST(0)); + int spawn2_id = (int) SvIV(ST(0)); quest_manager.disable_spawn2(spawn2_id); XSRETURN_EMPTY; } XS(XS__setstat); -XS(XS__setstat) -{ +XS(XS__setstat) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: setstat(stat_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::setstat(stat_id, int_value)"); - int stat_id = (int)SvIV(ST(0)); - int int_value = (int)SvIV(ST(1)); + int stat_id = (int) SvIV(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.setstat(stat_id, int_value); @@ -341,14 +335,13 @@ XS(XS__setstat) } XS(XS__incstat); //old setstat command aza -XS(XS__incstat) -{ +XS(XS__incstat) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: incstat(stat_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::incstat(int stat_id, int value)"); - int stat_id = (int)SvIV(ST(0)); - int int_value = (int)SvIV(ST(1)); + int stat_id = (int) SvIV(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.incstat(stat_id, int_value); @@ -356,14 +349,13 @@ XS(XS__incstat) } XS(XS__castspell); -XS(XS__castspell) -{ +XS(XS__castspell) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: castspell(spell_id, target_id)"); + Perl_croak(aTHX_ "Usage: quest::castspell(int spell_id, int target_id)"); - int spell_id = (int)SvIV(ST(0)); - int target_id = (int)SvIV(ST(1)); + int spell_id = (int) SvIV(ST(0)); + int target_id = (int) SvIV(ST(1)); quest_manager.castspell(spell_id, target_id); @@ -371,13 +363,12 @@ XS(XS__castspell) } XS(XS__selfcast); -XS(XS__selfcast) -{ +XS(XS__selfcast) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: selfcast(spell_id)"); + Perl_croak(aTHX_ "Usage: quest::selfcast(int spell_id)"); - int spell_id = (int)SvIV(ST(0)); + int spell_id = (int) SvIV(ST(0)); quest_manager.selfcast(spell_id); @@ -385,20 +376,19 @@ XS(XS__selfcast) } XS(XS__addloot); -XS(XS__addloot) -{ +XS(XS__addloot) { dXSARGS; - if(items < 1 || items > 3) - Perl_croak(aTHX_ "Usage: addloot(item_id, charges = 0, equipitem = true)"); + if (items < 1 || items > 3) + Perl_croak(aTHX_ "Usage: quest::addloot(uint32 item_id, uint16 charges = 0, [bool equip_item = true])"); - uint32 item_id = (uint32)SvUV(ST(0)); - uint16 charges = 0; - bool equipitem = true; + uint32 item_id = (uint32) SvUV(ST(0)); + uint16 charges = 0; + bool equipitem = true; if (items > 1) - charges = (uint16)SvUV(ST(1)); + charges = (uint16) SvUV(ST(1)); if (items > 2) - equipitem = (bool)SvTRUE(ST(2)); + equipitem = (bool) SvTRUE(ST(2)); quest_manager.addloot(item_id, charges, equipitem); @@ -406,13 +396,12 @@ XS(XS__addloot) } XS(XS__zone); -XS(XS__zone) -{ +XS(XS__zone) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: zone(zone_name)"); + Perl_croak(aTHX_ "Usage: quest::zone(string zone_name)"); - char * zone_name = (char *)SvPV_nolen(ST(0)); + char *zone_name = (char *) SvPV_nolen(ST(0)); quest_manager.Zone(zone_name); @@ -420,14 +409,13 @@ XS(XS__zone) } XS(XS__settimer); -XS(XS__settimer) -{ +XS(XS__settimer) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: settimer(timer_name, seconds)"); + Perl_croak(aTHX_ "Usage: quest::settimer(string timer_name, int seconds)"); - char * timer_name = (char *)SvPV_nolen(ST(0)); - int seconds = (int)SvIV(ST(1)); + char *timer_name = (char *) SvPV_nolen(ST(0)); + int seconds = (int) SvIV(ST(1)); quest_manager.settimer(timer_name, seconds); @@ -435,14 +423,13 @@ XS(XS__settimer) } XS(XS__settimerMS); -XS(XS__settimerMS) -{ +XS(XS__settimerMS) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: settimerMS(timer_name, milliseconds)"); + Perl_croak(aTHX_ "Usage: quest::settimerMS(string timer_name, int milliseconds)"); - char * timer_name = (char *)SvPV_nolen(ST(0)); - int milliseconds = (int)SvIV(ST(1)); + char *timer_name = (char *) SvPV_nolen(ST(0)); + int milliseconds = (int) SvIV(ST(1)); quest_manager.settimerMS(timer_name, milliseconds); @@ -450,13 +437,12 @@ XS(XS__settimerMS) } XS(XS__stoptimer); -XS(XS__stoptimer) -{ +XS(XS__stoptimer) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: stoptimer(timer_name)"); + Perl_croak(aTHX_ "Usage: quest::stoptimer(string timer_name)"); - char * timer_name = (char *)SvPV_nolen(ST(0)); + char *timer_name = (char *) SvPV_nolen(ST(0)); quest_manager.stoptimer(timer_name); @@ -464,11 +450,10 @@ XS(XS__stoptimer) } XS(XS__stopalltimers); -XS(XS__stopalltimers) -{ +XS(XS__stopalltimers) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: stopalltimers()"); + Perl_croak(aTHX_ "Usage: quest::stopalltimers()"); quest_manager.stopalltimers(); @@ -476,13 +461,12 @@ XS(XS__stopalltimers) } XS(XS__emote); -XS(XS__emote) -{ +XS(XS__emote) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: emote(message)"); + Perl_croak(aTHX_ "Usage: quest::emote(string message)"); - char * message = (char *)SvPV_nolen(ST(0)); + char *message = (char *) SvPV_nolen(ST(0)); quest_manager.emote(message); @@ -490,13 +474,12 @@ XS(XS__emote) } XS(XS__shout); -XS(XS__shout) -{ +XS(XS__shout) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: shout(message)"); + Perl_croak(aTHX_ "Usage: quest::shout(string message)"); - char * message = (char *)SvPV_nolen(ST(0)); + char *message = (char *) SvPV_nolen(ST(0)); quest_manager.shout(message); @@ -504,13 +487,12 @@ XS(XS__shout) } XS(XS__shout2); -XS(XS__shout2) -{ +XS(XS__shout2) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: shout2(message)"); + Perl_croak(aTHX_ "Usage: quest::shout2(string message)"); - char * message = (char *)SvPV_nolen(ST(0)); + char *message = (char *) SvPV_nolen(ST(0)); quest_manager.shout2(message); @@ -518,31 +500,30 @@ XS(XS__shout2) } XS(XS__gmsay); -XS(XS__gmsay) -{ +XS(XS__gmsay) { dXSARGS; if ((items < 1) || (items > 5)) - Perl_croak(aTHX_ "Usage: gmsay(message, color_id, send_to_world)"); + Perl_croak(aTHX_ "Usage: quest::gmsay(string message, [int color_id], [bool send_to_world = 0])"); - char * message = (char *)SvPV_nolen(ST(0)); - int color_id = 7; - bool send_to_world = 0; - uint32 to_guilddbid = 0; - uint16 to_minstatus = 80; + char *message = (char *) SvPV_nolen(ST(0)); + int color_id = 7; + bool send_to_world = 0; + uint32 to_guilddbid = 0; + uint16 to_minstatus = 80; if (items > 1) { - color_id = (int)SvIV(ST(1)); + color_id = (int) SvIV(ST(1)); } if (items > 2) { - send_to_world = ((int)SvIV(ST(2))) == 0?false:true; + send_to_world = ((int) SvIV(ST(2))) == 0 ? false : true; } if (items > 3) - to_guilddbid = (int)SvUV(ST(3)); + to_guilddbid = (int) SvUV(ST(3)); if (items > 4) - to_minstatus = (int)SvUV(ST(4)); + to_minstatus = (int) SvUV(ST(4)); quest_manager.gmsay(message, color_id, send_to_world, to_guilddbid, to_minstatus); @@ -550,18 +531,17 @@ XS(XS__gmsay) } XS(XS__depop); -XS(XS__depop) -{ +XS(XS__depop) { dXSARGS; if (items < 0 || items > 1) - Perl_croak(aTHX_ "Usage: depop(npc_type_id = 0)"); + Perl_croak(aTHX_ "Usage: quest::depop(int npc_type_id = 0)"); - int npc_type_id; + int npc_type_id; if (items < 1) npc_type_id = 0; else - npc_type_id = (int)SvIV(ST(0)); + npc_type_id = (int) SvIV(ST(0)); quest_manager.depop(npc_type_id); @@ -570,18 +550,17 @@ XS(XS__depop) } XS(XS__depop_withtimer); -XS(XS__depop_withtimer) -{ +XS(XS__depop_withtimer) { dXSARGS; if (items < 0 || items > 1) - Perl_croak(aTHX_ "Usage: depop_withtimer(npc_type_id= 0)"); + Perl_croak(aTHX_ "Usage: quest::depop_withtimer(int npc_type_id = 0)"); - int npc_type_id; + int npc_type_id; if (items < 1) npc_type_id = 0; else - npc_type_id = (int)SvIV(ST(0)); + npc_type_id = (int) SvIV(ST(0)); quest_manager.depop_withtimer(npc_type_id); @@ -590,18 +569,17 @@ XS(XS__depop_withtimer) } XS(XS__depopall); -XS(XS__depopall) -{ +XS(XS__depopall) { dXSARGS; if (items < 0 || items > 1) - Perl_croak(aTHX_ "Usage: depopall(npc_type_id= 0)"); + Perl_croak(aTHX_ "Usage: quest::depopall(int npc_type_id = 0)"); - int npc_type_id; + int npc_type_id; if (items < 1) npc_type_id = 0; else - npc_type_id = (int)SvIV(ST(0)); + npc_type_id = (int) SvIV(ST(0)); quest_manager.depopall(npc_type_id); @@ -610,14 +588,13 @@ XS(XS__depopall) } XS(XS__settarget); -XS(XS__settarget) -{ +XS(XS__settarget) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: settarget(target_enum, target_id)"); + Perl_croak(aTHX_ "Usage: quest::settarget(string target_enum ['npc_type', 'entity'], int target_id)"); - char * target_enum = (char *)SvPV_nolen(ST(0)); - int target_id = (int)SvIV(ST(1)); + char *target_enum = (char *) SvPV_nolen(ST(0)); + int target_id = (int) SvIV(ST(1)); quest_manager.settarget(target_enum, target_id); @@ -625,17 +602,16 @@ XS(XS__settarget) } XS(XS__follow); -XS(XS__follow) -{ +XS(XS__follow) { dXSARGS; if (items != 1 && items != 2) - Perl_croak(aTHX_ "Usage: follow(entity_id, [distance])"); + Perl_croak(aTHX_ "Usage: quest::follow(int entity_id, [int distance = 10])"); - int entity_id = (int)SvIV(ST(0)); - int distance; + int entity_id = (int) SvIV(ST(0)); + int distance; if (items == 2) - distance = (int)SvIV(ST(1)); + distance = (int) SvIV(ST(1)); else distance = 10; @@ -645,11 +621,10 @@ XS(XS__follow) } XS(XS__sfollow); -XS(XS__sfollow) -{ +XS(XS__sfollow) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: sfollow()"); + Perl_croak(aTHX_ "Usage: quest::sfollow()"); quest_manager.sfollow(); @@ -658,13 +633,12 @@ XS(XS__sfollow) } XS(XS__changedeity); -XS(XS__changedeity) -{ +XS(XS__changedeity) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: changedeity(diety_id)"); + Perl_croak(aTHX_ "Usage: quest::changedeity(int deity_id)"); - int diety_id = (int)SvIV(ST(0)); + int diety_id = (int) SvIV(ST(0)); quest_manager.changedeity(diety_id); @@ -672,13 +646,12 @@ XS(XS__changedeity) } XS(XS__exp); -XS(XS__exp) -{ +XS(XS__exp) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: exp(amt)"); + Perl_croak(aTHX_ "Usage: quest::exp(int amount)"); - int amt = (int)SvIV(ST(0)); + int amt = (int) SvIV(ST(0)); quest_manager.exp(amt); @@ -686,13 +659,12 @@ XS(XS__exp) } XS(XS__level); -XS(XS__level) -{ +XS(XS__level) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: level(newlevel)"); + Perl_croak(aTHX_ "Usage: quest::level(int new_level)"); - int newlevel = (int)SvIV(ST(0)); + int newlevel = (int) SvIV(ST(0)); quest_manager.level(newlevel); @@ -700,13 +672,12 @@ XS(XS__level) } XS(XS__traindisc); -XS(XS__traindisc) -{ +XS(XS__traindisc) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: traindisc(discipline_tome_item_id)"); + Perl_croak(aTHX_ "Usage: quest::traindisc(int tome_item_id)"); - int discipline_tome_item_id = (int)SvIV(ST(0)); + int discipline_tome_item_id = (int) SvIV(ST(0)); quest_manager.traindisc(discipline_tome_item_id); @@ -714,28 +685,26 @@ XS(XS__traindisc) } XS(XS__isdisctome); -XS(XS__isdisctome) -{ +XS(XS__isdisctome) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: isdisctome(item_id)"); + Perl_croak(aTHX_ "Usage: quest::isdisctome(int item_id)"); bool RETVAL; - int item_id = (int)SvIV(ST(0)); + int item_id = (int) SvIV(ST(0)); RETVAL = quest_manager.isdisctome(item_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); XSRETURN(1); } XS(XS__safemove); -XS(XS__safemove) -{ +XS(XS__safemove) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: safemove()"); + Perl_croak(aTHX_ "Usage: quest::safemove()"); quest_manager.safemove(); @@ -744,13 +713,12 @@ XS(XS__safemove) } XS(XS__rain); -XS(XS__rain) -{ +XS(XS__rain) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: rain(weather)"); + Perl_croak(aTHX_ "Usage: quest::rain(int weather)"); - int weather = (int)SvIV(ST(0)); + int weather = (int) SvIV(ST(0)); quest_manager.rain(weather); @@ -758,13 +726,12 @@ XS(XS__rain) } XS(XS__snow); -XS(XS__snow) -{ +XS(XS__snow) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: snow(weather)"); + Perl_croak(aTHX_ "Usage: quest::snow(int weather)"); - int weather = (int)SvIV(ST(0)); + int weather = (int) SvIV(ST(0)); quest_manager.snow(weather); @@ -772,13 +739,12 @@ XS(XS__snow) } XS(XS__surname); -XS(XS__surname) -{ +XS(XS__surname) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: surname(name)"); + Perl_croak(aTHX_ "Usage: quest::surname(string name)"); - char * name = (char *)SvPV_nolen(ST(0)); + char *name = (char *) SvPV_nolen(ST(0)); quest_manager.surname(name); @@ -786,13 +752,12 @@ XS(XS__surname) } XS(XS__permaclass); -XS(XS__permaclass) -{ +XS(XS__permaclass) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: permaclass(class_id)"); + Perl_croak(aTHX_ "Usage: quest::permaclass(int class_id)"); - int class_id = (int)SvIV(ST(0)); + int class_id = (int) SvIV(ST(0)); quest_manager.permaclass(class_id); @@ -800,13 +765,12 @@ XS(XS__permaclass) } XS(XS__permarace); -XS(XS__permarace) -{ +XS(XS__permarace) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: permarace(race_id)"); + Perl_croak(aTHX_ "Usage: quest::permarace(int race_id)"); - int race_id = (int)SvIV(ST(0)); + int race_id = (int) SvIV(ST(0)); quest_manager.permarace(race_id); @@ -814,13 +778,12 @@ XS(XS__permarace) } XS(XS__permagender); -XS(XS__permagender) -{ +XS(XS__permagender) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: permagender(gender_id)"); + Perl_croak(aTHX_ "Usage: quest::permagender(int gender_id)"); - int gender_id = (int)SvIV(ST(0)); + int gender_id = (int) SvIV(ST(0)); quest_manager.permagender(gender_id); @@ -828,55 +791,54 @@ XS(XS__permagender) } XS(XS__scribespells); -XS(XS__scribespells) -{ +XS(XS__scribespells) { dXSARGS; if (items < 1) - Perl_croak(aTHX_ "Usage: scribespells(max_level, min_level = 1)"); + Perl_croak(aTHX_ "Usage: quest::scribespells(int max_level, [int min_level = 1])"); - uint16 RETVAL; + uint16 RETVAL; dXSTARG; - uint8 max_level = (uint8)SvIV(ST(0)); - uint8 min_level = (uint8)SvIV(ST(1)); + uint8 max_level = (uint8) SvIV(ST(0)); + uint8 min_level = (uint8) SvIV(ST(1)); if (min_level) RETVAL = quest_manager.scribespells(max_level, min_level); else RETVAL = quest_manager.scribespells(max_level); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__traindiscs); -XS(XS__traindiscs) -{ +XS(XS__traindiscs) { dXSARGS; if (items < 1) - Perl_croak(aTHX_ "Usage: traindiscs(max_level, min_level = 1)"); + Perl_croak(aTHX_ "Usage: quest::traindiscs(int max_level, [int min_level = 1])"); - uint16 RETVAL; + uint16 RETVAL; dXSTARG; - uint8 max_level = (uint8)SvIV(ST(0)); - uint8 min_level = (uint8)SvIV(ST(1)); + uint8 max_level = (uint8) SvIV(ST(0)); + uint8 min_level = (uint8) SvIV(ST(1)); if (min_level) RETVAL = quest_manager.traindiscs(max_level, min_level); else RETVAL = quest_manager.traindiscs(max_level); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__unscribespells); -XS(XS__unscribespells) -{ +XS(XS__unscribespells) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: unscribespells()"); + Perl_croak(aTHX_ "Usage: quest::unscribespells()"); quest_manager.unscribespells(); @@ -885,11 +847,10 @@ XS(XS__unscribespells) } XS(XS__untraindiscs); -XS(XS__untraindiscs) -{ +XS(XS__untraindiscs) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: untraindiscs()"); + Perl_croak(aTHX_ "Usage: quest::untraindiscs()"); quest_manager.untraindiscs(); @@ -898,16 +859,15 @@ XS(XS__untraindiscs) } XS(XS__givecash); -XS(XS__givecash) -{ +XS(XS__givecash) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: givecash(copper, silver, gold, platinum)"); + Perl_croak(aTHX_ "Usage: quest::givecash(int copper, int silver, int gold, int platinum)"); - int copper = (int)SvIV(ST(0)); - int silver = (int)SvIV(ST(1)); - int gold = (int)SvIV(ST(2)); - int platinum = (int)SvIV(ST(3)); + int copper = (int) SvIV(ST(0)); + int silver = (int) SvIV(ST(1)); + int gold = (int) SvIV(ST(2)); + int platinum = (int) SvIV(ST(3)); quest_manager.givecash(copper, silver, gold, platinum); @@ -915,13 +875,12 @@ XS(XS__givecash) } XS(XS__pvp); -XS(XS__pvp) -{ +XS(XS__pvp) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: pvp(mode)"); + Perl_croak(aTHX_ "Usage: quest::pvp(string mode [on|off])"); - char * mode = (char *)SvPV_nolen(ST(0)); + char *mode = (char *) SvPV_nolen(ST(0)); quest_manager.pvp(mode); @@ -929,39 +888,37 @@ XS(XS__pvp) } XS(XS__movepc); -XS(XS__movepc) -{ +XS(XS__movepc) { dXSARGS; if (items != 4 && items != 5) - Perl_croak(aTHX_ "Usage: movepc(zone_id, x, y, z [,heading])"); + Perl_croak(aTHX_ "Usage: quest::movepc(int zone_id, float x, float y, float z [float heading])"); - int zone_id = (int)SvIV(ST(0)); - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); + int zone_id = (int) SvIV(ST(0)); + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); if (items == 4) - quest_manager.movepc(zone_id, x, y, z, 0.0f); + quest_manager.movepc(zone_id, x, y, z, 0.0f); else { - float heading = (float)SvNV(ST(4)); - quest_manager.movepc(zone_id, x, y, z, heading); + float heading = (float) SvNV(ST(4)); + quest_manager.movepc(zone_id, x, y, z, heading); } XSRETURN_EMPTY; } XS(XS__gmmove); -XS(XS__gmmove) -{ +XS(XS__gmmove) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: gmmove(x, y, z)"); + Perl_croak(aTHX_ "Usage: quest::gmmove(float x, float y, float z)"); - float x = (float)SvNV(ST(0)); - float y = (float)SvNV(ST(1)); - float z = (float)SvNV(ST(2)); + float x = (float) SvNV(ST(0)); + float y = (float) SvNV(ST(1)); + float z = (float) SvNV(ST(2)); quest_manager.gmmove(x, y, z); @@ -969,16 +926,15 @@ XS(XS__gmmove) } XS(XS__movegrp); -XS(XS__movegrp) -{ +XS(XS__movegrp) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: movegrp(zone_id, x, y, z)"); + Perl_croak(aTHX_ "Usage: quest::movegrp(int zone_id, float x, float y, float z)"); - int zone_id = (int)SvIV(ST(0)); - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); + int zone_id = (int) SvIV(ST(0)); + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); quest_manager.movegrp(zone_id, x, y, z); @@ -986,13 +942,12 @@ XS(XS__movegrp) } XS(XS__doanim); -XS(XS__doanim) -{ +XS(XS__doanim) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: doanim(anim_id)"); + Perl_croak(aTHX_ "Usage: quest::doanim(int animation_id)"); - int anim_id = (int)SvIV(ST(0)); + int anim_id = (int) SvIV(ST(0)); quest_manager.doanim(anim_id); @@ -1000,14 +955,13 @@ XS(XS__doanim) } XS(XS__addskill); -XS(XS__addskill) -{ +XS(XS__addskill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: addskill(skill_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::addskill(int skill_id, int value)"); - int skill_id = (int)SvIV(ST(0)); - int int_value = (int)SvIV(ST(1)); + int skill_id = (int) SvIV(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.addskill(skill_id, int_value); @@ -1015,14 +969,13 @@ XS(XS__addskill) } XS(XS__setlanguage); -XS(XS__setlanguage) -{ +XS(XS__setlanguage) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: setlanguage(skill_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::setlanguage(int skill_id, int value)"); - int skill_id = (int)SvIV(ST(0)); - int int_value = (int)SvIV(ST(1)); + int skill_id = (int) SvIV(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.setlanguage(skill_id, int_value); @@ -1030,14 +983,13 @@ XS(XS__setlanguage) } XS(XS__setskill); -XS(XS__setskill) -{ +XS(XS__setskill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: setskill(skill_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::setskill(int skill_id, int value)"); - int skill_id = (int)SvIV(ST(0)); - int int_value = (int)SvIV(ST(1)); + int skill_id = (int) SvIV(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.setskill(skill_id, int_value); @@ -1045,13 +997,12 @@ XS(XS__setskill) } XS(XS__setallskill); -XS(XS__setallskill) -{ +XS(XS__setallskill) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: setallskill(int_value)"); + Perl_croak(aTHX_ "Usage: quest::setallskill(int value)"); - int int_value = (int)SvIV(ST(0)); + int int_value = (int) SvIV(ST(0)); quest_manager.setallskill(int_value); @@ -1059,13 +1010,12 @@ XS(XS__setallskill) } XS(XS__attack); -XS(XS__attack) -{ +XS(XS__attack) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: attack(client_name)"); + Perl_croak(aTHX_ "Usage: quest::attack(string client_name)"); - char * client_name = (char *)SvPV_nolen(ST(0)); + char *client_name = (char *) SvPV_nolen(ST(0)); quest_manager.attack(client_name); @@ -1073,13 +1023,12 @@ XS(XS__attack) } XS(XS__attacknpc); -XS(XS__attacknpc) -{ +XS(XS__attacknpc) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: attacknpc(npc_entity_id)"); + Perl_croak(aTHX_ "Usage: quest::attacknpc(int npc_entity_id)"); - int npc_entity_id = (int)SvIV(ST(0)); + int npc_entity_id = (int) SvIV(ST(0)); quest_manager.attacknpc(npc_entity_id); @@ -1087,13 +1036,12 @@ XS(XS__attacknpc) } XS(XS__attacknpctype); -XS(XS__attacknpctype) -{ +XS(XS__attacknpctype) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: attacknpctype(npc_type_id)"); + Perl_croak(aTHX_ "Usage: quest::attacknpctype(int npc_type_id)"); - int npc_type_id = (int)SvIV(ST(0)); + int npc_type_id = (int) SvIV(ST(0)); quest_manager.attacknpctype(npc_type_id); @@ -1101,11 +1049,10 @@ XS(XS__attacknpctype) } XS(XS__save); -XS(XS__save) -{ +XS(XS__save) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: save()"); + Perl_croak(aTHX_ "Usage: quest::save()"); quest_manager.save(); @@ -1114,20 +1061,19 @@ XS(XS__save) } XS(XS__faction); -XS(XS__faction) -{ +XS(XS__faction) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: faction(faction_id, int_value, temp)"); + Perl_croak(aTHX_ "Usage: quest::faction(int faction_id, int value, [int temp = 0])"); - int faction_id = (int)SvIV(ST(0)); - int int_value = (int)SvIV(ST(1)); + int faction_id = (int) SvIV(ST(0)); + int int_value = (int) SvIV(ST(1)); int temp; - if(items == 2) + if (items == 2) temp = 0; else - temp = (int)SvIV(ST(2)); + temp = (int) SvIV(ST(2)); quest_manager.faction(faction_id, int_value, temp); @@ -1135,13 +1081,12 @@ XS(XS__faction) } XS(XS__setsky); -XS(XS__setsky) -{ +XS(XS__setsky) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: setsky(new_sky)"); + Perl_croak(aTHX_ "Usage: quest::setsky(uint8 sky)"); - unsigned char new_sky = (unsigned char)SvUV(ST(0)); + unsigned char new_sky = (unsigned char) SvUV(ST(0)); quest_manager.setsky(new_sky); @@ -1149,14 +1094,13 @@ XS(XS__setsky) } XS(XS__setguild); -XS(XS__setguild) -{ +XS(XS__setguild) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: setguild(new_guild_id, guild_rank_id)"); + Perl_croak(aTHX_ "Usage: quest::setguild(int guild_id, int guild_rank_id)"); - unsigned long new_guild_id = (unsigned long)SvUV(ST(0)); - int guild_rank_id = (int)SvIV(ST(1)); + unsigned long new_guild_id = (unsigned long) SvUV(ST(0)); + int guild_rank_id = (int) SvIV(ST(1)); quest_manager.setguild(new_guild_id, guild_rank_id); @@ -1164,14 +1108,13 @@ XS(XS__setguild) } XS(XS__createguild); -XS(XS__createguild) -{ +XS(XS__createguild) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: createguild(guild_name, leader_name)"); + Perl_croak(aTHX_ "Usage: quest::createguild(string guild_name, string leader_name)"); - char * guild_name = (char *)SvPV_nolen(ST(0)); - char * leader_name = (char *)SvPV_nolen(ST(1)); + char *guild_name = (char *) SvPV_nolen(ST(0)); + char *leader_name = (char *) SvPV_nolen(ST(1)); quest_manager.CreateGuild(guild_name, leader_name); @@ -1179,26 +1122,23 @@ XS(XS__createguild) } XS(XS__settime); -XS(XS__settime) -{ +XS(XS__settime) { dXSARGS; if (items < 2) - Perl_croak(aTHX_ "Usage: settime(new_hour, new_min, [update_world = true])"); + Perl_croak(aTHX_ "Usage: quest::settime(int new_hour, int new_min, [bool update_world = true])"); - if (items == 2){ - int new_hour = (int)SvIV(ST(0)); - int new_min = (int)SvIV(ST(1)); + if (items == 2) { + int new_hour = (int) SvIV(ST(0)); + int new_min = (int) SvIV(ST(1)); quest_manager.settime(new_hour, new_min, true); - } - else if (items == 3){ - int new_hour = (int)SvIV(ST(0)); - int new_min = (int)SvIV(ST(1)); + } else if (items == 3) { + int new_hour = (int) SvIV(ST(0)); + int new_min = (int) SvIV(ST(1)); - int update_world = (int)SvIV(ST(2)); - if (update_world == 1){ + int update_world = (int) SvIV(ST(2)); + if (update_world == 1) { quest_manager.settime(new_hour, new_min, true); - } - else{ + } else { quest_manager.settime(new_hour, new_min, false); } } @@ -1207,13 +1147,12 @@ XS(XS__settime) } XS(XS__itemlink); -XS(XS__itemlink) -{ +XS(XS__itemlink) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: itemlink(item_id)"); + Perl_croak(aTHX_ "Usage: quest::itemlink(int item_id)"); - int item_id = (int)SvIV(ST(0)); + int item_id = (int) SvIV(ST(0)); quest_manager.itemlink(item_id); @@ -1221,56 +1160,53 @@ XS(XS__itemlink) } XS(XS__signalwith); -XS(XS__signalwith) -{ +XS(XS__signalwith) { dXSARGS; if (items == 2) { - int npc_id = (int)SvIV(ST(0)); - int signal_id = (int)SvIV(ST(1)); + int npc_id = (int) SvIV(ST(0)); + int signal_id = (int) SvIV(ST(1)); quest_manager.signalwith(npc_id, signal_id); - } else if(items == 3) { - int npc_id = (int)SvIV(ST(0)); - int signal_id = (int)SvIV(ST(1)); - int wait = (int)SvIV(ST(2)); + } else if (items == 3) { + int npc_id = (int) SvIV(ST(0)); + int signal_id = (int) SvIV(ST(1)); + int wait = (int) SvIV(ST(2)); quest_manager.signalwith(npc_id, signal_id, wait); } else { - Perl_croak(aTHX_ "Usage: signalwith(npc_id,signal_id[,wait_ms])"); + Perl_croak(aTHX_ "Usage: quest::signalwith(int npc_id, int signal_id, [int wait_ms])"); } XSRETURN_EMPTY; } XS(XS__signal); -XS(XS__signal) -{ +XS(XS__signal) { dXSARGS; if (items == 1) { - int npc_id = (int)SvIV(ST(0)); + int npc_id = (int) SvIV(ST(0)); quest_manager.signal(npc_id); - } else if(items == 2) { - int npc_id = (int)SvIV(ST(0)); - int wait = (int)SvIV(ST(1)); + } else if (items == 2) { + int npc_id = (int) SvIV(ST(0)); + int wait = (int) SvIV(ST(1)); quest_manager.signal(npc_id, wait); } else { - Perl_croak(aTHX_ "Usage: signal(npc_id[,wait_ms])"); + Perl_croak(aTHX_ "Usage: quest::signal(int npc_id, [int wait_ms])"); } XSRETURN_EMPTY; } XS(XS__setglobal); -XS(XS__setglobal) -{ +XS(XS__setglobal) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: setglobal(key, str_value, options, duration)"); + Perl_croak(aTHX_ "Usage: quest::setglobal(stirng key, string value, int options, string duration)"); - char * key = (char *)SvPV_nolen(ST(0)); - char * str_value = (char *)SvPV_nolen(ST(1)); - int options = (int)SvIV(ST(2)); - char * duration = (char *)SvPV_nolen(ST(3)); + char *key = (char *) SvPV_nolen(ST(0)); + char *str_value = (char *) SvPV_nolen(ST(1)); + int options = (int) SvIV(ST(2)); + char *duration = (char *) SvPV_nolen(ST(3)); quest_manager.setglobal(key, str_value, options, duration); @@ -1278,18 +1214,18 @@ XS(XS__setglobal) } XS(XS__targlobal); -XS(XS__targlobal) -{ +XS(XS__targlobal) { dXSARGS; if (items != 6) - Perl_croak(aTHX_ "Usage: targlobal(key, str_value, duration, npc_id, char_id, zone_id)"); + Perl_croak(aTHX_ + "Usage: quest::targlobal(stirng key, string value, string duration, int npc_id, int chararacter_id, int zone_id)"); - char * key = (char *)SvPV_nolen(ST(0)); - char * str_value = (char *)SvPV_nolen(ST(1)); - char * duration = (char *)SvPV_nolen(ST(2)); - int npc_id = (int)SvIV(ST(3)); - int char_id = (int)SvIV(ST(4)); - int zone_id = (int)SvIV(ST(5)); + char *key = (char *) SvPV_nolen(ST(0)); + char *str_value = (char *) SvPV_nolen(ST(1)); + char *duration = (char *) SvPV_nolen(ST(2)); + int npc_id = (int) SvIV(ST(3)); + int char_id = (int) SvIV(ST(4)); + int zone_id = (int) SvIV(ST(5)); quest_manager.targlobal(key, str_value, duration, npc_id, char_id, zone_id); @@ -1297,13 +1233,12 @@ XS(XS__targlobal) } XS(XS__delglobal); -XS(XS__delglobal) -{ +XS(XS__delglobal) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: delglobal(key)"); + Perl_croak(aTHX_ "Usage: quest::delglobal(string key)"); - char * key = (char *)SvPV_nolen(ST(0)); + char *key = (char *) SvPV_nolen(ST(0)); quest_manager.delglobal(key); @@ -1311,11 +1246,10 @@ XS(XS__delglobal) } XS(XS__ding); -XS(XS__ding) -{ +XS(XS__ding) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: ding()"); + Perl_croak(aTHX_ "Usage: quest::ding()"); quest_manager.ding(); @@ -1324,14 +1258,13 @@ XS(XS__ding) } XS(XS__rebind); -XS(XS__rebind) -{ +XS(XS__rebind) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: rebind(zone_id, x, y, z)"); + Perl_croak(aTHX_ "Usage: quest::rebind(int zone_id, float x, float y, float z)"); - int zone_id = (int)SvIV(ST(0)); - auto location = glm::vec3((float)SvNV(ST(1)),(float)SvNV(ST(2)),(float)SvNV(ST(3))); + int zone_id = (int) SvIV(ST(0)); + auto location = glm::vec3((float) SvNV(ST(1)), (float) SvNV(ST(2)), (float) SvNV(ST(3))); quest_manager.rebind(zone_id, location); @@ -1339,13 +1272,12 @@ XS(XS__rebind) } XS(XS__start); -XS(XS__start) -{ +XS(XS__start) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: start(wp)"); + Perl_croak(aTHX_ "Usage: quest::start(int waypoint)"); - int wp = (int)SvIV(ST(0)); + int wp = (int) SvIV(ST(0)); quest_manager.start(wp); @@ -1353,11 +1285,10 @@ XS(XS__start) } XS(XS__stop); -XS(XS__stop) -{ +XS(XS__stop) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: stop()"); + Perl_croak(aTHX_ "Usage: quest::stop()"); quest_manager.stop(); @@ -1366,13 +1297,12 @@ XS(XS__stop) } XS(XS__pause); -XS(XS__pause) -{ +XS(XS__pause) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: pause(duration)"); + Perl_croak(aTHX_ "Usage: quest::pause(int duration-ms)"); - int duration = (int)SvIV(ST(0)); + int duration = (int) SvIV(ST(0)); quest_manager.pause(duration); @@ -1380,25 +1310,25 @@ XS(XS__pause) } XS(XS__moveto); -XS(XS__moveto) -{ +XS(XS__moveto) { dXSARGS; if (items != 3 && items != 4 && items != 5) - Perl_croak(aTHX_ "Usage: moveto(x, y, z, [heading], [saveguard?])"); + Perl_croak(aTHX_ + "Usage: quest::moveto(float x, float y, float z, [float heading], [bool save_guard_location])"); - float x = (float)SvNV(ST(0)); - float y = (float)SvNV(ST(1)); - float z = (float)SvNV(ST(2)); - float h; - bool saveguard; + float x = (float) SvNV(ST(0)); + float y = (float) SvNV(ST(1)); + float z = (float) SvNV(ST(2)); + float h; + bool saveguard; - if(items > 3) - h = (float)SvNV(ST(3)); + if (items > 3) + h = (float) SvNV(ST(3)); else h = 0; - if(items > 4) - saveguard = (bool)SvTRUE(ST(4)); + if (items > 4) + saveguard = (bool) SvTRUE(ST(4)); else saveguard = false; @@ -1408,11 +1338,10 @@ XS(XS__moveto) } XS(XS__resume); -XS(XS__resume) -{ +XS(XS__resume) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: resume()"); + Perl_croak(aTHX_ "Usage: quest::resume()"); quest_manager.resume(); @@ -1421,14 +1350,13 @@ XS(XS__resume) } XS(XS__addldonpoints); -XS(XS__addldonpoints) -{ +XS(XS__addldonpoints) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: addldonpoints(points, theme_id)"); + Perl_croak(aTHX_ "Usage: quest::addldonpoints(int points, int theme_id)"); - long points = (long)SvIV(ST(0)); - unsigned long theme_id = (unsigned long)SvUV(ST(1)); + long points = (long) SvIV(ST(0)); + unsigned long theme_id = (unsigned long) SvUV(ST(1)); quest_manager.addldonpoints(points, theme_id); @@ -1436,14 +1364,13 @@ XS(XS__addldonpoints) } XS(XS__addldonwin); -XS(XS__addldonwin) -{ +XS(XS__addldonwin) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: addldonwin(wins, theme_id)"); + Perl_croak(aTHX_ "Usage: quest::addldonwin(int wins, int theme_id)"); - long wins = (long)SvIV(ST(0)); - unsigned long theme_id = (unsigned long)SvUV(ST(1)); + long wins = (long) SvIV(ST(0)); + unsigned long theme_id = (unsigned long) SvUV(ST(1)); quest_manager.addldonwin(wins, theme_id); @@ -1451,14 +1378,13 @@ XS(XS__addldonwin) } XS(XS__addldonloss); -XS(XS__addldonloss) -{ +XS(XS__addldonloss) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: addldonloss(losses, theme_id)"); + Perl_croak(aTHX_ "Usage: quest::addldonloss(int losses, int theme_id)"); - long losses = (long)SvIV(ST(0)); - unsigned long theme_id = (unsigned long)SvUV(ST(1)); + long losses = (long) SvIV(ST(0)); + unsigned long theme_id = (unsigned long) SvUV(ST(1)); quest_manager.addldonloss(losses, theme_id); @@ -1466,13 +1392,12 @@ XS(XS__addldonloss) } XS(XS__setnexthpevent); -XS(XS__setnexthpevent) -{ +XS(XS__setnexthpevent) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: setnexthpevent(at)"); + Perl_croak(aTHX_ "Usage: quest::setnexthpevent(int at_mob_percentage)"); - int at = (int)SvIV(ST(0)); + int at = (int) SvIV(ST(0)); quest_manager.setnexthpevent(at); @@ -1480,13 +1405,12 @@ XS(XS__setnexthpevent) } XS(XS__setnextinchpevent); -XS(XS__setnextinchpevent) -{ +XS(XS__setnextinchpevent) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: setnextinchpevent(at)"); + Perl_croak(aTHX_ "Usage: quest::setnextinchpevent(int at_mob_percentage)"); - int at = (int)SvIV(ST(0)); + int at = (int) SvIV(ST(0)); quest_manager.setnextinchpevent(at); @@ -1494,13 +1418,12 @@ XS(XS__setnextinchpevent) } XS(XS__sethp); -XS(XS__sethp) -{ +XS(XS__sethp) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: sethp(percentage)"); + Perl_croak(aTHX_ "Usage: quest::sethp(int mob_health_percentage [0-100])"); - int hpperc = (int)SvIV(ST(0)); + int hpperc = (int) SvIV(ST(0)); quest_manager.sethp(hpperc); @@ -1508,14 +1431,13 @@ XS(XS__sethp) } XS(XS__respawn); -XS(XS__respawn) -{ +XS(XS__respawn) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: respawn(npc_type_id, grid_id)"); + Perl_croak(aTHX_ "Usage: quest::respawn(int npc_type_id, int grid_id)"); - int npc_type_id = (int)SvIV(ST(0)); - int grid_id = (int)SvIV(ST(1)); + int npc_type_id = (int) SvIV(ST(0)); + int grid_id = (int) SvIV(ST(1)); quest_manager.respawn(npc_type_id, grid_id); @@ -1523,41 +1445,40 @@ XS(XS__respawn) } XS(XS__ChooseRandom); -XS(XS__ChooseRandom) -{ +XS(XS__ChooseRandom) { dXSARGS; if (items < 1) - Perl_croak(aTHX_ "Usage: ChooseRandom(... list ...)"); + Perl_croak(aTHX_ "Usage: quest::ChooseRandom(option1, option2, option3, option4, option5...[no limit])"); - int index = zone->random.Int(0, items-1); + int index = zone->random.Int(0, items - 1); SV *tmp = ST(0); - ST(0) = ST(index); + ST(0) = ST(index); ST(index) = tmp; - XSRETURN(1); //return 1 element from the stack (ST(0)) + XSRETURN(1); //return 1 element from the stack (ST(0)) } XS(XS__set_proximity); -XS(XS__set_proximity) -{ +XS(XS__set_proximity) { dXSARGS; if (items != 4 && items != 6 && items != 7) - Perl_croak(aTHX_ "Usage: set_proximity(min_x, max_x, min_y, max_y [, min_z, max_z], [say])"); + Perl_croak(aTHX_ + "Usage: quest::set_proximity(float min_x, float max_x, float min_y, float max_y, [float min_z], [float max_z], [say])"); - float min_x = (float)SvNV(ST(0)); - float max_x = (float)SvNV(ST(1)); - float min_y = (float)SvNV(ST(2)); - float max_y = (float)SvNV(ST(3)); + float min_x = (float) SvNV(ST(0)); + float max_x = (float) SvNV(ST(1)); + float min_y = (float) SvNV(ST(2)); + float max_y = (float) SvNV(ST(3)); - if(items == 4) + if (items == 4) quest_manager.set_proximity(min_x, max_x, min_y, max_y); else { - float min_z = (float)SvNV(ST(4)); - float max_z = (float)SvNV(ST(5)); - bool bSay = false; + float min_z = (float) SvNV(ST(4)); + float max_z = (float) SvNV(ST(5)); + bool bSay = false; if (items == 7) - bSay = (bool)SvTRUE(ST(6)); + bSay = (bool) SvTRUE(ST(6)); quest_manager.set_proximity(min_x, max_x, min_y, max_y, min_z, max_z, bSay); } @@ -1565,11 +1486,10 @@ XS(XS__set_proximity) } XS(XS__clear_proximity); -XS(XS__clear_proximity) -{ +XS(XS__clear_proximity) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: clear_proximity()"); + Perl_croak(aTHX_ "Usage: quest::clear_proximity()"); quest_manager.clear_proximity(); @@ -1577,11 +1497,10 @@ XS(XS__clear_proximity) } XS(XS__enable_proximity_say); -XS(XS__enable_proximity_say) -{ +XS(XS__enable_proximity_say) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: enable_proximity_say()"); + Perl_croak(aTHX_ "Usage: quest::enable_proximity_say()"); quest_manager.enable_proximity_say(); @@ -1589,11 +1508,10 @@ XS(XS__enable_proximity_say) } XS(XS__disable_proximity_say); -XS(XS__disable_proximity_say) -{ +XS(XS__disable_proximity_say) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: disable_proximity_say()"); + Perl_croak(aTHX_ "Usage: quest::disable_proximity_say()"); quest_manager.disable_proximity_say(); @@ -1604,8 +1522,8 @@ XS(XS__setanim); XS(XS__setanim) //Cisyouc: mob->setappearance() addition { dXSARGS; - if(items != 2) - Perl_croak(aTHX_ "Usage: quest::setanim(npc_type_id, anim_num);"); + if (items != 2) + Perl_croak(aTHX_ "Usage: quest::setanim(int npc_type_id, int appearance_number[0-4]);"); quest_manager.setanim(SvUV(ST(0)), SvUV(ST(1))); @@ -1613,11 +1531,10 @@ XS(XS__setanim) //Cisyouc: mob->setappearance() addition } XS(XS__showgrid); -XS(XS__showgrid) -{ +XS(XS__showgrid) { dXSARGS; - if(items != 1) - Perl_croak(aTHX_ "Usage: quest::showgrid(grid_id);"); + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::showgrid(int grid_id);"); quest_manager.showgrid(SvUV(ST(0))); @@ -1625,26 +1542,23 @@ XS(XS__showgrid) } XS(XS__spawn_condition); -XS(XS__spawn_condition) -{ +XS(XS__spawn_condition) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: spawn_condition(zone_short, [instance_id], condition_id, int_value)"); + Perl_croak(aTHX_ + "Usage: quest::spawn_condition(string zone_short, [int instance_id], uint16 condition_id, int16 value)"); - if(items == 3) - { - char * zone_short = (char *)SvPV_nolen(ST(0)); - uint16 condition_id = (int)SvUV(ST(1)); - int16 int_value = (int)SvIV(ST(2)); + if (items == 3) { + char *zone_short = (char *) SvPV_nolen(ST(0)); + uint16 condition_id = (int) SvUV(ST(1)); + int16 int_value = (int) SvIV(ST(2)); quest_manager.spawn_condition(zone_short, zone->GetInstanceID(), condition_id, int_value); - } - else - { - char * zone_short = (char *)SvPV_nolen(ST(0)); - uint32 instance_id = (int)SvUV(ST(1)); - uint16 condition_id = (int)SvUV(ST(2)); - int16 int_value = (int)SvIV(ST(3)); + } else { + char *zone_short = (char *) SvPV_nolen(ST(0)); + uint32 instance_id = (int) SvUV(ST(1)); + uint16 condition_id = (int) SvUV(ST(2)); + int16 int_value = (int) SvIV(ST(3)); quest_manager.spawn_condition(zone_short, instance_id, condition_id, int_value); } @@ -1652,52 +1566,50 @@ XS(XS__spawn_condition) } XS(XS__get_spawn_condition); -XS(XS__get_spawn_condition) -{ +XS(XS__get_spawn_condition) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: get_spawn_condition(zone_short, [instance_id], condition_id)"); + Perl_croak(aTHX_ "Usage: quest::get_spawn_condition(string zone_short, [int instance_id], int condition_id)"); - if(items == 2) - { - int16 RETVAL; + if (items == 2) { + int16 RETVAL; dXSTARG; - char * zone_short = (char *)SvPV_nolen(ST(0)); - uint16 cond_id = (int)SvIV(ST(1)); + char *zone_short = (char *) SvPV_nolen(ST(0)); + uint16 cond_id = (int) SvIV(ST(1)); RETVAL = quest_manager.get_spawn_condition(zone_short, zone->GetInstanceID(), cond_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); - } - else - { - int16 RETVAL; + } else { + int16 RETVAL; dXSTARG; - char * zone_short = (char *)SvPV_nolen(ST(0)); - uint16 instance_id = (int)SvIV(ST(1)); - uint16 cond_id = (int)SvIV(ST(2)); + char *zone_short = (char *) SvPV_nolen(ST(0)); + uint16 instance_id = (int) SvIV(ST(1)); + uint16 cond_id = (int) SvIV(ST(2)); RETVAL = quest_manager.get_spawn_condition(zone_short, instance_id, cond_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } } XS(XS__toggle_spawn_event); -XS(XS__toggle_spawn_event) -{ +XS(XS__toggle_spawn_event) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: toggle_spawn_event(event_id, is_enabled, is_strict, reset_base)"); + Perl_croak(aTHX_ + "Usage: quest::toggle_spawn_event(uint32 event_id, [bool is_enabled = false], [bool is_strict = false], [bool reset_base = false])"); - uint32 event_id = (int)SvIV(ST(0)); - bool is_enabled = ((int)SvIV(ST(1))) == 0?false:true; - bool is_strict = ((int)SvIV(ST(2))) == 0?false:true; - bool reset_base = ((int)SvIV(ST(3))) == 0?false:true; + uint32 event_id = (int) SvIV(ST(0)); + bool is_enabled = ((int) SvIV(ST(1))) == 0 ? false : true; + bool is_strict = ((int) SvIV(ST(2))) == 0 ? false : true; + bool reset_base = ((int) SvIV(ST(3))) == 0 ? false : true; quest_manager.toggle_spawn_event(event_id, is_enabled, is_strict, reset_base); @@ -1705,32 +1617,31 @@ XS(XS__toggle_spawn_event) } XS(XS__has_zone_flag); -XS(XS__has_zone_flag) -{ +XS(XS__has_zone_flag) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: has_zone_flag(zone_id)"); + Perl_croak(aTHX_ "Usage: quest::has_zone_flag(uint32 zone_id)"); - int16 RETVAL; + int16 RETVAL; dXSTARG; - uint32 zone_id = (int)SvIV(ST(0)); + uint32 zone_id = (int) SvIV(ST(0)); RETVAL = quest_manager.has_zone_flag(zone_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__set_zone_flag); -XS(XS__set_zone_flag) -{ +XS(XS__set_zone_flag) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: set_zone_flag(zone_id)"); + Perl_croak(aTHX_ "Usage: quest::set_zone_flag(uint32 zone_id)"); - uint32 zone_id = (int)SvIV(ST(0)); + uint32 zone_id = (int) SvIV(ST(0)); quest_manager.set_zone_flag(zone_id); @@ -1738,13 +1649,12 @@ XS(XS__set_zone_flag) } XS(XS__clear_zone_flag); -XS(XS__clear_zone_flag) -{ +XS(XS__clear_zone_flag) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: clear_zone_flag(zone_id)"); + Perl_croak(aTHX_ "Usage: quest::clear_zone_flag(uint32 zone_id)"); - uint32 zone_id = (int)SvIV(ST(0)); + uint32 zone_id = (int) SvIV(ST(0)); quest_manager.clear_zone_flag(zone_id); @@ -1752,137 +1662,128 @@ XS(XS__clear_zone_flag) } XS(XS__summonburiedplayercorpse); -XS(XS__summonburiedplayercorpse) -{ +XS(XS__summonburiedplayercorpse) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: summonburiedplayercorpse(char_id,dest_x,dest_y,dest_z,dest_heading)"); + Perl_croak(aTHX_ + "Usage: quest::summonburiedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading)"); - bool RETVAL; - uint32 char_id = (int)SvIV(ST(0)); - auto position = glm::vec4((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4))); + bool RETVAL; + uint32 char_id = (int) SvIV(ST(0)); + auto position = glm::vec4((float) SvIV(ST(1)), (float) SvIV(ST(2)), (float) SvIV(ST(3)), (float) SvIV(ST(4))); RETVAL = quest_manager.summonburiedplayercorpse(char_id, position); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); XSRETURN(1); } XS(XS__summonallplayercorpses); -XS(XS__summonallplayercorpses) -{ +XS(XS__summonallplayercorpses) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: summonallplayercorpses(char_id,dest_x,dest_y,dest_z,dest_heading)"); + Perl_croak(aTHX_ + "Usage: quest::summonallplayercorpses(int char_id, float dest_x, float dest_y, float dest_z, float dest_heading)"); - bool RETVAL; - uint32 char_id = (int)SvIV(ST(0)); - auto position = glm::vec4((float)SvIV(ST(1)),(float)SvIV(ST(2)),(float)SvIV(ST(3)),(float)SvIV(ST(4))); + bool RETVAL; + uint32 char_id = (int) SvIV(ST(0)); + auto position = glm::vec4((float) SvIV(ST(1)), (float) SvIV(ST(2)), (float) SvIV(ST(3)), (float) SvIV(ST(4))); RETVAL = quest_manager.summonallplayercorpses(char_id, position); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); XSRETURN(1); } XS(XS__getplayerburiedcorpsecount); -XS(XS__getplayerburiedcorpsecount) -{ +XS(XS__getplayerburiedcorpsecount) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: getplayerburiedcorpsecount(char_id)"); + Perl_croak(aTHX_ "Usage: quest::getplayerburiedcorpsecount(int character_id)"); - uint32 RETVAL; + uint32 RETVAL; dXSTARG; - uint32 char_id = (int)SvIV(ST(0)); + uint32 char_id = (int) SvIV(ST(0)); RETVAL = quest_manager.getplayerburiedcorpsecount(char_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__buryplayercorpse); -XS(XS__buryplayercorpse) -{ +XS(XS__buryplayercorpse) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: buryplayercorpse(char_id)"); + Perl_croak(aTHX_ "Usage: quest::buryplayercorpse(int character_id)"); - uint32 RETVAL; + uint32 RETVAL; dXSTARG; - uint32 char_id = (int)SvIV(ST(0)); + uint32 char_id = (int) SvIV(ST(0)); RETVAL = quest_manager.buryplayercorpse(char_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__forcedooropen); -XS(XS__forcedooropen) -{ +XS(XS__forcedooropen) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: forcedooropen(door_id, [alt_mode=0])"); + Perl_croak(aTHX_ "Usage: quest::forcedooropen(int door_id, [int alt_mode=0])"); - if (items == 1) - { - uint32 door_id = (int)SvIV(ST(0)); + if (items == 1) { + uint32 door_id = (int) SvIV(ST(0)); - quest_manager.forcedooropen(door_id, false); + quest_manager.forcedooropen(door_id, false); - XSRETURN_EMPTY; - } - else - { - uint32 door_id = (int)SvIV(ST(0)); - bool alt_mode = (int)SvIV(ST(1)) == 0?false:true; + XSRETURN_EMPTY; + } else { + uint32 door_id = (int) SvIV(ST(0)); + bool alt_mode = (int) SvIV(ST(1)) == 0 ? false : true; - quest_manager.forcedooropen(door_id, alt_mode); + quest_manager.forcedooropen(door_id, alt_mode); - XSRETURN_EMPTY; + XSRETURN_EMPTY; } } XS(XS__forcedoorclose); -XS(XS__forcedoorclose) -{ +XS(XS__forcedoorclose) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: forcedoorclose(door_id, [alt_mode=0])"); + Perl_croak(aTHX_ "Usage: quest::forcedoorclose(int door_id, [bool alt_mode = 0])"); - if (items == 1) - { - uint32 door_id = (int)SvIV(ST(0)); + if (items == 1) { + uint32 door_id = (int) SvIV(ST(0)); - quest_manager.forcedoorclose(door_id, false); + quest_manager.forcedoorclose(door_id, false); - XSRETURN_EMPTY; - } - else - { - uint32 door_id = (int)SvIV(ST(0)); - bool alt_mode = (int)SvIV(ST(1)) == 0?false:true; + XSRETURN_EMPTY; + } else { + uint32 door_id = (int) SvIV(ST(0)); + bool alt_mode = (int) SvIV(ST(1)) == 0 ? false : true; - quest_manager.forcedoorclose(door_id, alt_mode); + quest_manager.forcedoorclose(door_id, alt_mode); - XSRETURN_EMPTY; + XSRETURN_EMPTY; } } XS(XS__toggledoorstate); -XS(XS__toggledoorstate) -{ +XS(XS__toggledoorstate) { dXSARGS; - if (items !=1) - Perl_croak(aTHX_ "Usage: toggledoorstate(door_id)"); + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::toggledoorstate(int door_id)"); - uint32 door_id = (int)SvIV(ST(0)); + uint32 door_id = (int) SvIV(ST(0)); quest_manager.toggledoorstate(door_id); @@ -1890,31 +1791,30 @@ XS(XS__toggledoorstate) } XS(XS__isdooropen); -XS(XS__isdooropen) -{ +XS(XS__isdooropen) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: isdooropen(door_id)"); + Perl_croak(aTHX_ "Usage: quest::isdooropen(int door_id)"); - bool RETVAL; + bool RETVAL; dXSTARG; - uint32 door_id = (int)SvIV(ST(0)); + uint32 door_id = (int) SvIV(ST(0)); RETVAL = quest_manager.isdooropen(door_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__depopzone); -XS(XS__depopzone) -{ +XS(XS__depopzone) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: depopzone(StartSpawnStatus)"); + Perl_croak(aTHX_ "Usage: quest::depopzone([bool start_spawn_status = false])"); - bool StartSpawnStatus = ((int)SvIV(ST(0))) == 0?false:true; + bool StartSpawnStatus = ((int) SvIV(ST(0))) == 0 ? false : true; quest_manager.depopzone(StartSpawnStatus); @@ -1922,71 +1822,23 @@ XS(XS__depopzone) } XS(XS__repopzone); -XS(XS__repopzone) -{ +XS(XS__repopzone) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: repopzone()"); + Perl_croak(aTHX_ "Usage: quest::repopzone()"); quest_manager.repopzone(); XSRETURN_EMPTY; } -XS(XS__ConnectNodeToNode); -XS(XS__ConnectNodeToNode) -{ - dXSARGS; - if (items != 4) - Perl_croak(aTHX_ "Usage: ConnectNodeToNode(node1, node2, teleport, doorid)"); - - int node1 = (int)SvIV(ST(0)); - int node2 = (int)SvIV(ST(1)); - int teleport = (int)SvIV(ST(2)); - int doorid = (int)SvIV(ST(3)); - - quest_manager.ConnectNodeToNode(node1, node2, teleport, doorid); - - XSRETURN_EMPTY; -} - -XS(XS__AddNode); -XS(XS__AddNode) -{ - dXSARGS; - //void QuestManager::AddNode(float x, float y, float z, float best_z, int32 requested_id); - if (items < 3 || items > 5) - Perl_croak(aTHX_ "Usage: AddNode(x, y, z, [best_z], [requested_id])"); - - float x = (float)SvNV(ST(0)); - float y = (float)SvNV(ST(1)); - float z = (float)SvNV(ST(2)); - int best_z = 0; - int requested_id = 0; - - if (items == 4) - { - best_z = (float)SvNV(ST(3)); - } - else if (items == 5) - { - best_z = (float)SvNV(ST(3)); - requested_id = (int)SvIV(ST(4)); - } - - quest_manager.AddNode(x, y, z, best_z, requested_id); - - XSRETURN_EMPTY; -} - XS(XS__npcrace); -XS(XS__npcrace) -{ +XS(XS__npcrace) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: npcrace(race_id)"); + Perl_croak(aTHX_ "Usage: quest::npcrace(int race_id)"); - int race_id = (int)SvIV(ST(0)); + int race_id = (int) SvIV(ST(0)); quest_manager.npcrace(race_id); @@ -1994,13 +1846,12 @@ XS(XS__npcrace) } XS(XS__npcgender); -XS(XS__npcgender) -{ +XS(XS__npcgender) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: npcgender(gender_id)"); + Perl_croak(aTHX_ "Usage: quest::npcgender(int gender_id)"); - int gender_id= (int)SvIV(ST(0)); + int gender_id = (int) SvIV(ST(0)); quest_manager.npcgender(gender_id); @@ -2008,13 +1859,12 @@ XS(XS__npcgender) } XS(XS__npcsize); -XS(XS__npcsize) -{ +XS(XS__npcsize) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: npcsize(size)"); + Perl_croak(aTHX_ "Usage: quest::npcsize(int size)"); - int size = (int)SvIV(ST(0)); + int size = (int) SvIV(ST(0)); quest_manager.npcsize(size); @@ -2022,13 +1872,12 @@ XS(XS__npcsize) } XS(XS__npctexture); -XS(XS__npctexture) -{ +XS(XS__npctexture) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: npctexture(texture_id)"); + Perl_croak(aTHX_ "Usage: quest::npctexture(int texture_id)"); - int texture_id = (int)SvIV(ST(0)); + int texture_id = (int) SvIV(ST(0)); quest_manager.npctexture(texture_id); @@ -2036,13 +1885,12 @@ XS(XS__npctexture) } XS(XS__playerrace); -XS(XS__playerrace) -{ +XS(XS__playerrace) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: playerrace(race_id)"); + Perl_croak(aTHX_ "Usage: quest::playerrace(int race_id)"); - int race_id = (int)SvIV(ST(0)); + int race_id = (int) SvIV(ST(0)); quest_manager.playerrace(race_id); @@ -2050,13 +1898,12 @@ XS(XS__playerrace) } XS(XS__playergender); -XS(XS__playergender) -{ +XS(XS__playergender) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: playergender(gender_id)"); + Perl_croak(aTHX_ "Usage: quest::playergender(int gender_id)"); - int gender_id= (int)SvIV(ST(0)); + int gender_id = (int) SvIV(ST(0)); quest_manager.playergender(gender_id); @@ -2064,13 +1911,12 @@ XS(XS__playergender) } XS(XS__playersize); -XS(XS__playersize) -{ +XS(XS__playersize) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: playersize(newsize)"); + Perl_croak(aTHX_ "Usage: quest::playersize(int newsize)"); - int newsize = (int)SvIV(ST(0)); + int newsize = (int) SvIV(ST(0)); quest_manager.playersize(newsize); @@ -2078,13 +1924,12 @@ XS(XS__playersize) } XS(XS__playertexture); -XS(XS__playertexture) -{ +XS(XS__playertexture) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: playertexture(texture_id)"); + Perl_croak(aTHX_ "Usage: quest::playertexture(int texture_id)"); - int texture_id = (int)SvIV(ST(0)); + int texture_id = (int) SvIV(ST(0)); quest_manager.playertexture(texture_id); @@ -2092,14 +1937,14 @@ XS(XS__playertexture) } XS(XS__playerfeature); -XS(XS__playerfeature) -{ +XS(XS__playerfeature) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: playerfeature(str_value, int_value)"); + Perl_croak(aTHX_ + "Usage: quest::playerfeature(string feature [race|gender|texture|helm|haircolor|beardcolor|eyecolor1|eyecolor2|hair|face|beard|heritage|tatoo|details|size], int setting)"); - char * str_value = (char *)SvPV_nolen(ST(0)); - int int_value = (int)SvIV(ST(1)); + char *str_value = (char *) SvPV_nolen(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.playerfeature(str_value, int_value); @@ -2107,14 +1952,14 @@ XS(XS__playerfeature) } XS(XS__npcfeature); -XS(XS__npcfeature) -{ +XS(XS__npcfeature) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: npcfeature(str_value, int_value)"); + Perl_croak(aTHX_ + "Usage: quest::npcfeature(string feature [race|gender|texture|helm|haircolor|beardcolor|eyecolor1|eyecolor2|hair|face|beard|heritage|tatoo|details|size], int value)"); - char * str_value = (char *)SvPV_nolen(ST(0)); - int int_value = (int)SvIV(ST(1)); + char *str_value = (char *) SvPV_nolen(ST(0)); + int int_value = (int) SvIV(ST(1)); quest_manager.npcfeature(str_value, int_value); @@ -2171,7 +2016,7 @@ XS(XS__createBot) if(items != 6) { - Perl_croak(aTHX_ "Usage: createBot(firstname, lastname, level, race_id, class_id, gender_id)"); + Perl_croak(aTHX_ "Usage: quest::createBot(string first_name, string last_name, int level, int race_id, int class_id, int gender_id)"); } char *firstname = (char *)SvPV_nolen(ST(0)); @@ -2189,477 +2034,466 @@ XS(XS__createBot) #endif //BOTS XS(XS__taskselector); -XS(XS__taskselector) -{ +XS(XS__taskselector) { dXSARGS; - if((items >= 1) && (items <=MAXCHOOSERENTRIES)) { - int tasks[MAXCHOOSERENTRIES]; - for(int i=0; i< items; i++) { - tasks[i] = (int)SvIV(ST(i)); + if ((items >= 1) && (items <= MAXCHOOSERENTRIES)) { + int tasks[MAXCHOOSERENTRIES]; + for (int i = 0; i < items; i++) { + tasks[i] = (int) SvIV(ST(i)); } quest_manager.taskselector(items, tasks); } else { - Perl_croak(aTHX_ "Usage: taskselector(task_id1, task_id2, ..., task_id%i)", MAXCHOOSERENTRIES); + Perl_croak(aTHX_ "Usage: quest::taskselector(int task_id, 2, 3, 4, 5 [up to 40])"); } XSRETURN_EMPTY; } XS(XS__task_setselector); -XS(XS__task_setselector) -{ +XS(XS__task_setselector) { dXSARGS; - if(items == 1) { - int task_setid = (int)SvIV(ST(0)); + if (items == 1) { + int task_setid = (int) SvIV(ST(0)); quest_manager.tasksetselector(task_setid); } else { - Perl_croak(aTHX_ "Usage: task_setselector(task_setid)"); + Perl_croak(aTHX_ "Usage: quest::task_setselector(int task_set_id)"); } XSRETURN_EMPTY; } XS(XS__enabletask); -XS(XS__enabletask) -{ +XS(XS__enabletask) { dXSARGS; - if((items >= 1) && (items <=10)) { - int tasks[10]; - for(int i=0; i< items; i++) { - tasks[i] = (int)SvIV(ST(i)); + if ((items >= 1) && (items <= 10)) { + int tasks[10]; + for (int i = 0; i < items; i++) { + tasks[i] = (int) SvIV(ST(i)); } quest_manager.enabletask(items, tasks); } else { - Perl_croak(aTHX_ "Usage: enabletask(task_id1, task_id2, ..., task_id10"); + Perl_croak(aTHX_ "Usage: quest::enabletask(int task_id, 2, 3, [up to 10])"); } XSRETURN_EMPTY; } XS(XS__disabletask); -XS(XS__disabletask) -{ +XS(XS__disabletask) { dXSARGS; - if((items >= 1) && (items <=10)) { - int tasks[10]; - for(int i=0; i< items; i++) { - tasks[i] = (int)SvIV(ST(i)); + if ((items >= 1) && (items <= 10)) { + int tasks[10]; + for (int i = 0; i < items; i++) { + tasks[i] = (int) SvIV(ST(i)); } quest_manager.disabletask(items, tasks); } else { - Perl_croak(aTHX_ "Usage: disabletask(task_id1, task_id2, ..., task_id10"); + Perl_croak(aTHX_ "Usage: quest::disabletask(int task_id, 2, 3, [up to 10])"); } XSRETURN_EMPTY; } XS(XS__istaskenabled); -XS(XS__istaskenabled) -{ +XS(XS__istaskenabled) { dXSARGS; - bool RETVAL; + bool RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_id = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_id = (int) SvIV(ST(0)); RETVAL = quest_manager.istaskenabled(task_id); } else { - Perl_croak(aTHX_ "Usage: istaskenabled(task_id)"); + Perl_croak(aTHX_ "Usage: quest::istaskenabled(int task_id)"); } - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__istaskactive); -XS(XS__istaskactive) -{ +XS(XS__istaskactive) { dXSARGS; - bool RETVAL; + bool RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_id = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_id = (int) SvIV(ST(0)); RETVAL = quest_manager.istaskactive(task_id); } else { - Perl_croak(aTHX_ "Usage: istaskactive(task_id)"); + Perl_croak(aTHX_ "Usage: quest::istaskactive(int task_id)"); } - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__istaskactivityactive); -XS(XS__istaskactivityactive) -{ +XS(XS__istaskactivityactive) { dXSARGS; - bool RETVAL; + bool RETVAL; dXSTARG; - if(items == 2) { - unsigned int task_id = (int)SvIV(ST(0)); - unsigned int activity_id = (int)SvIV(ST(1)); + if (items == 2) { + unsigned int task_id = (int) SvIV(ST(0)); + unsigned int activity_id = (int) SvIV(ST(1)); RETVAL = quest_manager.istaskactivityactive(task_id, activity_id); } else { - Perl_croak(aTHX_ "Usage: istaskactivityactive(task_id, activity_id)"); + Perl_croak(aTHX_ "Usage: quest::istaskactivityactive(int task_id, int activity_id)"); } - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__gettaskactivitydonecount); -XS(XS__gettaskactivitydonecount) -{ +XS(XS__gettaskactivitydonecount) { dXSARGS; - uint32 RETVAL; + uint32 RETVAL; dXSTARG; - if(items == 2) { - unsigned int task_id = (int)SvIV(ST(0)); - unsigned int activity_id = (int)SvIV(ST(1)); + if (items == 2) { + unsigned int task_id = (int) SvIV(ST(0)); + unsigned int activity_id = (int) SvIV(ST(1)); RETVAL = quest_manager.gettaskactivitydonecount(task_id, activity_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } else { - Perl_croak(aTHX_ "Usage: gettaskactivitydonecount(task_id, activity_id)"); + Perl_croak(aTHX_ "Usage: quest::gettaskactivitydonecount(int task_id, int activity_id)"); } XSRETURN(1); } XS(XS__updatetaskactivity); -XS(XS__updatetaskactivity) -{ +XS(XS__updatetaskactivity) { dXSARGS; unsigned int task_id, activity_id; - int count = 1; - bool ignore_quest_update = false; - if(items == 2) { - task_id = (int)SvIV(ST(0)); - activity_id = (int)SvIV(ST(1)); + int count = 1; + bool ignore_quest_update = false; + if (items == 2) { + task_id = (int) SvIV(ST(0)); + activity_id = (int) SvIV(ST(1)); quest_manager.updatetaskactivity(task_id, activity_id, count, false); - } - else if (items == 3 || items == 4) { - task_id = (int)SvIV(ST(0)); - activity_id = (int)SvIV(ST(1)); - count = (int)SvIV(ST(2)); - if (items == 4){ - bool ignore_quest_update = (bool)SvTRUE(ST(3)); + } else if (items == 3 || items == 4) { + task_id = (int) SvIV(ST(0)); + activity_id = (int) SvIV(ST(1)); + count = (int) SvIV(ST(2)); + if (items == 4) { + bool ignore_quest_update = (bool) SvTRUE(ST(3)); } quest_manager.updatetaskactivity(task_id, activity_id, count, ignore_quest_update); } else { - Perl_croak(aTHX_ "Usage: updatetaskactivity(task_id, activity_id, [count], [ignore_quest_update])"); + Perl_croak(aTHX_ + "Usage: quest::updatetaskactivity(int task_id, int activity_id, [int count], [bool ignore_quest_update = false])"); } XSRETURN_EMPTY; } XS(XS__resettaskactivity); -XS(XS__resettaskactivity) -{ +XS(XS__resettaskactivity) { dXSARGS; unsigned int task, activity; - if(items == 2) { - int task_id = (int)SvIV(ST(0)); - int activity_id = (int)SvIV(ST(1)); + if (items == 2) { + int task_id = (int) SvIV(ST(0)); + int activity_id = (int) SvIV(ST(1)); quest_manager.resettaskactivity(task_id, activity_id); } else { - Perl_croak(aTHX_ "Usage: resettaskactivity(task_id, activity_id)"); + Perl_croak(aTHX_ "Usage: quest::resettaskactivity(int task_id, int activity_id)"); } XSRETURN_EMPTY; } XS(XS__taskexploredarea); -XS(XS__taskexploredarea) -{ +XS(XS__taskexploredarea) { dXSARGS; unsigned int explore_id; - if(items == 1) { - explore_id = (int)SvIV(ST(0)); + if (items == 1) { + explore_id = (int) SvIV(ST(0)); quest_manager.taskexploredarea(explore_id); } else { - Perl_croak(aTHX_ "Usage: taskexplorearea(explore_id)"); + Perl_croak(aTHX_ "Usage: quest::taskexplorearea(int explore_id)"); } XSRETURN_EMPTY; } XS(XS__assigntask); -XS(XS__assigntask) -{ +XS(XS__assigntask) { dXSARGS; unsigned int task_id; - bool enforce_level_requirement = false; - if(items == 1 || items == 2) { - task_id = (int)SvIV(ST(0)); - if (items == 2) - { - if ((int)SvIV(ST(1)) == 1) - { + bool enforce_level_requirement = false; + if (items == 1 || items == 2) { + task_id = (int) SvIV(ST(0)); + if (items == 2) { + if ((int) SvIV(ST(1)) == 1) { enforce_level_requirement = true; } } quest_manager.assigntask(task_id, enforce_level_requirement); } else { - Perl_croak(aTHX_ "Usage: assigntask(task_id, enforce_level_requirement)"); + Perl_croak(aTHX_ "Usage: quest::assigntask(int task_id, [bool enforce_level_requirement = false])"); } XSRETURN_EMPTY; } XS(XS__failtask); -XS(XS__failtask) -{ +XS(XS__failtask) { dXSARGS; unsigned int task_id; - if(items == 1) { - task_id = (int)SvIV(ST(0)); + if (items == 1) { + task_id = (int) SvIV(ST(0)); quest_manager.failtask(task_id); } else { - Perl_croak(aTHX_ "Usage: failtask(task_id)"); + Perl_croak(aTHX_ "Usage: quest::failtask(int task_id)"); } XSRETURN_EMPTY; } XS(XS__tasktimeleft); -XS(XS__tasktimeleft) -{ +XS(XS__tasktimeleft) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_id = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_id = (int) SvIV(ST(0)); RETVAL = quest_manager.tasktimeleft(task_id); } else { - Perl_croak(aTHX_ "Usage: tasktimeleft(task_id)"); + Perl_croak(aTHX_ "Usage: quest::tasktimeleft(int task_id)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__istaskcompleted); -XS(XS__istaskcompleted) -{ +XS(XS__istaskcompleted) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_id = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_id = (int) SvIV(ST(0)); RETVAL = quest_manager.istaskcompleted(task_id); } else { - Perl_croak(aTHX_ "Usage: istaskcompleted(task_id)"); + Perl_croak(aTHX_ "Usage: quest::istaskcompleted(int task_id)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__enabledtaskcount); -XS(XS__enabledtaskcount) -{ +XS(XS__enabledtaskcount) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_set = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_set = (int) SvIV(ST(0)); RETVAL = quest_manager.enabledtaskcount(task_set); } else { - Perl_croak(aTHX_ "Usage: enabledtaskcount(task_set)"); + Perl_croak(aTHX_ "Usage: quest::enabledtaskcount(int task_set)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__firsttaskinset); -XS(XS__firsttaskinset) -{ +XS(XS__firsttaskinset) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_set = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_set = (int) SvIV(ST(0)); RETVAL = quest_manager.firsttaskinset(task_set); } else { - Perl_croak(aTHX_ "Usage: firsttaskinset(task_set)"); + Perl_croak(aTHX_ "Usage: quest::firsttaskinset(int task_set)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__lasttaskinset); -XS(XS__lasttaskinset) -{ +XS(XS__lasttaskinset) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_set = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_set = (int) SvIV(ST(0)); RETVAL = quest_manager.lasttaskinset(task_set); } else { - Perl_croak(aTHX_ "Usage: lasttaskinset(task_set)"); + Perl_croak(aTHX_ "Usage: quest::lasttaskinset(int task_set)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__nexttaskinset); -XS(XS__nexttaskinset) -{ +XS(XS__nexttaskinset) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 2) { - unsigned int task_set = (int)SvIV(ST(0)); - unsigned int task_id = (int)SvIV(ST(1)); + if (items == 2) { + unsigned int task_set = (int) SvIV(ST(0)); + unsigned int task_id = (int) SvIV(ST(1)); RETVAL = quest_manager.nexttaskinset(task_set, task_id); } else { - Perl_croak(aTHX_ "Usage: nexttaskinset(task_set, task_id)"); + Perl_croak(aTHX_ "Usage: quest::nexttaskinset(int task_set, int task_id)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__activespeaktask); -XS(XS__activespeaktask) -{ +XS(XS__activespeaktask) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 0) { + if (items == 0) { RETVAL = quest_manager.activespeaktask(); } else { - Perl_croak(aTHX_ "Usage: activespeaktask()"); + Perl_croak(aTHX_ "Usage: quest::activespeaktask()"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__activespeakactivity); -XS(XS__activespeakactivity) -{ +XS(XS__activespeakactivity) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_id = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_id = (int) SvIV(ST(0)); RETVAL = quest_manager.activespeakactivity(task_id); } else { - Perl_croak(aTHX_ "Usage: activespeakactivity(task_id)"); + Perl_croak(aTHX_ "Usage: quest::activespeakactivity(int task_id)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__activetasksinset); -XS(XS__activetasksinset) -{ +XS(XS__activetasksinset) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_set = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_set = (int) SvIV(ST(0)); RETVAL = quest_manager.activetasksinset(task_set); } else { - Perl_croak(aTHX_ "Usage: activetasksinset(task_set)"); + Perl_croak(aTHX_ "Usage: quest::activetasksinset(int task_set)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__completedtasksinset); -XS(XS__completedtasksinset) -{ +XS(XS__completedtasksinset) { dXSARGS; - int RETVAL; + int RETVAL; dXSTARG; - if(items == 1) { - unsigned int task_set = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task_set = (int) SvIV(ST(0)); RETVAL = quest_manager.completedtasksinset(task_set); } else { - Perl_croak(aTHX_ "Usage: completedtasksinset(task_set)"); + Perl_croak(aTHX_ "Usage: quest::completedtasksinset(int task_set)"); } - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); XSRETURN(1); } XS(XS__istaskappropriate); -XS(XS__istaskappropriate) -{ +XS(XS__istaskappropriate) { dXSARGS; - bool RETVAL; + bool RETVAL; dXSTARG; - if(items == 1) { - unsigned int task = (int)SvIV(ST(0)); + if (items == 1) { + unsigned int task = (int) SvIV(ST(0)); RETVAL = quest_manager.istaskappropriate(task); } else { - Perl_croak(aTHX_ "Usage: istaskaappropriate(task)"); + Perl_croak(aTHX_ "Usage: quest::istaskaappropriate(int task_id)"); } - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } - XS(XS__popup); // prototype to pass -Wmissing-prototypes - XS(XS__popup) { - dXSARGS; +XS(XS__popup); // prototype to pass -Wmissing-prototypes +XS(XS__popup) { + dXSARGS; int popup_id = 0; - int buttons = 0; + int buttons = 0; int duration = 0; - if((items < 2) || (items > 5)) - Perl_croak(aTHX_ "Usage: popup(window_title, message, popup_id, buttons, duration)"); + if ((items < 2) || (items > 5)) + Perl_croak(aTHX_ + "Usage: quest::popup(string window_title, string message, int popup_id, int buttons, int duration)"); - if(items >= 3) - popup_id = (int)SvIV(ST(2)); + if (items >= 3) + popup_id = (int) SvIV(ST(2)); - if(items >= 4) - buttons = (int)SvIV(ST(3)); + if (items >= 4) + buttons = (int) SvIV(ST(3)); - if(items == 5) - duration = (int)SvIV(ST(4)); + if (items == 5) + duration = (int) SvIV(ST(4)); - quest_manager.popup(SvPV_nolen(ST(0)), SvPV_nolen(ST(1)), popup_id, buttons, duration); + quest_manager.popup(SvPV_nolen(ST(0)), SvPV_nolen(ST(1)), popup_id, buttons, duration); - XSRETURN_EMPTY; + XSRETURN_EMPTY; } XS(XS__clearspawntimers); -XS(XS__clearspawntimers) -{ +XS(XS__clearspawntimers) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: clearspawntimers()"); + Perl_croak(aTHX_ "Usage: quest::clearspawntimers()"); quest_manager.clearspawntimers(); @@ -2667,14 +2501,13 @@ XS(XS__clearspawntimers) } XS(XS__ze); -XS(XS__ze) -{ +XS(XS__ze) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: ze(channel_id, message)"); + Perl_croak(aTHX_ "Usage: quest::ze(int emote_color_id, string message)"); - int channel_id = (int)SvIV(ST(0)); - char * message = (char *)SvPV_nolen(ST(1)); + int channel_id = (int) SvIV(ST(0)); + char *message = (char *) SvPV_nolen(ST(1)); quest_manager.ze(channel_id, message); @@ -2682,14 +2515,13 @@ XS(XS__ze) } XS(XS__we); -XS(XS__we) -{ +XS(XS__we) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: we(channel_id, message)"); + Perl_croak(aTHX_ "Usage: quest::we(int emote_color_id, string message)"); - int channel_id = (int)SvIV(ST(0)); - char * message = (char *)SvPV_nolen(ST(1)); + int channel_id = (int) SvIV(ST(0)); + char *message = (char *) SvPV_nolen(ST(1)); quest_manager.we(channel_id, message); @@ -2697,45 +2529,45 @@ XS(XS__we) } XS(XS__getlevel); -XS(XS__getlevel) -{ +XS(XS__getlevel) { dXSARGS; if (items > 1) - Perl_croak(aTHX_ "Usage: getlevel(type)"); + Perl_croak(aTHX_ "Usage: quest::getlevel(int type)"); - int RETVAL; + int RETVAL; dXSTARG; - int type; + int type; if (items == 1) - type = (int)SvIV(ST(0)); + type = (int) SvIV(ST(0)); else type = 0; RETVAL = quest_manager.getlevel(type); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__CreateGroundObject); -XS(XS__CreateGroundObject) -{ +XS(XS__CreateGroundObject) { dXSARGS; if (items != 5 && items != 6) - Perl_croak(aTHX_ "Usage: creategroundobject(item_id, x, y, z, heading, [decay_time])"); + Perl_croak(aTHX_ + "Usage: quest::creategroundobject(int item_id, float x, float y, float z, float heading, [uint32 decay_time-ms = 300000])"); - int item_id = (int)SvIV(ST(0)); - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float heading = (float)SvNV(ST(4)); - uint16 id = 0; + int item_id = (int) SvIV(ST(0)); + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); + float heading = (float) SvNV(ST(4)); + uint16 id = 0; - if(items == 5) + if (items == 5) id = quest_manager.CreateGroundObject(item_id, glm::vec4(x, y, z, heading)); - else{ - uint32 decay_time = (uint32)SvIV(ST(5)); + else { + uint32 decay_time = (uint32) SvIV(ST(5)); id = quest_manager.CreateGroundObject(item_id, glm::vec4(x, y, z, heading), decay_time); } @@ -2743,63 +2575,62 @@ XS(XS__CreateGroundObject) } XS(XS__CreateGroundObjectFromModel); -XS(XS__CreateGroundObjectFromModel) -{ +XS(XS__CreateGroundObjectFromModel) { dXSARGS; if (items < 5 || items > 7) - Perl_croak(aTHX_ "Usage: creategroundobjectfrommodel(modelname, x, y, z, heading, [object_type], [decay_time])"); + Perl_croak(aTHX_ + "Usage: quest::creategroundobjectfrommodel(string model_name, float x, float y, float z, float heading, [int object_type], [uint32 decay_time-ms = 300000])"); - char * modelname = (char *)SvPV_nolen(ST(0)); - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float heading = (float)SvNV(ST(4)); + char *modelname = (char *) SvPV_nolen(ST(0)); + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); + float heading = (float) SvNV(ST(4)); uint32 object_type = 0; - uint32 decay_time = 0; - uint16 id = 0; + uint32 decay_time = 0; + uint16 id = 0; if (items > 5) - object_type = (uint32)SvIV(ST(5)); + object_type = (uint32) SvIV(ST(5)); if (items > 6) - decay_time = (uint32)SvIV(ST(6)); + decay_time = (uint32) SvIV(ST(6)); id = quest_manager.CreateGroundObjectFromModel(modelname, glm::vec4(x, y, z, heading), object_type, decay_time); XSRETURN_IV(id); } XS(XS__CreateDoor); -XS(XS__CreateDoor) -{ +XS(XS__CreateDoor) { dXSARGS; if (items < 5 || items > 7) - Perl_croak(aTHX_ "Usage: createdoor(modelname, x, y, z, heading, [object_type], [size])"); + Perl_croak(aTHX_ + "Usage: quest::createdoor(string model_name, float x, float y, float z, float heading, [int object_type = 58], [int size = 100])"); - char * modelname = (char *)SvPV_nolen(ST(0)); - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float heading = (float)SvNV(ST(4)); + char *modelname = (char *) SvPV_nolen(ST(0)); + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); + float heading = (float) SvNV(ST(4)); uint32 object_type = 58; - uint32 size = 100; - uint16 id = 0; + uint32 size = 100; + uint16 id = 0; if (items > 5) - object_type = (uint32)SvIV(ST(5)); + object_type = (uint32) SvIV(ST(5)); if (items > 6) - size = (uint32)SvIV(ST(6)); + size = (uint32) SvIV(ST(6)); id = quest_manager.CreateDoor(modelname, x, y, z, heading, object_type, size); XSRETURN_IV(id); } XS(XS__ModifyNPCStat); -XS(XS__ModifyNPCStat) -{ +XS(XS__ModifyNPCStat) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: ModifyNPCStat(stat_id, str_value)"); + Perl_croak(aTHX_ "Usage: quest::ModifyNPCStat(string key, string value)"); quest_manager.ModifyNPCStat(SvPV_nolen(ST(0)), SvPV_nolen(ST(1))); @@ -2807,30 +2638,28 @@ XS(XS__ModifyNPCStat) } XS(XS__collectitems); -XS(XS__collectitems) -{ +XS(XS__collectitems) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: collectitems(item_id, remove_item)"); + Perl_croak(aTHX_ "Usage: quest::collectitems(int item_id, [bool remove_item = true])"); - uint32 item_id = (int)SvIV(ST(0)); - bool remove_item = ((int)SvIV(ST(1))) == 0?false:true; + uint32 item_id = (int) SvIV(ST(0)); + bool remove_item = ((int) SvIV(ST(1))) == 0 ? false : true; int quantity = - quest_manager.collectitems(item_id, remove_item); + quest_manager.collectitems(item_id, remove_item); XSRETURN_IV(quantity); } XS(XS__UpdateSpawnTimer); -XS(XS__UpdateSpawnTimer) -{ +XS(XS__UpdateSpawnTimer) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: UpdateSpawnTimer(spawn2_id, updated_time_till_repop)"); + Perl_croak(aTHX_ "Usage: quest::UpdateSpawnTimer(uint32 spawn2_id, uint32 updated_time_till_repop)"); - uint32 spawn2_id = (int)SvIV(ST(0)); - uint32 updated_time_till_repop = (int)SvIV(ST(1)); + uint32 spawn2_id = (int) SvIV(ST(0)); + uint32 updated_time_till_repop = (int) SvIV(ST(1)); quest_manager.UpdateSpawnTimer(spawn2_id, updated_time_till_repop); @@ -2841,13 +2670,13 @@ XS(XS__MerchantSetItem); XS(XS__MerchantSetItem) { dXSARGS; if (items != 2 && items != 3) - Perl_croak(aTHX_ "Usage: MerchantSetItem(npc_id, item_id [, quantity])"); + Perl_croak(aTHX_ "Usage: quest::MerchantSetItem(uint32 npc_id, uint32 item_id, [uint32 quantity])"); - uint32 npc_id = (int)SvUV(ST(0)); - uint32 item_id = (int)SvUV(ST(1)); + uint32 npc_id = (int) SvUV(ST(0)); + uint32 item_id = (int) SvUV(ST(1)); uint32 quantity = 0; if (items == 3) - quantity = (int)SvUV(ST(2)); + quantity = (int) SvUV(ST(2)); quest_manager.MerchantSetItem(npc_id, item_id, quantity); @@ -2858,10 +2687,10 @@ XS(XS__MerchantCountItem); XS(XS__MerchantCountItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: MerchantCountItem(npc_id, item_id)"); + Perl_croak(aTHX_ "Usage: quest::MerchantCountItem(uint32 npc_id, uint32 item_id)"); - uint32 npc_id = (int)SvUV(ST(0)); - uint32 item_id = (int)SvUV(ST(1)); + uint32 npc_id = (int) SvUV(ST(0)); + uint32 item_id = (int) SvUV(ST(1)); uint32 quantity = quest_manager.MerchantCountItem(npc_id, item_id); XSRETURN_UV(quantity); @@ -2871,17 +2700,19 @@ XS(XS__varlink); XS(XS__varlink) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: varlink(item_id)"); + Perl_croak(aTHX_ "Usage: quest::varlink(uint32 item_id)"); dXSTARG; - Const_char * RETVAL; - char text[250]; - uint32 item_id; - item_id = (int)SvUV(ST(0)); + Const_char *RETVAL; + char text[250]; + uint32 item_id; + item_id = (int) SvUV(ST(0)); RETVAL = quest_manager.varlink(text, item_id); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; XSRETURN(1); } @@ -2889,12 +2720,12 @@ XS(XS__CreateInstance); XS(XS__CreateInstance) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: CreateInstance(zone_name, version, duration)"); + Perl_croak(aTHX_ "Usage: quest::CreateInstance(string zone_name, uint16 version, uint32 duration)"); - char * zone = (char *)SvPV_nolen(ST(0)); - uint16 version = (int)SvUV(ST(1)); - uint32 duration = (int)SvUV(ST(2)); - uint32 id = quest_manager.CreateInstance(zone, version, duration); + char *zone = (char *) SvPV_nolen(ST(0)); + uint16 version = (int) SvUV(ST(1)); + uint32 duration = (int) SvUV(ST(2)); + uint32 id = quest_manager.CreateInstance(zone, version, duration); XSRETURN_UV(id); } @@ -2903,9 +2734,9 @@ XS(XS__DestroyInstance); XS(XS__DestroyInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: DestroyInstance(id)"); + Perl_croak(aTHX_ "Usage: quest::DestroyInstance(int id)"); - uint16 id = (int)SvUV(ST(0)); + uint16 id = (int) SvUV(ST(0)); quest_manager.DestroyInstance(id); XSRETURN_EMPTY; @@ -2915,10 +2746,10 @@ XS(XS__UpdateInstanceTimer); XS(XS__UpdateInstanceTimer) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: UpdateInstanceTimer(instance_id, duration)"); + Perl_croak(aTHX_ "Usage: quest::UpdateInstanceTimer(int16 instance_id, uint32 duration)"); - uint16 instance_id = (uint16)SvUV(ST(0)); - uint32 duration = (uint32)SvUV(ST(1)); + uint16 instance_id = (uint16) SvUV(ST(0)); + uint32 duration = (uint32) SvUV(ST(1)); quest_manager.UpdateInstanceTimer(instance_id, duration); XSRETURN_EMPTY; @@ -2928,10 +2759,10 @@ XS(XS__GetInstanceTimer); XS(XS__GetInstanceTimer) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: GetInstanceTimer()"); - + Perl_croak(aTHX_ "Usage: quest::GetInstanceTimer()"); + uint32 timer = quest_manager.GetInstanceTimer(); - + XSRETURN_UV(timer); } @@ -2939,11 +2770,11 @@ XS(XS__GetInstanceTimerByID); XS(XS__GetInstanceTimerByID) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: GetInstanceTimerByID(instance_id)"); - - uint16 instance_id = (uint16)SvUV(ST(0)); - uint32 timer = quest_manager.GetInstanceTimerByID(instance_id); - + Perl_croak(aTHX_ "Usage: quest::GetInstanceTimerByID(uint16 instance_id)"); + + uint16 instance_id = (uint16) SvUV(ST(0)); + uint32 timer = quest_manager.GetInstanceTimerByID(instance_id); + XSRETURN_UV(timer); } @@ -2951,11 +2782,11 @@ XS(XS__GetInstanceID); XS(XS__GetInstanceID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: GetInstanceID(zone_name, version)"); + Perl_croak(aTHX_ "Usage: quest::GetInstanceID(string zone_name, uint16 version)"); - char * zone = (char *)SvPV_nolen(ST(0)); - uint16 version = (int)SvUV(ST(1)); - uint16 id = quest_manager.GetInstanceID(zone, version); + char *zone = (char *) SvPV_nolen(ST(0)); + uint16 version = (int) SvUV(ST(1)); + uint16 id = quest_manager.GetInstanceID(zone, version); XSRETURN_UV(id); } @@ -2964,23 +2795,21 @@ XS(XS__GetCharactersInInstance); XS(XS__GetCharactersInInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: GetCharactersInInstance(instance_id)"); + Perl_croak(aTHX_ "Usage: quest::GetCharactersInInstance(uint16 instance_id)"); dXSTARG; - Const_char * RETVAL; - uint16 instance_id = (int)SvUV(ST(0)); + Const_char *RETVAL; + uint16 instance_id = (int) SvUV(ST(0)); std::list char_id_list; - std::string char_id_string; + std::string char_id_string; database.GetCharactersInInstance(instance_id, char_id_list); - if (char_id_list.size() > 0) - { + if (char_id_list.size() > 0) { char_id_string = itoa(char_id_list.size()); char_id_string += " player(s) in instance: "; auto iter = char_id_list.begin(); - while (iter != char_id_list.end()) - { + while (iter != char_id_list.end()) { char char_name[64]; database.GetCharName(*iter, char_name); char_id_string += char_name; @@ -2991,12 +2820,13 @@ XS(XS__GetCharactersInInstance) { if (iter != char_id_list.end()) char_id_string += ", "; } - RETVAL = char_id_string.c_str(); - } - else + RETVAL = char_id_string.c_str(); + } else RETVAL = "No players in that instance."; - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; XSRETURN(1); } @@ -3004,9 +2834,9 @@ XS(XS__AssignToInstance); XS(XS__AssignToInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: AssignToInstance(instance_id)"); + Perl_croak(aTHX_ "Usage: quest::AssignToInstance(uint16 instance_id)"); - uint16 instance_id = (int)SvUV(ST(0)); + uint16 instance_id = (int) SvUV(ST(0)); quest_manager.AssignToInstance(instance_id); XSRETURN_EMPTY; @@ -3016,9 +2846,9 @@ XS(XS__AssignGroupToInstance); XS(XS__AssignGroupToInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: AssignGroupToInstance(instance_id)"); + Perl_croak(aTHX_ "Usage: quest::AssignGroupToInstance(uint16 instance_id)"); - uint16 instance_id = (int)SvUV(ST(0)); + uint16 instance_id = (int) SvUV(ST(0)); quest_manager.AssignGroupToInstance(instance_id); XSRETURN_EMPTY; @@ -3028,9 +2858,9 @@ XS(XS__AssignRaidToInstance); XS(XS__AssignRaidToInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: AssignRaidToInstance(instance_id)"); + Perl_croak(aTHX_ "Usage: quest::AssignRaidToInstance(uint16 instance_id)"); - uint16 instance_id = (int)SvUV(ST(0)); + uint16 instance_id = (int) SvUV(ST(0)); quest_manager.AssignRaidToInstance(instance_id); XSRETURN_EMPTY; @@ -3040,9 +2870,9 @@ XS(XS__RemoveFromInstance); XS(XS__RemoveFromInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: RemoveFromInstance(instance_id)"); + Perl_croak(aTHX_ "Usage: quest::RemoveFromInstance(uint16 instance_id)"); - uint16 instance_id = (int)SvUV(ST(0)); + uint16 instance_id = (int) SvUV(ST(0)); quest_manager.RemoveFromInstance(instance_id); XSRETURN_EMPTY; @@ -3052,34 +2882,31 @@ XS(XS__RemoveAllFromInstance); XS(XS__RemoveAllFromInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: RemoveAllFromInstance(instance_id)"); + Perl_croak(aTHX_ "Usage: quest::RemoveAllFromInstance(uint16 instance_id)"); - uint16 instance_id = (int)SvUV(ST(0)); + uint16 instance_id = (int) SvUV(ST(0)); quest_manager.RemoveAllFromInstance(instance_id); XSRETURN_EMPTY; } XS(XS__MovePCInstance); -XS(XS__MovePCInstance) -{ +XS(XS__MovePCInstance) { dXSARGS; if (items != 5 && items != 6) - Perl_croak(aTHX_ "Usage: MovePCInstance(zone_id, instance_id, x, y, z [,heading])"); + Perl_croak(aTHX_ + "Usage: quest::MovePCInstance(int zone_id, int instance_id, float x, float y, float z, [float heading])"); - int zone_id = (int)SvIV(ST(0)); - int instanceid = (int)SvIV(ST(1)); - float x = (float)SvNV(ST(2)); - float y = (float)SvNV(ST(3)); - float z = (float)SvNV(ST(4)); + int zone_id = (int) SvIV(ST(0)); + int instanceid = (int) SvIV(ST(1)); + float x = (float) SvNV(ST(2)); + float y = (float) SvNV(ST(3)); + float z = (float) SvNV(ST(4)); - if (items == 4) - { + if (items == 4) { quest_manager.MovePCInstance(zone_id, instanceid, glm::vec4(x, y, z, 0.0f)); - } - else - { - float heading = (float)SvNV(ST(5)); + } else { + float heading = (float) SvNV(ST(5)); quest_manager.MovePCInstance(zone_id, instanceid, glm::vec4(x, y, z, heading)); } @@ -3090,10 +2917,10 @@ XS(XS__FlagInstanceByGroupLeader); XS(XS__FlagInstanceByGroupLeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: FlagInstanceByGroupLeader(zone, version)"); + Perl_croak(aTHX_ "Usage: quest::FlagInstanceByGroupLeader(uint32 zone, uint16 version)"); - uint32 zone = (int)SvUV(ST(0)); - uint16 version = (int)SvUV(ST(1)); + uint32 zone = (int) SvUV(ST(0)); + uint16 version = (int) SvUV(ST(1)); quest_manager.FlagInstanceByGroupLeader(zone, version); XSRETURN_EMPTY; @@ -3103,10 +2930,10 @@ XS(XS__FlagInstanceByRaidLeader); XS(XS__FlagInstanceByRaidLeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: FlagInstanceByRaidLeader(zone, version)"); + Perl_croak(aTHX_ "Usage: quest::FlagInstanceByRaidLeader(uint32 zone, uint16 version)"); - uint32 zone = (int)SvUV(ST(0)); - uint16 version = (int)SvUV(ST(1)); + uint32 zone = (int) SvUV(ST(0)); + uint16 version = (int) SvUV(ST(1)); quest_manager.FlagInstanceByRaidLeader(zone, version); XSRETURN_EMPTY; @@ -3116,24 +2943,26 @@ XS(XS__saylink); XS(XS__saylink) { dXSARGS; if (items < 1 || items > 3) - Perl_croak(aTHX_ "Usage: saylink(message, [silent?], [link_name])"); + Perl_croak(aTHX_ "Usage: quest::saylink(string message, [bool silent = false], [link_name = message])"); dXSTARG; - Const_char * RETVAL; - char message[250]; - char link_name[250]; - bool silent = false; - strcpy(message,(char *)SvPV_nolen(ST(0))); - if(items >= 2) { - silent = ((int)SvIV(ST(1))) == 0 ? false : true; + Const_char *RETVAL; + char message[250]; + char link_name[250]; + bool silent = false; + strcpy(message, (char *) SvPV_nolen(ST(0))); + if (items >= 2) { + silent = ((int) SvIV(ST(1))) == 0 ? false : true; } if (items == 3) - strcpy(link_name,(char *)SvPV_nolen(ST(2))); + strcpy(link_name, (char *) SvPV_nolen(ST(2))); else - strcpy(link_name,message); + strcpy(link_name, message); RETVAL = quest_manager.saylink(message, silent, link_name); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; XSRETURN(1); } @@ -3141,26 +2970,27 @@ XS(XS__getguildnamebyid); XS(XS__getguildnamebyid) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: getguildnamebyid(guild_id)"); + Perl_croak(aTHX_ "Usage: quest::getguildnamebyid(uint32 guild_id)"); dXSTARG; - Const_char * RETVAL; - uint32 guild_id = (int)SvUV(ST(0)); + Const_char *RETVAL; + uint32 guild_id = (int) SvUV(ST(0)); RETVAL = quest_manager.getguildnamebyid(guild_id); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; XSRETURN(1); } XS(XS__SetRunning); -XS(XS__SetRunning) -{ +XS(XS__SetRunning) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: SetRunning(val)"); + Perl_croak(aTHX_ "Usage: quest::SetRunning(bool is_running)"); - bool val = ((int)SvIV(ST(0))) == 0?false:true; + bool val = ((int) SvIV(ST(0))) == 0 ? false : true; quest_manager.SetRunning(val); @@ -3168,68 +2998,67 @@ XS(XS__SetRunning) } XS(XS__IsRunning); -XS(XS__IsRunning) -{ +XS(XS__IsRunning) { dXSARGS; if (items >= 1) - Perl_croak(aTHX_ "Usage: IsRunning()"); + Perl_croak(aTHX_ "Usage: quest::IsRunning()"); - bool RETVAL; + bool RETVAL; dXSTARG; RETVAL = quest_manager.IsRunning(); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__IsEffectInSpell); -XS(XS__IsEffectInSpell) -{ +XS(XS__IsEffectInSpell) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: IsEffectInSpell(spell_id, effect_id)"); + Perl_croak(aTHX_ "Usage: quest::IsEffectInSpell(uint32 spell_id, uint32 effect_id)"); - uint32 spell_id = (uint32)SvUV(ST(0)); - uint32 effect_id = (uint32)SvUV(ST(1)); - bool RETVAL; + uint32 spell_id = (uint32) SvUV(ST(0)); + uint32 effect_id = (uint32) SvUV(ST(1)); + bool RETVAL; dXSTARG; RETVAL = IsEffectInSpell(spell_id, effect_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__IsBeneficialSpell); -XS(XS__IsBeneficialSpell) -{ +XS(XS__IsBeneficialSpell) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: IsBeneficialSpell(spell_id)"); + Perl_croak(aTHX_ "Usage: quest::IsBeneficialSpell(uint32 spell_id)"); - uint32 spell_id = (uint32)SvUV(ST(0)); - bool RETVAL; + uint32 spell_id = (uint32) SvUV(ST(0)); + bool RETVAL; dXSTARG; RETVAL = BeneficialSpell(spell_id); - XSprePUSH; PUSHu((IV)RETVAL); + XSprePUSH; + PUSHu((IV) RETVAL); XSRETURN(1); } XS(XS__GetSpellResistType); -XS(XS__GetSpellResistType) -{ +XS(XS__GetSpellResistType) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: GetSpellResistType(spell_id)"); + Perl_croak(aTHX_ "Usage: quest::GetSpellResistType(uint32 spell_id)"); - uint32 spell_id = (uint32)SvUV(ST(0)); - int32 spell_val = 0; + uint32 spell_id = (uint32) SvUV(ST(0)); + int32 spell_val = 0; dXSTARG; spell_val = GetSpellResistType(spell_id); @@ -3237,14 +3066,13 @@ XS(XS__GetSpellResistType) } XS(XS__GetSpellTargetType); -XS(XS__GetSpellTargetType) -{ +XS(XS__GetSpellTargetType) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: GetSpellTargetType(spell_id)"); + Perl_croak(aTHX_ "Usage: quest::GetSpellTargetType(uint32 spell_id)"); - uint32 spell_id = (uint32)SvUV(ST(0)); - int32 spell_val = 0; + uint32 spell_id = (uint32) SvUV(ST(0)); + int32 spell_val = 0; dXSTARG; spell_val = GetSpellTargetType(spell_id); @@ -3255,9 +3083,9 @@ XS(XS__FlyMode); XS(XS__FlyMode) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: FlyMode([0/1/2])"); + Perl_croak(aTHX_ "Usage: quest::FlyMode(uint8 mode [0-3])"); - uint8 flymode = (int)SvUV(ST(0)); + uint8 flymode = (int) SvUV(ST(0)); quest_manager.FlyMode(flymode); XSRETURN_EMPTY; @@ -3267,75 +3095,72 @@ XS(XS_FactionValue); XS(XS_FactionValue) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: factionvalue()"); + Perl_croak(aTHX_ "Usage: quest::factionvalue()"); uint8 fac = quest_manager.FactionValue(); XSRETURN_UV(fac); } XS(XS__enabletitle); -XS(XS__enabletitle) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: enabletitle(titleset)"); +XS(XS__enabletitle) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::enabletitle(int title_set_id)"); - int titleset = (int)SvIV(ST(0)); + int titleset = (int) SvIV(ST(0)); - quest_manager.enabletitle(titleset); + quest_manager.enabletitle(titleset); - XSRETURN_EMPTY; + XSRETURN_EMPTY; } XS(XS__checktitle); -XS(XS__checktitle) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: checktitle(titleset)"); +XS(XS__checktitle) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::checktitle(int title_set_id)"); - bool RETVAL; - int titleset = (int)SvIV(ST(0)); + bool RETVAL; + int titleset = (int) SvIV(ST(0)); - RETVAL = quest_manager.checktitle(titleset); + RETVAL = quest_manager.checktitle(titleset); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); XSRETURN(1); } XS(XS__removetitle); -XS(XS__removetitle) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: removetitle(titleset)"); +XS(XS__removetitle) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::removetitle(int title_set_id)"); - int titleset = (int)SvIV(ST(0)); + int titleset = (int) SvIV(ST(0)); - quest_manager.removetitle(titleset); + quest_manager.removetitle(titleset); - XSRETURN_EMPTY; + XSRETURN_EMPTY; } XS(XS__wearchange); -XS(XS__wearchange) -{ +XS(XS__wearchange) { dXSARGS; if (items < 2) - Perl_croak(aTHX_ "Usage: wearchange(slot, texture_id, [hero_forge_model_id], [elite_material_id])"); + Perl_croak(aTHX_ + "Usage: quest::wearchange(uint8 slot, uint16 texture_id, [uint32 hero_forge_model_id = 0], [uint32 elite_material_id = 0])"); - uint8 slot = (int)SvUV(ST(0)); - uint16 texture_id = (int)SvUV(ST(1)); + uint8 slot = (int) SvUV(ST(0)); + uint16 texture_id = (int) SvUV(ST(1)); - uint32 hero_forge_model_id= 0; - uint32 elite_material_id = 0; + uint32 hero_forge_model_id = 0; + uint32 elite_material_id = 0; if (items > 2) - hero_forge_model_id= (int)SvUV(ST(2)); + hero_forge_model_id = (int) SvUV(ST(2)); if (items > 3) - elite_material_id = (int)SvUV(ST(3)); + elite_material_id = (int) SvUV(ST(3)); quest_manager.wearchange(slot, texture_id, hero_forge_model_id, elite_material_id); @@ -3343,16 +3168,15 @@ XS(XS__wearchange) } XS(XS__voicetell); -XS(XS__voicetell) -{ +XS(XS__voicetell) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: voicetell(client_name, macro_id, race_id, gender_id)"); + Perl_croak(aTHX_ "Usage: quest::voicetell(string client_name, int macro_id, int ace_id, int gender_id)"); - char * client_name = (char *)SvPV_nolen(ST(0)); - int macro_id = (int)SvIV(ST(1)); - int race_id = (int)SvIV(ST(2)); - int gender_id = (int)SvIV(ST(3)); + char *client_name = (char *) SvPV_nolen(ST(0)); + int macro_id = (int) SvIV(ST(1)); + int race_id = (int) SvIV(ST(2)); + int gender_id = (int) SvIV(ST(3)); quest_manager.voicetell(client_name, macro_id, race_id, gender_id); @@ -3360,13 +3184,12 @@ XS(XS__voicetell) } XS(XS__LearnRecipe); -XS(XS__LearnRecipe) -{ +XS(XS__LearnRecipe) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: LearnRecipe(recipe_id)"); + Perl_croak(aTHX_ "Usage: quest::LearnRecipe(int recipe_id)"); - uint32 recipe_id = (uint32)SvIV(ST(0)); + uint32 recipe_id = (uint32) SvIV(ST(0)); quest_manager.LearnRecipe(recipe_id); @@ -3374,16 +3197,15 @@ XS(XS__LearnRecipe) } XS(XS__SendMail); -XS(XS__SendMail) -{ +XS(XS__SendMail) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: SendMail(to, from, subject, message)"); + Perl_croak(aTHX_ "Usage: quest::SendMail(stirng to, string from, string subject, string message)"); - char *to = (char *)SvPV_nolen(ST(0)); - char *from = (char *)SvPV_nolen(ST(1)); - char *subject = (char *)SvPV_nolen(ST(2)); - char *message = (char *)SvPV_nolen(ST(3)); + char *to = (char *) SvPV_nolen(ST(0)); + char *from = (char *) SvPV_nolen(ST(1)); + char *subject = (char *) SvPV_nolen(ST(2)); + char *message = (char *) SvPV_nolen(ST(3)); quest_manager.SendMail(to, from, subject, message); @@ -3391,79 +3213,76 @@ XS(XS__SendMail) } XS(XS__GetZoneID); -XS(XS__GetZoneID) -{ +XS(XS__GetZoneID) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: GetZoneID(zone)"); + Perl_croak(aTHX_ "Usage: quest::GetZoneID(string zone)"); - char *zone = (char *)SvPV_nolen(ST(0)); - int32 id = quest_manager.GetZoneID(zone); + char *zone = (char *) SvPV_nolen(ST(0)); + int32 id = quest_manager.GetZoneID(zone); XSRETURN_IV(id); } XS(XS__GetZoneLongName); -XS(XS__GetZoneLongName) -{ +XS(XS__GetZoneLongName) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: GetZoneLongName(zone)"); + Perl_croak(aTHX_ "Usage: quest::GetZoneLongName(string zone)"); dXSTARG; - char *zone = (char *)SvPV_nolen(ST(0)); - Const_char* RETVAL = quest_manager.GetZoneLongName(zone); + char *zone = (char *) SvPV_nolen(ST(0)); + Const_char *RETVAL = quest_manager.GetZoneLongName(zone); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; XSRETURN(1); } XS(XS__GetTimeSeconds); -XS(XS__GetTimeSeconds) -{ +XS(XS__GetTimeSeconds) { dXSARGS; if (items != 0) - Perl_croak(aTHX_ "Usage: GetTimeSeconds()"); + Perl_croak(aTHX_ "Usage: quest::GetTimeSeconds()"); - uint32 seconds = 0; + uint32 seconds = 0; dXSTARG; seconds = Timer::GetTimeSeconds(); XSRETURN_UV(seconds); } -XS(XS__crosszonesignalclientbychar_id); -XS(XS__crosszonesignalclientbychar_id) -{ +XS(XS__crosszonesignalclientbycharid); +XS(XS__crosszonesignalclientbycharid) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: crosszonesignalclientbychar_id(char_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbycharid(int character_id, int value)"); if (items == 2) { - int char_id = (int)SvIV(ST(0)); - uint32 int_value = (uint32)SvIV(ST(1)); + int char_id = (int) SvIV(ST(0)); + uint32 int_value = (uint32) SvIV(ST(1)); quest_manager.CrossZoneSignalPlayerByCharID(char_id, int_value); } else { - Perl_croak(aTHX_ "Usage: crosszonesignalclientbychar_id(char_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbycharid(int character_id, int value)"); } XSRETURN_EMPTY; } XS(XS__crosszonesignalclientbyname); -XS(XS__crosszonesignalclientbyname) -{ +XS(XS__crosszonesignalclientbyname) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: crosszonesignalclientbychar_id(name, int_value)"); + Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbycharid(string name, int value)"); if (items == 2) { - char *name = (char *)SvPV_nolen(ST(0)); - uint32 int_value = (uint32)SvIV(ST(1)); + char *name = (char *) SvPV_nolen(ST(0)); + uint32 int_value = (uint32) SvIV(ST(1)); quest_manager.CrossZoneSignalPlayerByName(name, int_value); } else { - Perl_croak(aTHX_ "Usage: crosszonesignalclientbychar_id(name, int_value)"); + Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbycharid(string name, int value)"); } XSRETURN_EMPTY; @@ -3471,36 +3290,31 @@ XS(XS__crosszonesignalclientbyname) XS(XS__crosszonemessageplayerbyname); -XS(XS__crosszonemessageplayerbyname) -{ +XS(XS__crosszonemessageplayerbyname) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: crosszonemessageplayerbyname(channel_id, name, message)"); + Perl_croak(aTHX_ "Usage: quest::crosszonemessageplayerbyname(int channel_id, string name, string message)"); if (items == 3) { - uint32 channel_id = (uint32)SvIV(ST(0)); - char *name = (char *)SvPV_nolen(ST(1)); - char *message = (char *)SvPV_nolen(ST(2)); + uint32 channel_id = (uint32) SvIV(ST(0)); + char *name = (char *) SvPV_nolen(ST(1)); + char *message = (char *) SvPV_nolen(ST(2)); quest_manager.CrossZoneMessagePlayerByName(channel_id, name, message); - } else { - Perl_croak(aTHX_ "Usage: crosszonemessageplayerbyname(channel_id, name, message)"); } XSRETURN_EMPTY; } XS(XS__enablerecipe); -XS(XS__enablerecipe) -{ +XS(XS__enablerecipe) { dXSARGS; bool success = false; if (items != 1) { - Perl_croak(aTHX_ "Usage: enablerecipe(recipe_id)"); - } - else { - uint32 recipe_id = (uint32)SvIV(ST(0)); + Perl_croak(aTHX_ "Usage: quest::enablerecipe(int recipe_id)"); + } else { + uint32 recipe_id = (uint32) SvIV(ST(0)); success = quest_manager.EnableRecipe(recipe_id); } if (!success) { @@ -3511,16 +3325,14 @@ XS(XS__enablerecipe) } XS(XS__disablerecipe); -XS(XS__disablerecipe) -{ +XS(XS__disablerecipe) { dXSARGS; bool success = false; if (items != 1) { - Perl_croak(aTHX_ "Usage: disablerecipe(recipe_id)"); - } - else { - uint32 recipe_id = (uint32)SvIV(ST(0)); + Perl_croak(aTHX_ "Usage: quest::disablerecipe(int recipe_id)"); + } else { + uint32 recipe_id = (uint32) SvIV(ST(0)); success = quest_manager.DisableRecipe(recipe_id); } if (!success) { @@ -3531,15 +3343,13 @@ XS(XS__disablerecipe) } XS(XS__clear_npctype_cache); -XS(XS__clear_npctype_cache) -{ +XS(XS__clear_npctype_cache) { dXSARGS; if (items != 1) { - Perl_croak(aTHX_ "Usage: clear_npctype_cache(npc_type_id)"); - } - else { - int32 npc_type_id = (int32)SvIV(ST(0)); + Perl_croak(aTHX_ "Usage: quest::clear_npctype_cache(int npc_type_id)"); + } else { + int32 npc_type_id = (int32) SvIV(ST(0)); quest_manager.ClearNPCTypeCache(npc_type_id); } @@ -3547,8 +3357,7 @@ XS(XS__clear_npctype_cache) } XS(XS__reloadzonestaticdata); -XS(XS__reloadzonestaticdata) -{ +XS(XS__reloadzonestaticdata) { dXSARGS; quest_manager.ReloadZoneStaticData(); @@ -3557,65 +3366,61 @@ XS(XS__reloadzonestaticdata) } XS(XS__qs_send_query); -XS(XS__qs_send_query) -{ +XS(XS__qs_send_query) { dXSARGS; - if (items != 1){ - Perl_croak(aTHX_ "Usage: qs_send_query(query)"); - } - else{ + if (items != 1) { + Perl_croak(aTHX_ "Usage: quest::qs_send_query(string query)"); + } else { // char *Query = (char *)SvPV_nolen(ST(0)); - std::string Query = (std::string)SvPV_nolen(ST(0)); + std::string Query = (std::string) SvPV_nolen(ST(0)); QServ->SendQuery(Query); } XSRETURN_EMPTY; } XS(XS__qs_player_event); -XS(XS__qs_player_event) -{ +XS(XS__qs_player_event) { dXSARGS; - if (items != 2){ - Perl_croak(aTHX_ "Usage: qs_player_event(char_id, message)"); - } - else{ - int char_id = (int)SvIV(ST(0)); - std::string message = (std::string)SvPV_nolen(ST(1)); + if (items != 2) { + Perl_croak(aTHX_ "Usage: quest::qs_player_event(int character_id, string message)"); + } else { + int char_id = (int) SvIV(ST(0)); + std::string message = (std::string) SvPV_nolen(ST(1)); QServ->PlayerLogEvent(Player_Log_Quest, char_id, message); } XSRETURN_EMPTY; } XS(XS__crosszonesetentityvariablebynpctypeid); -XS(XS__crosszonesetentityvariablebynpctypeid) -{ +XS(XS__crosszonesetentityvariablebynpctypeid) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: crosszonesetentityvariablebynpctypeid(npc_type_id, key, str_value)"); + Perl_croak(aTHX_ + "Usage: quest::crosszonesetentityvariablebynpctypeid(int npc_type_id, string key, string value)"); if (items == 3) { - uint32 npc_type_id = (uint32)SvIV(ST(0)); - const char *key = (const char *)SvPV_nolen(ST(1)); - const char *str_value = (const char *)SvPV_nolen(ST(2)); + uint32 npc_type_id = (uint32) SvIV(ST(0)); + const char *key = (const char *) SvPV_nolen(ST(1)); + const char *str_value = (const char *) SvPV_nolen(ST(2)); quest_manager.CrossZoneSetEntityVariableByNPCTypeID(npc_type_id, key, str_value); } XSRETURN_EMPTY; } -XS(XS__crosszonesetentityvariablebyclient_name); -XS(XS__crosszonesetentityvariablebyclient_name) -{ +XS(XS__crosszonesetentityvariablebyclientname); +XS(XS__crosszonesetentityvariablebyclientname) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: crosszonesetentityvariablebyclient_name(client_name, key, str_value)"); + Perl_croak(aTHX_ + "Usage: quest::crosszonesetentityvariablebyclientname(string client_name, string key, string value)"); if (items == 3) { - const char *client_name = (const char *)SvPV_nolen(ST(0)); - const char *key = (const char *)SvPV_nolen(ST(1)); - const char *str_value = (const char *)SvPV_nolen(ST(2)); + const char *client_name = (const char *) SvPV_nolen(ST(0)); + const char *key = (const char *) SvPV_nolen(ST(1)); + const char *str_value = (const char *) SvPV_nolen(ST(2)); quest_manager.CrossZoneSetEntityVariableByClientName(client_name, key, str_value); } @@ -3623,16 +3428,15 @@ XS(XS__crosszonesetentityvariablebyclient_name) } XS(XS__crosszonesignalnpcbynpctypeid); -XS(XS__crosszonesignalnpcbynpctypeid) -{ +XS(XS__crosszonesignalnpcbynpctypeid) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: crosszonesignalnpcbynpctypeid(npc_type_id, int_value)"); + Perl_croak(aTHX_ "Usage: quest::crosszonesignalnpcbynpctypeid(uint32 npc_type_id, uint32 value)"); if (items == 2) { - uint32 npc_type_id = (uint32)SvIV(ST(0)); - uint32 int_value = (uint32)SvIV(ST(1)); + uint32 npc_type_id = (uint32) SvIV(ST(0)); + uint32 int_value = (uint32) SvIV(ST(1)); quest_manager.CrossZoneSignalNPCByNPCTypeID(npc_type_id, int_value); } @@ -3640,49 +3444,45 @@ XS(XS__crosszonesignalnpcbynpctypeid) } XS(XS__worldwidemarquee); -XS(XS__worldwidemarquee) -{ +XS(XS__worldwidemarquee) { dXSARGS; if (items != 6) - Perl_croak(aTHX_ "Usage: worldwidemarquee(color_id, priority, fade_in, fade_out, duration, message)"); - + Perl_croak(aTHX_ + "Usage: quest::worldwidemarquee(uint32 color_id, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, string message)"); + if (items == 6) { - uint32 color_id = (uint32)SvIV(ST(0)); - uint32 priority = (uint32)SvIV(ST(1)); - uint32 fade_in = (uint32)SvIV(ST(2)); - uint32 fade_out = (uint32)SvIV(ST(3)); - uint32 duration = (uint32)SvIV(ST(4)); - char* message = (char *)SvPV_nolen(ST(5)); + uint32 color_id = (uint32) SvIV(ST(0)); + uint32 priority = (uint32) SvIV(ST(1)); + uint32 fade_in = (uint32) SvIV(ST(2)); + uint32 fade_out = (uint32) SvIV(ST(3)); + uint32 duration = (uint32) SvIV(ST(4)); + char *message = (char *) SvPV_nolen(ST(5)); quest_manager.WorldWideMarquee(color_id, priority, fade_in, fade_out, duration, message); } - + XSRETURN_EMPTY; } XS(XS__debug); -XS(XS__debug) -{ +XS(XS__debug) { dXSARGS; - if (items != 1 && items != 2){ - Perl_croak(aTHX_ "Usage: debug(message, [debug_level])"); - } - else{ - std::string log_message = (std::string)SvPV_nolen(ST(0)); - uint8 debug_level = 1; + if (items != 1 && items != 2) { + Perl_croak(aTHX_ "Usage: quest::debug(string message, [uint8 debug_level = 1 [1-3]])"); + } else { + std::string log_message = (std::string) SvPV_nolen(ST(0)); + uint8 debug_level = 1; if (items == 2) - debug_level = (uint8)SvIV(ST(1)); + debug_level = (uint8) SvIV(ST(1)); if (debug_level > Logs::Detail) return; - if (debug_level == Logs::General){ + if (debug_level == Logs::General) { Log(Logs::General, Logs::QuestDebug, log_message); - } - else if (debug_level == Logs::Moderate){ + } else if (debug_level == Logs::Moderate) { Log(Logs::Moderate, Logs::QuestDebug, log_message); - } - else if (debug_level == Logs::Detail){ + } else if (debug_level == Logs::Detail) { Log(Logs::Detail, Logs::QuestDebug, log_message); } } @@ -3693,36 +3493,83 @@ XS(XS__UpdateZoneHeader); XS(XS__UpdateZoneHeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: UpdateZoneHeader(key, str_value)"); - - std::string key = (std::string)SvPV_nolen(ST(0)); - std::string str_value = (std::string)SvPV_nolen(ST(1)); + Perl_croak(aTHX_ "Usage: quest::UpdateZoneHeader(string key, string value)"); + + std::string key = (std::string) SvPV_nolen(ST(0)); + std::string str_value = (std::string) SvPV_nolen(ST(1)); quest_manager.UpdateZoneHeader(key, str_value); - + XSRETURN_EMPTY; } +XS(XS__get_data); +XS(XS__get_data) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::get_data(string bucket_key)"); + + dXSTARG; + std::string key = (std::string) SvPV_nolen(ST(0)); + + sv_setpv(TARG, DataBucket::GetData(key).c_str()); + XSprePUSH; + PUSHTARG; + XSRETURN(1); +} + +XS(XS__set_data); +XS(XS__set_data) { + dXSARGS; + if (items != 2 && items != 3) { + Perl_croak(aTHX_ "Usage: quest::set_data(string key, string value, [string expires_at = 0])"); + } else { + std::string key = (std::string) SvPV_nolen(ST(0)); + std::string value = (std::string) SvPV_nolen(ST(1)); + + std::string expires_at; + if (items == 3) + expires_at = (std::string) SvPV_nolen(ST(2)); + + DataBucket::SetData(key, value, expires_at); + } + XSRETURN_EMPTY; +} + +XS(XS__delete_data); +XS(XS__delete_data) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::delete_data(string bucket_key)"); + + dXSTARG; + std::string key = (std::string) SvPV_nolen(ST(0)); + + XSprePUSH; + PUSHu((IV) DataBucket::DeleteData(key)); + + XSRETURN(1); +} + /* This is the callback perl will look for to setup the quest package's XSUBs */ EXTERN_C XS(boot_quest); // prototype to pass -Wmissing-prototypes -EXTERN_C XS(boot_quest) -{ +EXTERN_C XS(boot_quest) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = '\0'; - if(items != 1) + if (items != 1) Log(Logs::General, Logs::Error, "boot_quest does not take any arguments."); - char buf[128]; //shouldent have any function names longer than this. + char buf[128]; //shouldent have any function names longer than this. //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; #ifdef BOTS newXS(strcpy(buf, "botquest"), XS__botquest, file); @@ -3731,218 +3578,219 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "createBot"), XS__createBot, file); #endif //BOTS - newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file); - newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file); - newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file); - newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file); - newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file); - newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file); - newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file); - newXS(strcpy(buf, "GetInstanceTimer"), XS__GetInstanceTimer, file); - newXS(strcpy(buf, "GetInstanceTimerByID"), XS__GetInstanceTimerByID, file); - newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file); - newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file); - newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file); - newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file); - newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file); - newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file); - newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file); - newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file); - newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file); - newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file); - newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file); - newXS(strcpy(buf, "IsEffectInSpell"), XS__IsEffectInSpell, file); - newXS(strcpy(buf, "IsRunning"), XS__IsRunning, file); - newXS(strcpy(buf, "LearnRecipe"), XS__LearnRecipe, file); - newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file); - newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file); - newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file); - newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file); - newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file); - newXS(strcpy(buf, "SendMail"), XS__SendMail, file); - newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file); - newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file); - newXS(strcpy(buf, "activespeaktask"), XS__activespeaktask, file); - newXS(strcpy(buf, "activetasksinset"), XS__activetasksinset, file); - newXS(strcpy(buf, "addldonloss"), XS__addldonpoints, file); - newXS(strcpy(buf, "addldonpoints"), XS__addldonpoints, file); - newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file); - newXS(strcpy(buf, "addloot"), XS__addloot, file); - newXS(strcpy(buf, "addskill"), XS__addskill, file); - newXS(strcpy(buf, "assigntask"), XS__assigntask, file); - newXS(strcpy(buf, "attack"), XS__attack, file); - newXS(strcpy(buf, "attacknpc"), XS__attacknpc, file); - newXS(strcpy(buf, "attacknpctype"), XS__attacknpctype, file); - newXS(strcpy(buf, "buryplayercorpse"), XS__buryplayercorpse, file); - newXS(strcpy(buf, "castspell"), XS__castspell, file); - newXS(strcpy(buf, "changedeity"), XS__changedeity, file); - newXS(strcpy(buf, "checktitle"), XS__checktitle, file); - newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file); - newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file); - newXS(strcpy(buf, "clear_zone_flag"), XS__clear_zone_flag, file); - newXS(strcpy(buf, "clearspawntimers"), XS__clearspawntimers, file); - newXS(strcpy(buf, "collectitems"), XS__collectitems, file); - newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file); - newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file); - newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file); - newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file); - newXS(strcpy(buf, "createguild"), XS__createguild, file); - newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file); - newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file); - newXS(strcpy(buf, "crosszonesetentityvariablebyclient_name"), XS__crosszonesetentityvariablebyclient_name, file); - newXS(strcpy(buf, "crosszonesignalclientbychar_id"), XS__crosszonesignalclientbychar_id, file); - newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file); - newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file); - newXS(strcpy(buf, "worldwidemarquee"), XS__worldwidemarquee, file); - newXS(strcpy(buf, "debug"), XS__debug, file); - newXS(strcpy(buf, "delglobal"), XS__delglobal, file); - newXS(strcpy(buf, "depop"), XS__depop, file); - newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file); - newXS(strcpy(buf, "depopall"), XS__depopall, file); - newXS(strcpy(buf, "depopzone"), XS__depopzone, file); - newXS(strcpy(buf, "ding"), XS__ding, file); - newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file); - newXS(strcpy(buf, "disable_spawn2"), XS__disable_spawn2, file); - newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file); - newXS(strcpy(buf, "disabletask"), XS__disabletask, file); - newXS(strcpy(buf, "doanim"), XS__doanim, file); - newXS(strcpy(buf, "echo"), XS__echo, file); - newXS(strcpy(buf, "emote"), XS__emote, file); - newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file); - newXS(strcpy(buf, "enable_spawn2"), XS__enable_spawn2, file); - newXS(strcpy(buf, "enabledtaskcount"), XS__enabledtaskcount, file); - newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file); - newXS(strcpy(buf, "enabletask"), XS__enabletask, file); - newXS(strcpy(buf, "enabletitle"), XS__enabletitle, file); - newXS(strcpy(buf, "exp"), XS__exp, file); - newXS(strcpy(buf, "faction"), XS__faction, file); - newXS(strcpy(buf, "factionvalue"), XS_FactionValue, file); - newXS(strcpy(buf, "failtask"), XS__failtask, file); - newXS(strcpy(buf, "firsttaskinset"), XS__firsttaskinset, file); - newXS(strcpy(buf, "follow"), XS__follow, file); - newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file); - newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file); - newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file); - newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file); - newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file); - newXS(strcpy(buf, "getlevel"), XS__getlevel, file); - newXS(strcpy(buf, "getplayerburiedcorpsecount"), XS__getplayerburiedcorpsecount, file); - newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file); - newXS(strcpy(buf, "givecash"), XS__givecash, file); - newXS(strcpy(buf, "gmmove"), XS__gmmove, file); - newXS(strcpy(buf, "gmsay"), XS__gmsay, file); - newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file); - newXS(strcpy(buf, "incstat"), XS__incstat, file); - newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file); - newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file); - newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file); - newXS(strcpy(buf, "istaskactivityactive"), XS__istaskactivityactive, file); - newXS(strcpy(buf, "istaskappropriate"), XS__istaskappropriate, file); - newXS(strcpy(buf, "istaskcompleted"), XS__istaskcompleted, file); - newXS(strcpy(buf, "istaskenabled"), XS__istaskenabled, file); - newXS(strcpy(buf, "itemlink"), XS__itemlink, file); - newXS(strcpy(buf, "lasttaskinset"), XS__lasttaskinset, file); - newXS(strcpy(buf, "level"), XS__level, file); - newXS(strcpy(buf, "me"), XS__me, file); - newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file); - newXS(strcpy(buf, "movegrp"), XS__movegrp, file); - newXS(strcpy(buf, "movepc"), XS__movepc, file); - newXS(strcpy(buf, "moveto"), XS__moveto, file); - newXS(strcpy(buf, "nexttaskinset"), XS__nexttaskinset, file); - newXS(strcpy(buf, "npcfeature"), XS__npcfeature, file); - newXS(strcpy(buf, "npcgender"), XS__npcgender, file); - newXS(strcpy(buf, "npcrace"), XS__npcrace, file); - newXS(strcpy(buf, "npcsize"), XS__npcsize, file); - newXS(strcpy(buf, "npctexture"), XS__npctexture, file); - newXS(strcpy(buf, "pause"), XS__pause, file); - newXS(strcpy(buf, "permaclass"), XS__permaclass, file); - newXS(strcpy(buf, "permagender"), XS__permagender, file); - newXS(strcpy(buf, "permarace"), XS__permarace, file); - newXS(strcpy(buf, "playerfeature"), XS__playerfeature, file); - newXS(strcpy(buf, "playergender"), XS__playergender, file); - newXS(strcpy(buf, "playerrace"), XS__playerrace, file); - newXS(strcpy(buf, "playersize"), XS__playersize, file); - newXS(strcpy(buf, "playertexture"), XS__playertexture, file); - newXS(strcpy(buf, "popup"), XS__popup, file); - newXS(strcpy(buf, "pvp"), XS__pvp, file); - newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file); - newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file); - newXS(strcpy(buf, "rain"), XS__rain, file); - newXS(strcpy(buf, "rebind"), XS__rebind, file); - newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file); - newXS(strcpy(buf, "removetitle"), XS__removetitle, file); - newXS(strcpy(buf, "repopzone"), XS__repopzone, file); - newXS(strcpy(buf, "ConnectNodeToNode"), XS__ConnectNodeToNode, file); - newXS(strcpy(buf, "AddNode"), XS__AddNode, file); - newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file); - newXS(strcpy(buf, "respawn"), XS__respawn, file); - newXS(strcpy(buf, "resume"), XS__resume, file); - newXS(strcpy(buf, "safemove"), XS__safemove, file); - newXS(strcpy(buf, "save"), XS__save, file); - newXS(strcpy(buf, "say"), XS__say, file); - newXS(strcpy(buf, "saylink"), XS__saylink, file); - newXS(strcpy(buf, "scribespells"), XS__scribespells, file); - newXS(strcpy(buf, "selfcast"), XS__selfcast, file); - newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file); - newXS(strcpy(buf, "set_zone_flag"), XS__set_zone_flag, file); - newXS(strcpy(buf, "setallskill"), XS__setallskill, file); - newXS(strcpy(buf, "setanim"), XS__setanim, file); - newXS(strcpy(buf, "setglobal"), XS__setglobal, file); - newXS(strcpy(buf, "setguild"), XS__setguild, file); - newXS(strcpy(buf, "sethp"), XS__sethp, file); - newXS(strcpy(buf, "setlanguage"), XS__setlanguage, file); - newXS(strcpy(buf, "setnexthpevent"), XS__setnexthpevent, file); - newXS(strcpy(buf, "setnextinchpevent"), XS__setnextinchpevent, file); - newXS(strcpy(buf, "setskill"), XS__setskill, file); - newXS(strcpy(buf, "setsky"), XS__setsky, file); - newXS(strcpy(buf, "setstat"), XS__setstat, file); - newXS(strcpy(buf, "settarget"), XS__settarget, file); - newXS(strcpy(buf, "settime"), XS__settime, file); - newXS(strcpy(buf, "settimer"), XS__settimer, file); - newXS(strcpy(buf, "settimerMS"), XS__settimerMS, file); - newXS(strcpy(buf, "sfollow"), XS__sfollow, file); - newXS(strcpy(buf, "shout"), XS__shout, file); - newXS(strcpy(buf, "shout2"), XS__shout2, file); - newXS(strcpy(buf, "showgrid"), XS__showgrid, file); - newXS(strcpy(buf, "signal"), XS__signal, file); - newXS(strcpy(buf, "signalwith"), XS__signalwith, file); - newXS(strcpy(buf, "snow"), XS__snow, file); - newXS(strcpy(buf, "spawn"), XS__spawn, file); - newXS(strcpy(buf, "spawn2"), XS__spawn2, file); - newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file); - newXS(strcpy(buf, "spawn_from_spawn2"), XS__spawn_from_spawn2, file); - newXS(strcpy(buf, "start"), XS__start, file); - newXS(strcpy(buf, "stop"), XS__stop, file); - newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file); - newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file); - newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file); - newXS(strcpy(buf, "summonburiedplayercorpse"), XS__summonburiedplayercorpse, file); - newXS(strcpy(buf, "summonitem"), XS__summonitem, file); - newXS(strcpy(buf, "surname"), XS__surname, file); - newXS(strcpy(buf, "targlobal"), XS__targlobal, file); - newXS(strcpy(buf, "taskexploredarea"), XS__taskexploredarea, file); - newXS(strcpy(buf, "taskselector"), XS__taskselector, file); - newXS(strcpy(buf, "task_setselector"), XS__task_setselector, file); - newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file); - newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file); - newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file); - newXS(strcpy(buf, "traindisc"), XS__traindisc, file); - newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file); - newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file); - newXS(strcpy(buf, "unscribespells"), XS__unscribespells, file); - newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file); - newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file); - newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file); - newXS(strcpy(buf, "UpdateZoneHeader"), XS__UpdateZoneHeader, file); - newXS(strcpy(buf, "varlink"), XS__varlink, file); - newXS(strcpy(buf, "voicetell"), XS__voicetell, file); - newXS(strcpy(buf, "we"), XS__we, file); - newXS(strcpy(buf, "wearchange"), XS__wearchange, file); - newXS(strcpy(buf, "write"), XS__write, file); - newXS(strcpy(buf, "ze"), XS__ze, file); - newXS(strcpy(buf, "zone"), XS__zone, file); + newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file); + newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file); + newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file); + newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file); + newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file); + newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file); + newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file); + newXS(strcpy(buf, "GetInstanceTimer"), XS__GetInstanceTimer, file); + newXS(strcpy(buf, "GetInstanceTimerByID"), XS__GetInstanceTimerByID, file); + newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file); + newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file); + newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file); + newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file); + newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file); + newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file); + newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file); + newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file); + newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file); + newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file); + newXS(strcpy(buf, "get_data"), XS__get_data, file); + newXS(strcpy(buf, "set_data"), XS__set_data, file); + newXS(strcpy(buf, "delete_data"), XS__delete_data, file); + newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file); + newXS(strcpy(buf, "IsEffectInSpell"), XS__IsEffectInSpell, file); + newXS(strcpy(buf, "IsRunning"), XS__IsRunning, file); + newXS(strcpy(buf, "LearnRecipe"), XS__LearnRecipe, file); + newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file); + newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file); + newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file); + newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file); + newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file); + newXS(strcpy(buf, "SendMail"), XS__SendMail, file); + newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file); + newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file); + newXS(strcpy(buf, "activespeaktask"), XS__activespeaktask, file); + newXS(strcpy(buf, "activetasksinset"), XS__activetasksinset, file); + newXS(strcpy(buf, "addldonloss"), XS__addldonpoints, file); + newXS(strcpy(buf, "addldonpoints"), XS__addldonpoints, file); + newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file); + newXS(strcpy(buf, "addloot"), XS__addloot, file); + newXS(strcpy(buf, "addskill"), XS__addskill, file); + newXS(strcpy(buf, "assigntask"), XS__assigntask, file); + newXS(strcpy(buf, "attack"), XS__attack, file); + newXS(strcpy(buf, "attacknpc"), XS__attacknpc, file); + newXS(strcpy(buf, "attacknpctype"), XS__attacknpctype, file); + newXS(strcpy(buf, "buryplayercorpse"), XS__buryplayercorpse, file); + newXS(strcpy(buf, "castspell"), XS__castspell, file); + newXS(strcpy(buf, "changedeity"), XS__changedeity, file); + newXS(strcpy(buf, "checktitle"), XS__checktitle, file); + newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file); + newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file); + newXS(strcpy(buf, "clear_zone_flag"), XS__clear_zone_flag, file); + newXS(strcpy(buf, "clearspawntimers"), XS__clearspawntimers, file); + newXS(strcpy(buf, "collectitems"), XS__collectitems, file); + newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file); + newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file); + newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file); + newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file); + newXS(strcpy(buf, "createguild"), XS__createguild, file); + newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file); + newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file); + newXS(strcpy(buf, "crosszonesetentityvariablebyclientname"), XS__crosszonesetentityvariablebyclientname, file); + newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file); + newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file); + newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file); + newXS(strcpy(buf, "worldwidemarquee"), XS__worldwidemarquee, file); + newXS(strcpy(buf, "debug"), XS__debug, file); + newXS(strcpy(buf, "delglobal"), XS__delglobal, file); + newXS(strcpy(buf, "depop"), XS__depop, file); + newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file); + newXS(strcpy(buf, "depopall"), XS__depopall, file); + newXS(strcpy(buf, "depopzone"), XS__depopzone, file); + newXS(strcpy(buf, "ding"), XS__ding, file); + newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file); + newXS(strcpy(buf, "disable_spawn2"), XS__disable_spawn2, file); + newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file); + newXS(strcpy(buf, "disabletask"), XS__disabletask, file); + newXS(strcpy(buf, "doanim"), XS__doanim, file); + newXS(strcpy(buf, "echo"), XS__echo, file); + newXS(strcpy(buf, "emote"), XS__emote, file); + newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file); + newXS(strcpy(buf, "enable_spawn2"), XS__enable_spawn2, file); + newXS(strcpy(buf, "enabledtaskcount"), XS__enabledtaskcount, file); + newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file); + newXS(strcpy(buf, "enabletask"), XS__enabletask, file); + newXS(strcpy(buf, "enabletitle"), XS__enabletitle, file); + newXS(strcpy(buf, "exp"), XS__exp, file); + newXS(strcpy(buf, "faction"), XS__faction, file); + newXS(strcpy(buf, "factionvalue"), XS_FactionValue, file); + newXS(strcpy(buf, "failtask"), XS__failtask, file); + newXS(strcpy(buf, "firsttaskinset"), XS__firsttaskinset, file); + newXS(strcpy(buf, "follow"), XS__follow, file); + newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file); + newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file); + newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file); + newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file); + newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file); + newXS(strcpy(buf, "getlevel"), XS__getlevel, file); + newXS(strcpy(buf, "getplayerburiedcorpsecount"), XS__getplayerburiedcorpsecount, file); + newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file); + newXS(strcpy(buf, "givecash"), XS__givecash, file); + newXS(strcpy(buf, "gmmove"), XS__gmmove, file); + newXS(strcpy(buf, "gmsay"), XS__gmsay, file); + newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file); + newXS(strcpy(buf, "incstat"), XS__incstat, file); + newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file); + newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file); + newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file); + newXS(strcpy(buf, "istaskactivityactive"), XS__istaskactivityactive, file); + newXS(strcpy(buf, "istaskappropriate"), XS__istaskappropriate, file); + newXS(strcpy(buf, "istaskcompleted"), XS__istaskcompleted, file); + newXS(strcpy(buf, "istaskenabled"), XS__istaskenabled, file); + newXS(strcpy(buf, "itemlink"), XS__itemlink, file); + newXS(strcpy(buf, "lasttaskinset"), XS__lasttaskinset, file); + newXS(strcpy(buf, "level"), XS__level, file); + newXS(strcpy(buf, "me"), XS__me, file); + newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file); + newXS(strcpy(buf, "movegrp"), XS__movegrp, file); + newXS(strcpy(buf, "movepc"), XS__movepc, file); + newXS(strcpy(buf, "moveto"), XS__moveto, file); + newXS(strcpy(buf, "nexttaskinset"), XS__nexttaskinset, file); + newXS(strcpy(buf, "npcfeature"), XS__npcfeature, file); + newXS(strcpy(buf, "npcgender"), XS__npcgender, file); + newXS(strcpy(buf, "npcrace"), XS__npcrace, file); + newXS(strcpy(buf, "npcsize"), XS__npcsize, file); + newXS(strcpy(buf, "npctexture"), XS__npctexture, file); + newXS(strcpy(buf, "pause"), XS__pause, file); + newXS(strcpy(buf, "permaclass"), XS__permaclass, file); + newXS(strcpy(buf, "permagender"), XS__permagender, file); + newXS(strcpy(buf, "permarace"), XS__permarace, file); + newXS(strcpy(buf, "playerfeature"), XS__playerfeature, file); + newXS(strcpy(buf, "playergender"), XS__playergender, file); + newXS(strcpy(buf, "playerrace"), XS__playerrace, file); + newXS(strcpy(buf, "playersize"), XS__playersize, file); + newXS(strcpy(buf, "playertexture"), XS__playertexture, file); + newXS(strcpy(buf, "popup"), XS__popup, file); + newXS(strcpy(buf, "pvp"), XS__pvp, file); + newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file); + newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file); + newXS(strcpy(buf, "rain"), XS__rain, file); + newXS(strcpy(buf, "rebind"), XS__rebind, file); + newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file); + newXS(strcpy(buf, "removetitle"), XS__removetitle, file); + newXS(strcpy(buf, "repopzone"), XS__repopzone, file); + newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file); + newXS(strcpy(buf, "respawn"), XS__respawn, file); + newXS(strcpy(buf, "resume"), XS__resume, file); + newXS(strcpy(buf, "safemove"), XS__safemove, file); + newXS(strcpy(buf, "save"), XS__save, file); + newXS(strcpy(buf, "say"), XS__say, file); + newXS(strcpy(buf, "saylink"), XS__saylink, file); + newXS(strcpy(buf, "scribespells"), XS__scribespells, file); + newXS(strcpy(buf, "selfcast"), XS__selfcast, file); + newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file); + newXS(strcpy(buf, "set_zone_flag"), XS__set_zone_flag, file); + newXS(strcpy(buf, "setallskill"), XS__setallskill, file); + newXS(strcpy(buf, "setanim"), XS__setanim, file); + newXS(strcpy(buf, "setglobal"), XS__setglobal, file); + newXS(strcpy(buf, "setguild"), XS__setguild, file); + newXS(strcpy(buf, "sethp"), XS__sethp, file); + newXS(strcpy(buf, "setlanguage"), XS__setlanguage, file); + newXS(strcpy(buf, "setnexthpevent"), XS__setnexthpevent, file); + newXS(strcpy(buf, "setnextinchpevent"), XS__setnextinchpevent, file); + newXS(strcpy(buf, "setskill"), XS__setskill, file); + newXS(strcpy(buf, "setsky"), XS__setsky, file); + newXS(strcpy(buf, "setstat"), XS__setstat, file); + newXS(strcpy(buf, "settarget"), XS__settarget, file); + newXS(strcpy(buf, "settime"), XS__settime, file); + newXS(strcpy(buf, "settimer"), XS__settimer, file); + newXS(strcpy(buf, "settimerMS"), XS__settimerMS, file); + newXS(strcpy(buf, "sfollow"), XS__sfollow, file); + newXS(strcpy(buf, "shout"), XS__shout, file); + newXS(strcpy(buf, "shout2"), XS__shout2, file); + newXS(strcpy(buf, "showgrid"), XS__showgrid, file); + newXS(strcpy(buf, "signal"), XS__signal, file); + newXS(strcpy(buf, "signalwith"), XS__signalwith, file); + newXS(strcpy(buf, "snow"), XS__snow, file); + newXS(strcpy(buf, "spawn"), XS__spawn, file); + newXS(strcpy(buf, "spawn2"), XS__spawn2, file); + newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file); + newXS(strcpy(buf, "spawn_from_spawn2"), XS__spawn_from_spawn2, file); + newXS(strcpy(buf, "start"), XS__start, file); + newXS(strcpy(buf, "stop"), XS__stop, file); + newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file); + newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file); + newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file); + newXS(strcpy(buf, "summonburiedplayercorpse"), XS__summonburiedplayercorpse, file); + newXS(strcpy(buf, "summonitem"), XS__summonitem, file); + newXS(strcpy(buf, "surname"), XS__surname, file); + newXS(strcpy(buf, "targlobal"), XS__targlobal, file); + newXS(strcpy(buf, "taskexploredarea"), XS__taskexploredarea, file); + newXS(strcpy(buf, "taskselector"), XS__taskselector, file); + newXS(strcpy(buf, "task_setselector"), XS__task_setselector, file); + newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file); + newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file); + newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file); + newXS(strcpy(buf, "traindisc"), XS__traindisc, file); + newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file); + newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file); + newXS(strcpy(buf, "unscribespells"), XS__unscribespells, file); + newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file); + newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file); + newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file); + newXS(strcpy(buf, "UpdateZoneHeader"), XS__UpdateZoneHeader, file); + newXS(strcpy(buf, "varlink"), XS__varlink, file); + newXS(strcpy(buf, "voicetell"), XS__voicetell, file); + newXS(strcpy(buf, "we"), XS__we, file); + newXS(strcpy(buf, "wearchange"), XS__wearchange, file); + newXS(strcpy(buf, "write"), XS__write, file); + newXS(strcpy(buf, "ze"), XS__ze, file); + newXS(strcpy(buf, "zone"), XS__zone, file); - XSRETURN_YES; + XSRETURN_YES; } #endif diff --git a/zone/encounter.h b/zone/encounter.h index e0d8dbcb0..eeeba8e0f 100644 --- a/zone/encounter.h +++ b/zone/encounter.h @@ -36,7 +36,7 @@ public: //abstract virtual function implementations required by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; } virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; } - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } diff --git a/zone/entity.cpp b/zone/entity.cpp index e54042d5a..264b8cfc9 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -647,7 +647,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0); - npc->FixZ(1); + npc->FixZ(); uint16 emoteid = npc->GetEmoteID(); if (emoteid != 0) @@ -1546,7 +1546,7 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap } } -void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *app, bool iSendToSender) +void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *app, bool iSendToSender, EQEmu::versions::ClientVersionBit client_version_bits) { auto it = client_list.begin(); while (it != client_list.end()) { @@ -1556,6 +1556,9 @@ void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *a if (!c || ((c == sender) && !iSendToSender)) continue; + if ((c->ClientVersionBit() & client_version_bits) == 0) + continue; + if (!c->IsXTarget(sender)) continue; @@ -2824,26 +2827,6 @@ void EntityList::ListPlayerCorpses(Client *client) client->Message(0, "%d player corpses listed.", x); } -void EntityList::FindPathsToAllNPCs() -{ - if (!zone->pathing) - return; - - auto it = npc_list.begin(); - while (it != npc_list.end()) { - glm::vec3 Node0 = zone->pathing->GetPathNodeCoordinates(0, false); - glm::vec3 Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ()); - std::deque Route = zone->pathing->FindRoute(Node0, Dest); - if (Route.empty()) - printf("Unable to find a route to %s\n", it->second->GetName()); - else - printf("Found a route to %s\n", it->second->GetName()); - ++it; - } - - fflush(stdout); -} - // returns the number of corpses deleted. A negative number indicates an error code. int32 EntityList::DeleteNPCCorpses() { diff --git a/zone/entity.h b/zone/entity.h index ec29b3581..f296a8cb4 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -353,11 +353,11 @@ public: void QueueClientsByTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, Mob* SkipThisMob = 0, bool ackreq = true, bool HoTT = true, uint32 ClientVersionBits = 0xFFFFFFFF, bool inspect_buffs = false); - void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true); + void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, EQEmu::versions::ClientVersionBit client_version_bits = EQEmu::versions::ClientVersionBit::bit_AllClients); void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app); void QueueManaged(Mob* sender, const EQApplicationPacket* app, bool ignore_sender=false, bool ackreq = true); - void AEAttack(Mob *attacker, float dist, int Hand = EQEmu::inventory::slotPrimary, int count = 0, bool IsFromSpell = false); + void AEAttack(Mob *attacker, float dist, int Hand = EQEmu::invslot::slotPrimary, int count = 0, bool IsFromSpell = false); void AETaunt(Client *caster, float range=0, int32 bonus_hate=0); void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0, int *max_targets = nullptr); void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true); @@ -385,7 +385,6 @@ public: void ListNPCs(Client* client, const char* arg1 = 0, const char* arg2 = 0, uint8 searchtype = 0); void ListNPCCorpses(Client* client); void ListPlayerCorpses(Client* client); - void FindPathsToAllNPCs(); int32 DeleteNPCCorpses(); int32 DeletePlayerCorpses(); void CorpseFix(Client* c); diff --git a/zone/exp.cpp b/zone/exp.cpp index 2902610a8..94f36197d 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -512,6 +512,13 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) { aaexp = had_aaexp; //watch for wrap } + // AA Sanity Checking for players who set aa exp and deleveled below allowed aa level. + if (GetLevel() <= 50 && m_epp.perAA > 0) { + Message(15, "You are below the level allowed to gain AA Experience. AA Experience set to 0%"); + aaexp = 0; + m_epp.perAA = 0; + } + // Now update our character's normal and AA xp SetEXP(exp, aaexp, resexp); } diff --git a/zone/fearpath.cpp b/zone/fearpath.cpp index 6f3580406..0593cbee2 100644 --- a/zone/fearpath.cpp +++ b/zone/fearpath.cpp @@ -19,7 +19,6 @@ #include "../common/rulesys.h" #include "map.h" -#include "pathing.h" #include "zone.h" #ifdef _WINDOWS @@ -130,23 +129,12 @@ void Mob::CalculateNewFearpoint() { if(RuleB(Pathing, Fear) && zone->pathing) { - int Node = zone->pathing->GetRandomPathNode(); + auto Node = zone->pathing->GetRandomLocation(); + if (Node.x != 0.0f || Node.y != 0.0f || Node.z != 0.0f) { - glm::vec3 Loc = zone->pathing->GetPathNodeCoordinates(Node); + ++Node.z; + m_FearWalkTarget = Node; - ++Loc.z; - - glm::vec3 CurrentPosition(GetX(), GetY(), GetZ()); - - std::deque Route = zone->pathing->FindRoute(CurrentPosition, Loc); - - if(!Route.empty()) - { - m_FearWalkTarget = glm::vec3(Loc.x, Loc.y, Loc.z); - currently_fleeing = true; - - Log(Logs::Detail, Logs::None, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z); - return; } Log(Logs::Detail, Logs::None, "No path found to selected node. Falling through to old fear point selection."); @@ -172,9 +160,7 @@ void Mob::CalculateNewFearpoint() } } - if (loop <= 100) - { - m_FearWalkTarget = glm::vec3(ranx, rany, ranz); - } + if (currently_fleeing) + m_FearWalkTarget = glm::vec3(ranx, rany, ranz); } diff --git a/zone/forage.cpp b/zone/forage.cpp index 7adb245ee..e5248cf01 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -153,7 +153,7 @@ uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id, //we need this function to immediately determine, after we receive OP_Fishing, if we can even try to fish, otherwise we have to wait a while to get the failure bool Client::CanFish() { //make sure we still have a fishing pole on: - const EQEmu::ItemInstance* Pole = m_inv[EQEmu::inventory::slotPrimary]; + const EQEmu::ItemInstance* Pole = m_inv[EQEmu::invslot::slotPrimary]; int32 bslot = m_inv.HasItemByUse(EQEmu::item::ItemTypeFishingBait, 1, invWhereWorn | invWherePersonal); const EQEmu::ItemInstance* Bait = nullptr; if (bslot != INVALID_INDEX) @@ -258,7 +258,7 @@ void Client::GoFish() Bait = m_inv.GetItem(bslot); //if the bait isnt equipped, need to add its skill bonus - if (bslot >= EQEmu::legacy::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == EQEmu::skills::SkillFishing) { + if (bslot >= EQEmu::invslot::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == EQEmu::skills::SkillFishing) { fishing_skill += Bait->GetItem()->SkillModValue; } @@ -331,12 +331,12 @@ void Client::GoFish() else { PushItemOnCursor(*inst); - SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo); if(RuleB(TaskSystem, EnableTaskSystem)) UpdateTasksForItem(ActivityFish, food_id); safe_delete(inst); - inst = m_inv.GetItem(EQEmu::inventory::slotCursor); + inst = m_inv.GetItem(EQEmu::invslot::slotCursor); } if(inst) { @@ -368,7 +368,7 @@ void Client::GoFish() //and then swap out items in primary slot... too lazy to fix right now if (zone->random.Int(0, 49) == 1) { Message_StringID(MT_Skills, FISHING_POLE_BROKE); //Your fishing pole broke! - DeleteItemInInventory(EQEmu::inventory::slotPrimary, 0, true); + DeleteItemInInventory(EQEmu::invslot::slotPrimary, 0, true); } if (CheckIncreaseSkill(EQEmu::skills::SkillFishing, nullptr, 5)) @@ -445,12 +445,12 @@ void Client::ForageItem(bool guarantee) { } else { PushItemOnCursor(*inst); - SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo); if(RuleB(TaskSystem, EnableTaskSystem)) UpdateTasksForItem(ActivityForage, foragedfood); safe_delete(inst); - inst = m_inv.GetItem(EQEmu::inventory::slotCursor); + inst = m_inv.GetItem(EQEmu::invslot::slotCursor); } if(inst) { diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 5af9da7d9..f02cbe6b6 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -207,9 +207,7 @@ void HateList::AddEntToHateList(Mob *in_entity, int32 in_hate, int32 in_damage, parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "1", 0); if (in_entity->IsClient()) { - if (hate_owner->CastToNPC()->IsRaidTarget()) - in_entity->CastToClient()->SetEngagedRaidTarget(true); - in_entity->CastToClient()->IncrementAggroCount(); + in_entity->CastToClient()->IncrementAggroCount(hate_owner->CastToNPC()->IsRaidTarget()); } } } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 17cfc1aa1..d375d94b6 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -35,7 +35,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { int i; if(where_to_check & invWhereWorn) { - for (i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; i++) { + for (i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -48,8 +48,8 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } } - if (GetItemIDAt(EQEmu::inventory::slotPowerSource) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(EQEmu::inventory::slotPowerSource) != INVALID_ID)) { - cur = m_inv.GetItem(EQEmu::inventory::slotPowerSource); + if (GetItemIDAt(EQEmu::invslot::SLOT_POWER_SOURCE) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(EQEmu::invslot::SLOT_POWER_SOURCE) != INVALID_ID)) { + cur = m_inv.GetItem(EQEmu::invslot::SLOT_POWER_SOURCE); if(cur && cur->GetItem()->Stackable) { x += cur->GetCharges(); } else { @@ -57,25 +57,25 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) - DeleteItemInInventory(EQEmu::inventory::slotPowerSource, 0, true); + DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, true); else - DeleteItemInInventory(EQEmu::inventory::slotPowerSource, 0, false); // Prevents Titanium crash + DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, false); // Prevents Titanium crash } } if(where_to_check & invWhereCursor) { - if (GetItemIDAt(EQEmu::inventory::slotCursor) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(EQEmu::inventory::slotCursor) != INVALID_ID)) { - cur = m_inv.GetItem(EQEmu::inventory::slotCursor); + if (GetItemIDAt(EQEmu::invslot::slotCursor) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(EQEmu::invslot::slotCursor) != INVALID_ID)) { + cur = m_inv.GetItem(EQEmu::invslot::slotCursor); if(cur && cur->GetItem()->Stackable) { x += cur->GetCharges(); } else { x++; } - DeleteItemInInventory(EQEmu::inventory::slotCursor, 0, true); + DeleteItemInInventory(EQEmu::invslot::slotCursor, 0, true); } - for (i = EQEmu::legacy::CURSOR_BAG_BEGIN; i <= EQEmu::legacy::CURSOR_BAG_END; i++) { + for (i = EQEmu::invbag::CURSOR_BAG_BEGIN; i <= EQEmu::invbag::CURSOR_BAG_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -90,7 +90,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } if(where_to_check & invWherePersonal) { - for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++) { + for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -103,7 +103,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } } - for (i = EQEmu::legacy::GENERAL_BAGS_BEGIN; i <= EQEmu::legacy::GENERAL_BAGS_END; i++) { + for (i = EQEmu::invbag::GENERAL_BAGS_BEGIN; i <= EQEmu::invbag::GENERAL_BAGS_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -118,7 +118,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } if(where_to_check & invWhereBank) { - for (i = EQEmu::legacy::BANK_BEGIN; i <= EQEmu::legacy::BANK_END; i++) { + for (i = EQEmu::invslot::BANK_BEGIN; i <= EQEmu::invslot::BANK_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -131,7 +131,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } } - for (i = EQEmu::legacy::BANK_BAGS_BEGIN; i <= EQEmu::legacy::BANK_BAGS_END; i++) { + for (i = EQEmu::invbag::BANK_BAGS_BEGIN; i <= EQEmu::invbag::BANK_BAGS_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -146,7 +146,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } if(where_to_check & invWhereSharedBank) { - for (i = EQEmu::legacy::SHARED_BANK_BEGIN; i <= EQEmu::legacy::SHARED_BANK_END; i++) { + for (i = EQEmu::invslot::SHARED_BANK_BEGIN; i <= EQEmu::invslot::SHARED_BANK_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -159,7 +159,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } } - for (i = EQEmu::legacy::SHARED_BANK_BAGS_BEGIN; i <= EQEmu::legacy::SHARED_BANK_BAGS_END; i++) { + for (i = EQEmu::invbag::SHARED_BANK_BAGS_BEGIN; i <= EQEmu::invbag::SHARED_BANK_BAGS_END; i++) { if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) { cur = m_inv.GetItem(i); if(cur && cur->GetItem()->Stackable) { @@ -236,7 +236,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, } */ - uint32 augments[EQEmu::inventory::SocketCount] = { aug1, aug2, aug3, aug4, aug5, aug6 }; + uint32 augments[EQEmu::invaug::SOCKET_COUNT] = { aug1, aug2, aug3, aug4, aug5, aug6 }; uint32 classes = item->Classes; uint32 races = item->Races; @@ -246,7 +246,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, bool enforcerestr = RuleB(Inventory, EnforceAugmentRestriction); bool enforceusable = RuleB(Inventory, EnforceAugmentUsability); - for (int iter = EQEmu::inventory::socketBegin; iter < EQEmu::inventory::SocketCount; ++iter) { + for (int iter = EQEmu::invaug::SOCKET_BEGIN; iter <= EQEmu::invaug::SOCKET_END; ++iter) { const EQEmu::ItemData* augtest = database.GetItem(augments[iter]); if(augtest == nullptr) { @@ -540,7 +540,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, } // add any validated augments - for (int iter = EQEmu::inventory::socketBegin; iter < EQEmu::inventory::SocketCount; ++iter) { + for (int iter = EQEmu::invaug::SOCKET_BEGIN; iter <= EQEmu::invaug::SOCKET_END; ++iter) { if(augments[iter]) inst->PutAugment(&database, iter, augments[iter]); } @@ -554,22 +554,22 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, inst->SetOrnamentHeroModel(ornament_hero_model); // check to see if item is usable in requested slot - if (enforceusable && (((to_slot >= EQEmu::inventory::slotCharm) && (to_slot <= EQEmu::inventory::slotAmmo)) || (to_slot == EQEmu::inventory::slotPowerSource))) { - uint32 slottest = (to_slot == EQEmu::inventory::slotPowerSource) ? 22 : to_slot; // can't change '22' just yet... + if (enforceusable && (((to_slot >= EQEmu::invslot::slotCharm) && (to_slot <= EQEmu::invslot::slotAmmo)) || (to_slot == EQEmu::invslot::SLOT_POWER_SOURCE))) { + uint32 slottest = (to_slot == EQEmu::invslot::SLOT_POWER_SOURCE) ? 22 : to_slot; // can't change '22' just yet... if(!(slots & ((uint32)1 << slottest))) { Message(0, "This item is not equipable at slot %u - moving to cursor.", to_slot); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to equip an item unusable in slot %u - moved to cursor.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, to_slot, item->ID, aug1, aug2, aug3, aug4, aug5, aug6); - to_slot = EQEmu::inventory::slotCursor; + to_slot = EQEmu::invslot::slotCursor; } } // put item into inventory - if (to_slot == EQEmu::inventory::slotCursor) { + if (to_slot == EQEmu::invslot::slotCursor) { PushItemOnCursor(*inst); - SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo); } else { PutItemInInventory(to_slot, *inst, true); @@ -671,7 +671,7 @@ void Client::DropItem(int16 slot_id, bool recurse) } // Save client inventory change to database - if (slot_id == EQEmu::inventory::slotCursor) { + if (slot_id == EQEmu::invslot::slotCursor) { SendCursorBuffer(); auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(CharacterID(), s, e); @@ -762,11 +762,11 @@ void Client::SendCursorBuffer() GetName(), test_item->Name, test_item->ID); Message_StringID(MT_LootMessages, 290); parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); - DeleteItemInInventory(EQEmu::inventory::slotCursor); + DeleteItemInInventory(EQEmu::invslot::slotCursor); SendCursorBuffer(); } else { - SendItemPacket(EQEmu::inventory::slotCursor, test_inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, test_inst, ItemPacketLimbo); } } @@ -819,7 +819,7 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd qsaudit->items[parent_offset].aug_5 = m_inv[slot_id]->GetAugmentItemID(5); if (m_inv[slot_id]->IsClassBag()) { - for (uint8 bag_idx = EQEmu::inventory::containerBegin; bag_idx < m_inv[slot_id]->GetItem()->BagSlots; bag_idx++) { + for (uint8 bag_idx = EQEmu::invbag::SLOT_BEGIN; bag_idx < m_inv[slot_id]->GetItem()->BagSlots; bag_idx++) { EQEmu::ItemInstance* bagitem = m_inv[slot_id]->GetItem(bag_idx); if(bagitem) { @@ -845,7 +845,7 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd bool isDeleted = m_inv.DeleteItem(slot_id, quantity); const EQEmu::ItemInstance* inst = nullptr; - if (slot_id == EQEmu::inventory::slotCursor) { + if (slot_id == EQEmu::invslot::slotCursor) { auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); if(update_db) database.SaveCursor(character_id, s, e); @@ -897,7 +897,7 @@ bool Client::PushItemOnCursor(const EQEmu::ItemInstance& inst, bool client_updat m_inv.PushCursor(inst); if (client_update) { - SendItemPacket(EQEmu::inventory::slotCursor, &inst, ItemPacketLimbo); + SendItemPacket(EQEmu::invslot::slotCursor, &inst, ItemPacketLimbo); } auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); @@ -911,7 +911,7 @@ bool Client::PushItemOnCursor(const EQEmu::ItemInstance& inst, bool client_updat bool Client::PutItemInInventory(int16 slot_id, const EQEmu::ItemInstance& inst, bool client_update) { Log(Logs::Detail, Logs::Inventory, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id); - if (slot_id == EQEmu::inventory::slotCursor) { // don't trust macros before conditional statements... + if (slot_id == EQEmu::invslot::slotCursor) { // don't trust macros before conditional statements... return PushItemOnCursor(inst, client_update); } else { @@ -920,11 +920,11 @@ bool Client::PutItemInInventory(int16 slot_id, const EQEmu::ItemInstance& inst, if (client_update) { - SendItemPacket(slot_id, &inst, ((slot_id == EQEmu::inventory::slotCursor) ? ItemPacketLimbo : ItemPacketTrade)); + SendItemPacket(slot_id, &inst, ((slot_id == EQEmu::invslot::slotCursor) ? ItemPacketLimbo : ItemPacketTrade)); //SendWearChange(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id)); } - if (slot_id == EQEmu::inventory::slotCursor) { + if (slot_id == EQEmu::invslot::slotCursor) { auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); return database.SaveCursor(this->CharacterID(), s, e); } @@ -942,7 +942,7 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst, bool cursor_empty = m_inv.CursorEmpty(); - if (slot_id == EQEmu::inventory::slotCursor) { + if (slot_id == EQEmu::invslot::slotCursor) { m_inv.PushCursor(inst); auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(this->CharacterID(), s, e); @@ -953,7 +953,7 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst, } // Subordinate items in cursor buffer must be sent via ItemPacketSummonItem or we just overwrite the visible cursor and desync the client - if (slot_id == EQEmu::inventory::slotCursor && !cursor_empty) { + if (slot_id == EQEmu::invslot::slotCursor && !cursor_empty) { // RoF+ currently has a specialized cursor handler if (ClientVersion() < EQEmu::versions::ClientVersion::RoF) SendItemPacket(slot_id, &inst, ItemPacketLimbo); @@ -963,7 +963,7 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst, } if (bag_item_data) { - for (int index = 0; index < EQEmu::inventory::ContainerCount; ++index) { + for (int index = 0; index < EQEmu::invbag::SLOT_COUNT; ++index) { if (bag_item_data[index] == nullptr) continue; @@ -981,12 +981,12 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst, // Dump bag contents to cursor in the event that owning bag is not the first cursor item // (This assumes that the data passed is correctly associated..no safety checks are implemented) - if (slot_id == EQEmu::inventory::slotCursor && !cursor_empty) { + if (slot_id == EQEmu::invslot::slotCursor && !cursor_empty) { Log(Logs::Detail, Logs::Inventory, "Putting bag loot item %s (%d) into slot %d (non-empty cursor override)", - inst.GetItem()->Name, inst.GetItem()->ID, EQEmu::inventory::slotCursor); + inst.GetItem()->Name, inst.GetItem()->ID, EQEmu::invslot::slotCursor); - PutLootInInventory(EQEmu::inventory::slotCursor, *bagitem); + PutLootInInventory(EQEmu::invslot::slotCursor, *bagitem); } else { auto bag_slot = EQEmu::InventoryProfile::CalcSlotId(slot_id, index); @@ -1008,7 +1008,7 @@ bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, b return false; int16 i; uint32 item_id = item->GetItem()->ID; - for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++) { + for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) { EQEmu::ItemInstance* tmp_inst = m_inv.GetItem(i); if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize){ MoveItemCharges(*item, i, type); @@ -1019,8 +1019,8 @@ bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, b return true; } } - for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++) { - for (uint8 j = EQEmu::inventory::containerBegin; j < EQEmu::inventory::ContainerCount; j++) { + for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) { + for (uint8 j = EQEmu::invbag::SLOT_BEGIN; j <= EQEmu::invbag::SLOT_END; j++) { uint16 slotid = EQEmu::InventoryProfile::CalcSlotId(i, j); EQEmu::ItemInstance* tmp_inst = m_inv.GetItem(slotid); @@ -1045,28 +1045,28 @@ bool Client::AutoPutLootInInventory(EQEmu::ItemInstance& inst, bool try_worn, bo // #1: Try to auto equip if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel <= level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != EQEmu::item::ItemTypeAugmentation) { // too messy as-is... - for (int16 i = EQEmu::legacy::EQUIPMENT_BEGIN; i < EQEmu::inventory::slotPowerSource; i++) { // originally (i < 22) - if (i == EQEmu::legacy::GENERAL_BEGIN) { + for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i < EQEmu::invslot::SLOT_POWER_SOURCE; i++) { // originally (i < 22) + if (i == EQEmu::invslot::GENERAL_BEGIN) { // added power source check for SoF+ clients if (this->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) - i = EQEmu::inventory::slotPowerSource; + i = EQEmu::invslot::SLOT_POWER_SOURCE; else break; } if (!m_inv[i]) { - if (i == EQEmu::inventory::slotPrimary && inst.IsWeapon()) { // If item is primary slot weapon + if (i == EQEmu::invslot::slotPrimary && inst.IsWeapon()) { // If item is primary slot weapon if (inst.GetItem()->IsType2HWeapon()) { // and uses 2hs \ 2hb \ 2hp - if (m_inv[EQEmu::inventory::slotSecondary]) { // and if secondary slot is not empty + if (m_inv[EQEmu::invslot::slotSecondary]) { // and if secondary slot is not empty continue; // Can't auto-equip } } } - if (i == EQEmu::inventory::slotSecondary && m_inv[EQEmu::inventory::slotPrimary]) { // check to see if primary slot is a two hander - if (m_inv[EQEmu::inventory::slotPrimary]->GetItem()->IsType2HWeapon()) + if (i == EQEmu::invslot::slotSecondary && m_inv[EQEmu::invslot::slotPrimary]) { // check to see if primary slot is a two hander + if (m_inv[EQEmu::invslot::slotPrimary]->GetItem()->IsType2HWeapon()) continue; } - if (i == EQEmu::inventory::slotSecondary && inst.IsWeapon() && !CanThisClassDualWield()) { + if (i == EQEmu::invslot::slotSecondary && inst.IsWeapon() && !CanThisClassDualWield()) { continue; } @@ -1117,7 +1117,7 @@ void Client::MoveItemCharges(EQEmu::ItemInstance &from, int16 to_slot, uint8 typ tmp_inst->SetCharges(tmp_inst->GetCharges() + charges_to_move); from.SetCharges(from.GetCharges() - charges_to_move); SendLootItemInPacket(tmp_inst, to_slot); - if (to_slot == EQEmu::inventory::slotCursor) { + if (to_slot == EQEmu::invslot::slotCursor) { auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(this->CharacterID(), s, e); } @@ -1374,16 +1374,16 @@ void Client::SendLootItemInPacket(const EQEmu::ItemInstance* inst, int16 slot_id bool Client::IsValidSlot(uint32 slot) { if ((slot == (uint32)INVALID_INDEX) || - (slot >= EQEmu::inventory::slotBegin && slot < EQEmu::legacy::TYPE_POSSESSIONS_SIZE) || - (slot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && slot <= EQEmu::legacy::CURSOR_BAG_END) || - (slot >= EQEmu::legacy::TRIBUTE_BEGIN && slot <= EQEmu::legacy::TRIBUTE_END) || - (slot >= EQEmu::legacy::BANK_BEGIN && slot <= EQEmu::legacy::BANK_END) || - (slot >= EQEmu::legacy::BANK_BAGS_BEGIN && slot <= EQEmu::legacy::BANK_BAGS_END) || - (slot >= EQEmu::legacy::SHARED_BANK_BEGIN && slot <= EQEmu::legacy::SHARED_BANK_END) || - (slot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && slot <= EQEmu::legacy::SHARED_BANK_BAGS_END) || - (slot >= EQEmu::legacy::TRADE_BEGIN && slot <= EQEmu::legacy::TRADE_END) || - (slot >= EQEmu::legacy::WORLD_BEGIN && slot <= EQEmu::legacy::WORLD_END) || - (slot == EQEmu::inventory::slotPowerSource) + (slot >= EQEmu::invslot::POSSESSIONS_BEGIN && slot <= EQEmu::invslot::POSSESSIONS_END) || + (slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && slot <= EQEmu::invbag::CURSOR_BAG_END) || + (slot >= EQEmu::invslot::TRIBUTE_BEGIN && slot <= EQEmu::invslot::TRIBUTE_END) || + (slot >= EQEmu::invslot::BANK_BEGIN && slot <= EQEmu::invslot::BANK_END) || + (slot >= EQEmu::invbag::BANK_BAGS_BEGIN && slot <= EQEmu::invbag::BANK_BAGS_END) || + (slot >= EQEmu::invslot::SHARED_BANK_BEGIN && slot <= EQEmu::invslot::SHARED_BANK_END) || + (slot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && slot <= EQEmu::invbag::SHARED_BANK_BAGS_END) || + (slot >= EQEmu::invslot::TRADE_BEGIN && slot <= EQEmu::invslot::TRADE_END) || + (slot >= EQEmu::invslot::WORLD_BEGIN && slot <= EQEmu::invslot::WORLD_END) || + (slot == EQEmu::invslot::SLOT_POWER_SOURCE) ) { return true; } @@ -1394,10 +1394,10 @@ bool Client::IsValidSlot(uint32 slot) { bool Client::IsBankSlot(uint32 slot) { - if ((slot >= EQEmu::legacy::BANK_BEGIN && slot <= EQEmu::legacy::BANK_END) || - (slot >= EQEmu::legacy::BANK_BAGS_BEGIN && slot <= EQEmu::legacy::BANK_BAGS_END) || - (slot >= EQEmu::legacy::SHARED_BANK_BEGIN && slot <= EQEmu::legacy::SHARED_BANK_END) || - (slot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && slot <= EQEmu::legacy::SHARED_BANK_BAGS_END)) + if ((slot >= EQEmu::invslot::BANK_BEGIN && slot <= EQEmu::invslot::BANK_END) || + (slot >= EQEmu::invbag::BANK_BAGS_BEGIN && slot <= EQEmu::invbag::BANK_BAGS_END) || + (slot >= EQEmu::invslot::SHARED_BANK_BEGIN && slot <= EQEmu::invslot::SHARED_BANK_END) || + (slot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && slot <= EQEmu::invbag::SHARED_BANK_BAGS_END)) { return true; } @@ -1433,8 +1433,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF) { return true; } // Can't do RoF+ - if (move_in->to_slot == EQEmu::inventory::slotCursor) { - auto test_inst = m_inv.GetItem(EQEmu::inventory::slotCursor); + if (move_in->to_slot == EQEmu::invslot::slotCursor) { + auto test_inst = m_inv.GetItem(EQEmu::invslot::slotCursor); if (test_inst == nullptr) { return true; } auto test_item = test_inst->GetItem(); if (test_item == nullptr) { return true; } @@ -1453,18 +1453,18 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { GetName(), test_item->Name, test_item->ID); Message_StringID(MT_LootMessages, 290); parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); - DeleteItemInInventory(EQEmu::inventory::slotCursor, 0, true); + DeleteItemInInventory(EQEmu::invslot::slotCursor, 0, true); } } return true; } if (move_in->to_slot == (uint32)INVALID_INDEX) { - if (move_in->from_slot == (uint32)EQEmu::inventory::slotCursor) { + if (move_in->from_slot == (uint32)EQEmu::invslot::slotCursor) { Log(Logs::Detail, Logs::Inventory, "Client destroyed item from cursor slot %d", move_in->from_slot); if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit - EQEmu::ItemInstance *inst = m_inv.GetItem(EQEmu::inventory::slotCursor); + EQEmu::ItemInstance *inst = m_inv.GetItem(EQEmu::invslot::slotCursor); if(inst) { parse->EventItem(EVENT_DESTROY_ITEM, this, inst, nullptr, "", 0); } @@ -1481,9 +1481,9 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { return true; // Item deletion } } - if (auto_attack && (move_in->from_slot == EQEmu::inventory::slotPrimary || move_in->from_slot == EQEmu::inventory::slotSecondary || move_in->from_slot == EQEmu::inventory::slotRange)) + if (auto_attack && (move_in->from_slot == EQEmu::invslot::slotPrimary || move_in->from_slot == EQEmu::invslot::slotSecondary || move_in->from_slot == EQEmu::invslot::slotRange)) SetAttackTimer(); - else if (auto_attack && (move_in->to_slot == EQEmu::inventory::slotPrimary || move_in->to_slot == EQEmu::inventory::slotSecondary || move_in->to_slot == EQEmu::inventory::slotRange)) + else if (auto_attack && (move_in->to_slot == EQEmu::invslot::slotPrimary || move_in->to_slot == EQEmu::invslot::slotSecondary || move_in->to_slot == EQEmu::invslot::slotRange)) SetAttackTimer(); // Step 1: Variables int16 src_slot_id = (int16)move_in->from_slot; @@ -1531,13 +1531,13 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { uint32 dstbagid = 0; //if (src_slot_id >= 250 && src_slot_id < 330) { - if (src_slot_id >= EQEmu::legacy::GENERAL_BAGS_BEGIN && src_slot_id <= EQEmu::legacy::GENERAL_BAGS_END) { + if (src_slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN && src_slot_id <= EQEmu::invbag::GENERAL_BAGS_END) { srcbag = m_inv.GetItem(((int)(src_slot_id / 10)) - 3); if (srcbag) srcbagid = srcbag->GetItem()->ID; } //if (dst_slot_id >= 250 && dst_slot_id < 330) { - if (dst_slot_id >= EQEmu::legacy::GENERAL_BAGS_BEGIN && dst_slot_id <= EQEmu::legacy::GENERAL_BAGS_END) { + if (dst_slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN && dst_slot_id <= EQEmu::invbag::GENERAL_BAGS_END) { dstbag = m_inv.GetItem(((int)(dst_slot_id / 10)) - 3); if (dstbag) dstbagid = dstbag->GetItem()->ID; @@ -1550,7 +1550,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Step 2: Validate item in from_slot // After this, we can assume src_inst is a valid ptr - if (!src_inst && (src_slot_id < EQEmu::legacy::WORLD_BEGIN || src_slot_id > EQEmu::legacy::WORLD_END)) { + if (!src_inst && (src_slot_id < EQEmu::invslot::WORLD_BEGIN || src_slot_id > EQEmu::invslot::WORLD_END)) { if (dst_inst) { // If there is no source item, but there is a destination item, // move the slots around before deleting the invalid source slot item, @@ -1564,14 +1564,14 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { return false; } //verify shared bank transactions in the database - if (src_inst && src_slot_id >= EQEmu::legacy::SHARED_BANK_BEGIN && src_slot_id <= EQEmu::legacy::SHARED_BANK_BAGS_END) { + if (src_inst && src_slot_id >= EQEmu::invslot::SHARED_BANK_BEGIN && src_slot_id <= EQEmu::invbag::SHARED_BANK_BAGS_END) { if(!database.VerifyInventory(account_id, src_slot_id, src_inst)) { Log(Logs::General, Logs::Error, "Player %s on account %s was found exploiting the shared bank.\n", GetName(), account_name); DeleteItemInInventory(dst_slot_id,0,true); return(false); } - if (src_slot_id >= EQEmu::legacy::SHARED_BANK_BEGIN && src_slot_id <= EQEmu::legacy::SHARED_BANK_END && src_inst->IsClassBag()){ - for (uint8 idx = EQEmu::inventory::containerBegin; idx < EQEmu::inventory::ContainerCount; idx++) { + if (src_slot_id >= EQEmu::invslot::SHARED_BANK_BEGIN && src_slot_id <= EQEmu::invslot::SHARED_BANK_END && src_inst->IsClassBag()){ + for (uint8 idx = EQEmu::invbag::SLOT_BEGIN; idx <= EQEmu::invbag::SLOT_END; idx++) { const EQEmu::ItemInstance* baginst = src_inst->GetItem(idx); if (baginst && !database.VerifyInventory(account_id, EQEmu::InventoryProfile::CalcSlotId(src_slot_id, idx), baginst)){ DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(src_slot_id, idx), 0, false); @@ -1579,14 +1579,14 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } } } - if (dst_inst && dst_slot_id >= EQEmu::legacy::SHARED_BANK_BEGIN && dst_slot_id <= EQEmu::legacy::SHARED_BANK_BAGS_END) { + if (dst_inst && dst_slot_id >= EQEmu::invslot::SHARED_BANK_BEGIN && dst_slot_id <= EQEmu::invbag::SHARED_BANK_BAGS_END) { if(!database.VerifyInventory(account_id, dst_slot_id, dst_inst)) { Log(Logs::General, Logs::Error, "Player %s on account %s was found exploting the shared bank.\n", GetName(), account_name); DeleteItemInInventory(src_slot_id,0,true); return(false); } - if (dst_slot_id >= EQEmu::legacy::SHARED_BANK_BEGIN && dst_slot_id <= EQEmu::legacy::SHARED_BANK_END && dst_inst->IsClassBag()){ - for (uint8 idx = EQEmu::inventory::containerBegin; idx < EQEmu::inventory::ContainerCount; idx++) { + if (dst_slot_id >= EQEmu::invslot::SHARED_BANK_BEGIN && dst_slot_id <= EQEmu::invslot::SHARED_BANK_END && dst_inst->IsClassBag()){ + for (uint8 idx = EQEmu::invbag::SLOT_BEGIN; idx <= EQEmu::invbag::SLOT_END; idx++) { const EQEmu::ItemInstance* baginst = dst_inst->GetItem(idx); if (baginst && !database.VerifyInventory(account_id, EQEmu::InventoryProfile::CalcSlotId(dst_slot_id, idx), baginst)){ DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(dst_slot_id, idx), 0, false); @@ -1598,8 +1598,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Check for No Drop Hacks Mob* with = trade->With(); - if (((with && with->IsClient() && dst_slot_id >= EQEmu::legacy::TRADE_BEGIN && dst_slot_id <= EQEmu::legacy::TRADE_END) || - (dst_slot_id >= EQEmu::legacy::SHARED_BANK_BEGIN && dst_slot_id <= EQEmu::legacy::SHARED_BANK_BAGS_END)) + if (((with && with->IsClient() && dst_slot_id >= EQEmu::invslot::TRADE_BEGIN && dst_slot_id <= EQEmu::invslot::TRADE_END) || + (dst_slot_id >= EQEmu::invslot::SHARED_BANK_BEGIN && dst_slot_id <= EQEmu::invbag::SHARED_BANK_BAGS_END)) && GetInv().CheckNoDrop(src_slot_id) && RuleI(World, FVNoDropFlag) == 0 || RuleI(Character, MinStatusForNoDropExemptions) < Admin() && RuleI(World, FVNoDropFlag) == 2) { auto ndh_inst = m_inv[src_slot_id]; @@ -1629,7 +1629,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Step 3: Check for interaction with World Container (tradeskills) if(m_tradeskill_object != nullptr) { - if (src_slot_id >= EQEmu::legacy::WORLD_BEGIN && src_slot_id <= EQEmu::legacy::WORLD_END) { + if (src_slot_id >= EQEmu::invslot::WORLD_BEGIN && src_slot_id <= EQEmu::invslot::WORLD_END) { // Picking up item from world container EQEmu::ItemInstance* inst = m_tradeskill_object->PopItem(EQEmu::InventoryProfile::CalcBagIdx(src_slot_id)); if (inst) { @@ -1641,7 +1641,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { return true; } - else if (dst_slot_id >= EQEmu::legacy::WORLD_BEGIN && dst_slot_id <= EQEmu::legacy::WORLD_END) { + else if (dst_slot_id >= EQEmu::invslot::WORLD_BEGIN && dst_slot_id <= EQEmu::invslot::WORLD_END) { // Putting item into world container, which may swap (or pile onto) with existing item uint8 world_idx = EQEmu::InventoryProfile::CalcBagIdx(dst_slot_id); EQEmu::ItemInstance* world_inst = m_tradeskill_object->PopItem(world_idx); @@ -1693,7 +1693,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } safe_delete(world_inst); - if (src_slot_id == EQEmu::inventory::slotCursor) + if (src_slot_id == EQEmu::invslot::slotCursor) { if (dstitemid == 0) { @@ -1714,15 +1714,15 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } // Step 4: Check for entity trade - if (dst_slot_id >= EQEmu::legacy::TRADE_BEGIN && dst_slot_id <= EQEmu::legacy::TRADE_END) { - if (src_slot_id != EQEmu::inventory::slotCursor) { + if (dst_slot_id >= EQEmu::invslot::TRADE_BEGIN && dst_slot_id <= EQEmu::invslot::TRADE_END) { + if (src_slot_id != EQEmu::invslot::slotCursor) { Kick(); return false; } if (with) { Log(Logs::Detail, Logs::Inventory, "Trade item move from slot %d to slot %d (trade with %s)", src_slot_id, dst_slot_id, with->GetName()); // Fill Trade list with items from cursor - if (!m_inv[EQEmu::inventory::slotCursor]) { + if (!m_inv[EQEmu::invslot::slotCursor]) { Message(13, "Error: Cursor item not located on server!"); return false; } @@ -1742,7 +1742,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit SummonItem(src_inst->GetID(), src_inst->GetCharges()); - DeleteItemInInventory(EQEmu::inventory::slotCursor); + DeleteItemInInventory(EQEmu::invslot::slotCursor); return true; } @@ -1808,12 +1808,12 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } else { // Not dealing with charges - just do direct swap - if (src_inst && (dst_slot_id <= EQEmu::legacy::EQUIPMENT_END || dst_slot_id == EQEmu::inventory::slotPowerSource) && dst_slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) { + if (src_inst && (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END || dst_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) && dst_slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) { if (src_inst->GetItem()->Attuneable) { src_inst->SetAttuned(true); } if (src_inst->IsAugmented()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { if (src_inst->GetAugment(i)) { if (src_inst->GetAugment(i)->GetItem()->Attuneable) { src_inst->GetAugment(i)->SetAttuned(true); @@ -1840,7 +1840,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { Log(Logs::Detail, Logs::Inventory, "Moving entire item from slot %d to slot %d", src_slot_id, dst_slot_id); - if (src_slot_id <= EQEmu::legacy::EQUIPMENT_END || src_slot_id == EQEmu::inventory::slotPowerSource) { + if (src_slot_id <= EQEmu::invslot::EQUIPMENT_END || src_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) { if(src_inst) { parse->EventItem(EVENT_UNEQUIP_ITEM, this, src_inst, nullptr, "", src_slot_id); } @@ -1850,7 +1850,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } } - if (dst_slot_id <= EQEmu::legacy::EQUIPMENT_END || dst_slot_id == EQEmu::inventory::slotPowerSource) { + if (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END || dst_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) { if(dst_inst) { parse->EventItem(EVENT_UNEQUIP_ITEM, this, dst_inst, nullptr, "", dst_slot_id); } @@ -1862,12 +1862,12 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } int matslot = SlotConvert2(dst_slot_id); - if (dst_slot_id <= EQEmu::legacy::EQUIPMENT_END && matslot != EQEmu::textures::armorHead) { // think this is to allow the client to update with /showhelm + if (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END && matslot != EQEmu::textures::armorHead) { // think this is to allow the client to update with /showhelm SendWearChange(matslot); } // Step 7: Save change to the database - if (src_slot_id == EQEmu::inventory::slotCursor) { + if (src_slot_id == EQEmu::invslot::slotCursor) { // If not swapping another item to cursor and stacking items were depleted if (dstitemid == 0 || all_to_stack == true) { @@ -1880,7 +1880,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { database.SaveInventory(character_id, m_inv.GetItem(src_slot_id), src_slot_id); } - if (dst_slot_id == EQEmu::inventory::slotCursor) { + if (dst_slot_id == EQEmu::invslot::slotCursor) { auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(character_id, s, e); } @@ -1904,7 +1904,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { Log(Logs::Detail, Logs::Inventory, "Inventory desyncronization. (charname: %s, source: %i, destination: %i)", GetName(), move_slots->from_slot, move_slots->to_slot); Message(15, "Inventory Desyncronization detected: Resending slot data..."); - if ((move_slots->from_slot >= EQEmu::legacy::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::legacy::CURSOR_BAG_END) || move_slots->from_slot == EQEmu::inventory::slotPowerSource) { + if ((move_slots->from_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::invbag::CURSOR_BAG_END) || move_slots->from_slot == EQEmu::invslot::SLOT_POWER_SOURCE) { int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { // This prevents the client from crashing when closing any 'phantom' bags @@ -1947,7 +1947,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); } } - if ((move_slots->to_slot >= EQEmu::legacy::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::legacy::CURSOR_BAG_END) || move_slots->to_slot == EQEmu::inventory::slotPowerSource) { + if ((move_slots->to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::invbag::CURSOR_BAG_END) || move_slots->to_slot == EQEmu::invslot::SLOT_POWER_SOURCE) { int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { const EQEmu::ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' @@ -2029,7 +2029,7 @@ void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) { qsaudit->items[move_count++].aug_5 = from_inst->GetAugmentItemID(5); if (from_inst->IsType(EQEmu::item::ItemClassBag)) { - for (uint8 bag_idx = EQEmu::inventory::containerBegin; bag_idx < from_inst->GetItem()->BagSlots; bag_idx++) { + for (uint8 bag_idx = EQEmu::invbag::SLOT_BEGIN; bag_idx < from_inst->GetItem()->BagSlots; bag_idx++) { const EQEmu::ItemInstance* from_baginst = from_inst->GetItem(bag_idx); if(from_baginst) { @@ -2062,7 +2062,7 @@ void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) { qsaudit->items[move_count++].aug_5 = to_inst->GetAugmentItemID(5); if (to_inst->IsType(EQEmu::item::ItemClassBag)) { - for (uint8 bag_idx = EQEmu::inventory::containerBegin; bag_idx < to_inst->GetItem()->BagSlots; bag_idx++) { + for (uint8 bag_idx = EQEmu::invbag::SLOT_BEGIN; bag_idx < to_inst->GetItem()->BagSlots; bag_idx++) { const EQEmu::ItemInstance* to_baginst = to_inst->GetItem(bag_idx); if(to_baginst) { @@ -2182,10 +2182,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { EQEmu::ItemInstance* ins = nullptr; int x; int num = 0; - for(x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::GENERAL_BAGS_END; x++) + for(x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; x++) { - if (x == EQEmu::inventory::slotCursor + 1) - x = EQEmu::legacy::GENERAL_BAGS_BEGIN; + if (x == EQEmu::invslot::slotCursor + 1) + x = EQEmu::invbag::GENERAL_BAGS_BEGIN; TempItem = nullptr; ins = GetInv().GetItem(x); if (ins) @@ -2199,10 +2199,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { } if (num < amt) return false; - for(x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::GENERAL_BAGS_END; x++) // should this be CURSOR_BAG_END? + for(x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; x++) // should this be CURSOR_BAG_END? { - if (x == EQEmu::inventory::slotCursor + 1) - x = EQEmu::legacy::GENERAL_BAGS_BEGIN; + if (x == EQEmu::invslot::slotCursor + 1) + x = EQEmu::invbag::GENERAL_BAGS_BEGIN; TempItem = nullptr; ins = GetInv().GetItem(x); if (ins) @@ -2298,7 +2298,7 @@ static bool CopyBagContents(EQEmu::ItemInstance* new_bag, const EQEmu::ItemInsta void Client::DisenchantSummonedBags(bool client_update) { - for (auto slot_id = EQEmu::legacy::GENERAL_BEGIN; slot_id <= EQEmu::legacy::GENERAL_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) { auto inst = m_inv[slot_id]; if (!inst) { continue; } if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } @@ -2319,7 +2319,7 @@ void Client::DisenchantSummonedBags(bool client_update) safe_delete(new_inst); } - for (auto slot_id = EQEmu::legacy::BANK_BEGIN; slot_id <= EQEmu::legacy::BANK_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) { auto inst = m_inv[slot_id]; if (!inst) { continue; } if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } @@ -2340,7 +2340,7 @@ void Client::DisenchantSummonedBags(bool client_update) safe_delete(new_inst); } - for (auto slot_id = EQEmu::legacy::SHARED_BANK_BEGIN; slot_id <= EQEmu::legacy::SHARED_BANK_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::SHARED_BANK_BEGIN; slot_id <= EQEmu::invslot::SHARED_BANK_END; ++slot_id) { auto inst = m_inv[slot_id]; if (!inst) { continue; } if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } @@ -2362,7 +2362,7 @@ void Client::DisenchantSummonedBags(bool client_update) } while (!m_inv.CursorEmpty()) { - auto inst = m_inv[EQEmu::inventory::slotCursor]; + auto inst = m_inv[EQEmu::invslot::slotCursor]; if (!inst) { break; } if (!IsSummonedBagID(inst->GetItem()->ID)) { break; } if (!inst->GetItem()->IsClassBag()) { break; } @@ -2376,14 +2376,14 @@ void Client::DisenchantSummonedBags(bool client_update) if (!new_inst) { break; } if (CopyBagContents(new_inst, inst)) { - Log(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, EQEmu::inventory::slotCursor); + Log(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, EQEmu::invslot::slotCursor); std::list local; local.push_front(new_inst); - m_inv.PopItem(EQEmu::inventory::slotCursor); + m_inv.PopItem(EQEmu::invslot::slotCursor); safe_delete(inst); while (!m_inv.CursorEmpty()) { - auto limbo_inst = m_inv.PopItem(EQEmu::inventory::slotCursor); + auto limbo_inst = m_inv.PopItem(EQEmu::invslot::slotCursor); if (limbo_inst == nullptr) { continue; } local.push_back(limbo_inst); } @@ -2409,7 +2409,7 @@ void Client::DisenchantSummonedBags(bool client_update) void Client::RemoveNoRent(bool client_update) { - for (auto slot_id = EQEmu::legacy::EQUIPMENT_BEGIN; slot_id <= EQEmu::legacy::EQUIPMENT_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) { auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2417,7 +2417,7 @@ void Client::RemoveNoRent(bool client_update) } } - for (auto slot_id = EQEmu::legacy::GENERAL_BEGIN; slot_id <= EQEmu::legacy::GENERAL_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) { auto inst = m_inv[slot_id]; if (inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2425,15 +2425,15 @@ void Client::RemoveNoRent(bool client_update) } } - if (m_inv[EQEmu::inventory::slotPowerSource]) { - auto inst = m_inv[EQEmu::inventory::slotPowerSource]; + if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) { + auto inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]; if (inst && !inst->GetItem()->NoRent) { - Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::inventory::slotPowerSource); - DeleteItemInInventory(EQEmu::inventory::slotPowerSource, 0, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false); // Ti slot non-existent + Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE); + DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false); // Ti slot non-existent } } - for (auto slot_id = EQEmu::legacy::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::legacy::CURSOR_BAG_END; ++slot_id) { + for (auto slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::CURSOR_BAG_END; ++slot_id) { auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2441,7 +2441,7 @@ void Client::RemoveNoRent(bool client_update) } } - for (auto slot_id = EQEmu::legacy::BANK_BEGIN; slot_id <= EQEmu::legacy::BANK_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) { auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2449,7 +2449,7 @@ void Client::RemoveNoRent(bool client_update) } } - for (auto slot_id = EQEmu::legacy::BANK_BAGS_BEGIN; slot_id <= EQEmu::legacy::BANK_BAGS_END; ++slot_id) { + for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) { auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2457,7 +2457,7 @@ void Client::RemoveNoRent(bool client_update) } } - for (auto slot_id = EQEmu::legacy::SHARED_BANK_BEGIN; slot_id <= EQEmu::legacy::SHARED_BANK_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::SHARED_BANK_BEGIN; slot_id <= EQEmu::invslot::SHARED_BANK_END; ++slot_id) { auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2465,7 +2465,7 @@ void Client::RemoveNoRent(bool client_update) } } - for (auto slot_id = EQEmu::legacy::SHARED_BANK_BAGS_BEGIN; slot_id <= EQEmu::legacy::SHARED_BANK_BAGS_END; ++slot_id) { + for (auto slot_id = EQEmu::invbag::SHARED_BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::SHARED_BANK_BAGS_END; ++slot_id) { auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2477,7 +2477,7 @@ void Client::RemoveNoRent(bool client_update) std::list local; while (!m_inv.CursorEmpty()) { - auto inst = m_inv.PopItem(EQEmu::inventory::slotCursor); + auto inst = m_inv.PopItem(EQEmu::invslot::slotCursor); if (inst == nullptr) { continue; } local.push_back(inst); } @@ -2503,7 +2503,7 @@ void Client::RemoveNoRent(bool client_update) // Two new methods to alleviate perpetual login desyncs void Client::RemoveDuplicateLore(bool client_update) { - for (auto slot_id = EQEmu::legacy::EQUIPMENT_BEGIN; slot_id <= EQEmu::legacy::EQUIPMENT_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) { auto inst = m_inv.PopItem(slot_id); if (inst == nullptr) { continue; } if(CheckLoreConflict(inst->GetItem())) { @@ -2516,7 +2516,7 @@ void Client::RemoveDuplicateLore(bool client_update) safe_delete(inst); } - for (auto slot_id = EQEmu::legacy::GENERAL_BEGIN; slot_id <= EQEmu::legacy::GENERAL_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) { auto inst = m_inv.PopItem(slot_id); if (inst == nullptr) { continue; } if (CheckLoreConflict(inst->GetItem())) { @@ -2529,21 +2529,21 @@ void Client::RemoveDuplicateLore(bool client_update) safe_delete(inst); } - if (m_inv[EQEmu::inventory::slotPowerSource]) { - auto inst = m_inv.PopItem(EQEmu::inventory::slotPowerSource); + if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) { + auto inst = m_inv.PopItem(EQEmu::invslot::SLOT_POWER_SOURCE); if (inst) { if (CheckLoreConflict(inst->GetItem())) { - Log(Logs::Detail, Logs::Inventory, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::inventory::slotPowerSource); - database.SaveInventory(character_id, nullptr, EQEmu::inventory::slotPowerSource); + Log(Logs::Detail, Logs::Inventory, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE); + database.SaveInventory(character_id, nullptr, EQEmu::invslot::SLOT_POWER_SOURCE); } else { - m_inv.PutItem(EQEmu::inventory::slotPowerSource, *inst); + m_inv.PutItem(EQEmu::invslot::SLOT_POWER_SOURCE, *inst); } safe_delete(inst); } } - for (auto slot_id = EQEmu::legacy::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::legacy::CURSOR_BAG_END; ++slot_id) { + for (auto slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::CURSOR_BAG_END; ++slot_id) { auto inst = m_inv.PopItem(slot_id); if (inst == nullptr) { continue; } if(CheckLoreConflict(inst->GetItem())) { @@ -2556,7 +2556,7 @@ void Client::RemoveDuplicateLore(bool client_update) safe_delete(inst); } - for (auto slot_id = EQEmu::legacy::BANK_BEGIN; slot_id <= EQEmu::legacy::BANK_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) { auto inst = m_inv.PopItem(slot_id); if (inst == nullptr) { continue; } if(CheckLoreConflict(inst->GetItem())) { @@ -2569,7 +2569,7 @@ void Client::RemoveDuplicateLore(bool client_update) safe_delete(inst); } - for (auto slot_id = EQEmu::legacy::BANK_BAGS_BEGIN; slot_id <= EQEmu::legacy::BANK_BAGS_END; ++slot_id) { + for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) { auto inst = m_inv.PopItem(slot_id); if (inst == nullptr) { continue; } if(CheckLoreConflict(inst->GetItem())) { @@ -2589,7 +2589,7 @@ void Client::RemoveDuplicateLore(bool client_update) std::list local_2; while (!m_inv.CursorEmpty()) { - auto inst = m_inv.PopItem(EQEmu::inventory::slotCursor); + auto inst = m_inv.PopItem(EQEmu::invslot::slotCursor); if (inst == nullptr) { continue; } local_1.push_back(inst); } @@ -2630,7 +2630,7 @@ void Client::RemoveDuplicateLore(bool client_update) void Client::MoveSlotNotAllowed(bool client_update) { - for (auto slot_id = EQEmu::legacy::EQUIPMENT_BEGIN; slot_id <= EQEmu::legacy::EQUIPMENT_END; ++slot_id) { + for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) { if(m_inv[slot_id] && !m_inv[slot_id]->IsSlotAllowed(slot_id)) { auto inst = m_inv.PopItem(slot_id); bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false; @@ -2642,13 +2642,13 @@ void Client::MoveSlotNotAllowed(bool client_update) } } - if (m_inv[EQEmu::inventory::slotPowerSource] && !m_inv[EQEmu::inventory::slotPowerSource]->IsSlotAllowed(EQEmu::inventory::slotPowerSource)) { - auto inst = m_inv.PopItem(EQEmu::inventory::slotPowerSource); + if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE] && !m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]->IsSlotAllowed(EQEmu::invslot::SLOT_POWER_SOURCE)) { + auto inst = m_inv.PopItem(EQEmu::invslot::SLOT_POWER_SOURCE); bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false; int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow); - Log(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, EQEmu::inventory::slotPowerSource, free_slot_id); + Log(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE, free_slot_id); PutItemInInventory(free_slot_id, *inst, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false); - database.SaveInventory(character_id, nullptr, EQEmu::inventory::slotPowerSource); + database.SaveInventory(character_id, nullptr, EQEmu::invslot::SLOT_POWER_SOURCE); safe_delete(inst); } @@ -2766,13 +2766,13 @@ static int16 BandolierSlotToWeaponSlot(int BandolierSlot) switch (BandolierSlot) { case bandolierPrimary: - return EQEmu::inventory::slotPrimary; + return EQEmu::invslot::slotPrimary; case bandolierSecondary: - return EQEmu::inventory::slotSecondary; + return EQEmu::invslot::slotSecondary; case bandolierRange: - return EQEmu::inventory::slotRange; + return EQEmu::invslot::slotRange; default: - return EQEmu::inventory::slotAmmo; + return EQEmu::invslot::slotAmmo; } } @@ -2847,13 +2847,13 @@ void Client::SetBandolier(const EQApplicationPacket *app) // removed 'invWhereCursor' argument from above and implemented slots 30, 331-340 checks here if (slot == INVALID_INDEX) { - if (m_inv.GetItem(EQEmu::inventory::slotCursor)) { - if (m_inv.GetItem(EQEmu::inventory::slotCursor)->GetItem()->ID == m_pp.bandoliers[bss->Number].Items[BandolierSlot].ID && - m_inv.GetItem(EQEmu::inventory::slotCursor)->GetCharges() >= 1) { // '> 0' the same, but this matches Inventory::_HasItem conditional check - slot = EQEmu::inventory::slotCursor; + if (m_inv.GetItem(EQEmu::invslot::slotCursor)) { + if (m_inv.GetItem(EQEmu::invslot::slotCursor)->GetItem()->ID == m_pp.bandoliers[bss->Number].Items[BandolierSlot].ID && + m_inv.GetItem(EQEmu::invslot::slotCursor)->GetCharges() >= 1) { // '> 0' the same, but this matches Inventory::_HasItem conditional check + slot = EQEmu::invslot::slotCursor; } - else if (m_inv.GetItem(EQEmu::inventory::slotCursor)->GetItem()->ItemClass == 1) { - for(int16 CursorBagSlot = EQEmu::legacy::CURSOR_BAG_BEGIN; CursorBagSlot <= EQEmu::legacy::CURSOR_BAG_END; CursorBagSlot++) { + else if (m_inv.GetItem(EQEmu::invslot::slotCursor)->GetItem()->ItemClass == 1) { + for(int16 CursorBagSlot = EQEmu::invbag::CURSOR_BAG_BEGIN; CursorBagSlot <= EQEmu::invbag::CURSOR_BAG_END; CursorBagSlot++) { if (m_inv.GetItem(CursorBagSlot)) { if (m_inv.GetItem(CursorBagSlot)->GetItem()->ID == m_pp.bandoliers[bss->Number].Items[BandolierSlot].ID && m_inv.GetItem(CursorBagSlot)->GetCharges() >= 1) { // ditto @@ -2999,7 +2999,7 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC // if(ItemToReturn->IsStackable()) { - for (int16 i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::inventory::slotCursor; i++) { // changed slot max to 30 from 29. client will stack into slot 30 (bags too) before moving. + for (int16 i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { // changed slot max to 30 from 29. client will stack into slot 30 (bags too) before moving. EQEmu::ItemInstance* InvItem = m_inv.GetItem(i); @@ -3025,12 +3025,12 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC // if (InvItem && InvItem->IsClassBag()) { - int16 BaseSlotID = EQEmu::InventoryProfile::CalcSlotId(i, EQEmu::inventory::containerBegin); + int16 BaseSlotID = EQEmu::InventoryProfile::CalcSlotId(i, EQEmu::invbag::SLOT_BEGIN); uint8 BagSize=InvItem->GetItem()->BagSlots; uint8 BagSlot; - for (BagSlot = EQEmu::inventory::containerBegin; BagSlot < BagSize; BagSlot++) { + for (BagSlot = EQEmu::invbag::SLOT_BEGIN; BagSlot < BagSize; BagSlot++) { InvItem = m_inv.GetItem(BaseSlotID + BagSlot); if (InvItem && (InvItem->GetItem()->ID == ItemID) && (InvItem->GetCharges() < InvItem->GetItem()->StackSize)) { @@ -3058,7 +3058,7 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC // We have tried stacking items, now just try and find an empty slot. - for (int16 i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::inventory::slotCursor; i++) { // changed slot max to 30 from 29. client will move into slot 30 (bags too) before pushing onto cursor. + for (int16 i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { // changed slot max to 30 from 29. client will move into slot 30 (bags too) before pushing onto cursor. EQEmu::ItemInstance* InvItem = m_inv.GetItem(i); @@ -3077,11 +3077,11 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC } if (InvItem->IsClassBag() && EQEmu::InventoryProfile::CanItemFitInContainer(ItemToReturn->GetItem(), InvItem->GetItem())) { - int16 BaseSlotID = EQEmu::InventoryProfile::CalcSlotId(i, EQEmu::inventory::containerBegin); + int16 BaseSlotID = EQEmu::InventoryProfile::CalcSlotId(i, EQEmu::invbag::SLOT_BEGIN); uint8 BagSize=InvItem->GetItem()->BagSlots; - for (uint8 BagSlot = EQEmu::inventory::containerBegin; BagSlot < BagSize; BagSlot++) { + for (uint8 BagSlot = EQEmu::invbag::SLOT_BEGIN; BagSlot < BagSize; BagSlot++) { InvItem = m_inv.GetItem(BaseSlotID + BagSlot); @@ -3119,27 +3119,27 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool std::map instmap; // build reference map - for (int16 index = EQEmu::inventory::slotBegin; index < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; ++index) { + for (int16 index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::POSSESSIONS_END; ++index) { auto inst = m_inv[index]; if (inst == nullptr) { continue; } instmap[index] = inst; } - for (int16 index = EQEmu::legacy::TRIBUTE_BEGIN; index <= EQEmu::legacy::TRIBUTE_END; ++index) { + for (int16 index = EQEmu::invslot::TRIBUTE_BEGIN; index <= EQEmu::invslot::TRIBUTE_END; ++index) { auto inst = m_inv[index]; if (inst == nullptr) { continue; } instmap[index] = inst; } - for (int16 index = EQEmu::legacy::BANK_BEGIN; index <= EQEmu::legacy::BANK_END; ++index) { + for (int16 index = EQEmu::invslot::BANK_BEGIN; index <= EQEmu::invslot::BANK_END; ++index) { auto inst = m_inv[index]; if (inst == nullptr) { continue; } instmap[index] = inst; } - for (int16 index = EQEmu::legacy::SHARED_BANK_BEGIN; index <= EQEmu::legacy::SHARED_BANK_END; ++index) { + for (int16 index = EQEmu::invslot::SHARED_BANK_BEGIN; index <= EQEmu::invslot::SHARED_BANK_END; ++index) { auto inst = m_inv[index]; if (inst == nullptr) { continue; } instmap[index] = inst; } - for (int16 index = EQEmu::legacy::TRADE_BEGIN; index <= EQEmu::legacy::TRADE_END; ++index) { + for (int16 index = EQEmu::invslot::TRADE_BEGIN; index <= EQEmu::invslot::TRADE_END; ++index) { auto inst = m_inv[index]; if (inst == nullptr) { continue; } instmap[index] = inst; @@ -3147,10 +3147,10 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool auto tsobject = GetTradeskillObject(); if (tsobject != nullptr) { - for (int16 index = EQEmu::inventory::slotBegin; index < EQEmu::legacy::TYPE_WORLD_SIZE; ++index) { + for (int16 index = EQEmu::invslot::SLOT_BEGIN; index < EQEmu::invtype::WORLD_SIZE; ++index) { auto inst = tsobject->GetItem(index); if (inst == nullptr) { continue; } - instmap[EQEmu::legacy::WORLD_BEGIN + index] = inst; + instmap[EQEmu::invslot::WORLD_BEGIN + index] = inst; } } @@ -3163,8 +3163,8 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool instmap[8000 + limbo] = *cursor_itr; } - if (m_inv[EQEmu::inventory::slotPowerSource]) - instmap[EQEmu::inventory::slotPowerSource] = m_inv[EQEmu::inventory::slotPowerSource]; + if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) + instmap[EQEmu::invslot::SLOT_POWER_SOURCE] = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]; // call InterrogateInventory_ for error check for (auto instmap_itr = instmap.begin(); (instmap_itr != instmap.end()) && (!error); ++instmap_itr) { @@ -3222,7 +3222,7 @@ void Client::InterrogateInventory_(bool errorcheck, Client* requester, int16 hea } else { if (inst) { - for (int16 sub = EQEmu::inventory::containerBegin; (sub < EQEmu::inventory::ContainerCount) && (!error); ++sub) { // treat any EQEmu::ItemInstance as having the max internal slots available + for (int16 sub = EQEmu::invbag::SLOT_BEGIN; (sub <= EQEmu::invbag::SLOT_END) && (!error); ++sub) { // treat any EQEmu::ItemInstance as having the max internal slots available if (inst->GetItem(sub)) InterrogateInventory_(true, requester, head, sub, inst->GetItem(sub), inst, log, silent, error, depth + 1); } @@ -3252,7 +3252,7 @@ void Client::InterrogateInventory_(bool errorcheck, Client* requester, int16 hea } if (inst) { - for (int16 sub = EQEmu::inventory::containerBegin; (sub < EQEmu::inventory::ContainerCount); ++sub) { + for (int16 sub = EQEmu::invbag::SLOT_BEGIN; (sub <= EQEmu::invbag::SLOT_END); ++sub) { if (inst->GetItem(sub)) InterrogateInventory_(false, requester, head, sub, inst->GetItem(sub), inst, log, silent, error, depth + 1); } @@ -3267,11 +3267,11 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It // very basic error checking - can be elaborated upon if more in-depth testing is needed... if ( - (head >= EQEmu::legacy::EQUIPMENT_BEGIN && head <= EQEmu::legacy::EQUIPMENT_END) || - (head >= EQEmu::legacy::TRIBUTE_BEGIN && head <= EQEmu::legacy::TRIBUTE_END) || - (head >= EQEmu::legacy::WORLD_BEGIN && head <= EQEmu::legacy::WORLD_END) || + (head >= EQEmu::invslot::EQUIPMENT_BEGIN && head <= EQEmu::invslot::EQUIPMENT_END) || + (head >= EQEmu::invslot::TRIBUTE_BEGIN && head <= EQEmu::invslot::TRIBUTE_END) || + (head >= EQEmu::invslot::WORLD_BEGIN && head <= EQEmu::invslot::WORLD_END) || (head >= 8000 && head <= 8101) || - (head == EQEmu::inventory::slotPowerSource)) { + (head == EQEmu::invslot::SLOT_POWER_SOURCE)) { switch (depth) { case 0: // requirement: inst is extant @@ -3283,7 +3283,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It return true; if (!parent->IsType(EQEmu::item::ItemClassCommon)) return true; - if (index >= EQEmu::inventory::SocketCount) + if (index > EQEmu::invaug::SOCKET_END) return true; break; default: // requirement: none (something bad happened...) @@ -3291,11 +3291,11 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It } } else if ( - (head >= EQEmu::legacy::GENERAL_BEGIN && head <= EQEmu::legacy::GENERAL_END) || - (head == EQEmu::inventory::slotCursor) || - (head >= EQEmu::legacy::BANK_BEGIN && head <= EQEmu::legacy::BANK_END) || - (head >= EQEmu::legacy::SHARED_BANK_BEGIN && head <= EQEmu::legacy::SHARED_BANK_END) || - (head >= EQEmu::legacy::TRADE_BEGIN && head <= EQEmu::legacy::TRADE_END)) { + (head >= EQEmu::invslot::GENERAL_BEGIN && head <= EQEmu::invslot::GENERAL_END) || + (head == EQEmu::invslot::slotCursor) || + (head >= EQEmu::invslot::BANK_BEGIN && head <= EQEmu::invslot::BANK_END) || + (head >= EQEmu::invslot::SHARED_BANK_BEGIN && head <= EQEmu::invslot::SHARED_BANK_END) || + (head >= EQEmu::invslot::TRADE_BEGIN && head <= EQEmu::invslot::TRADE_END)) { switch (depth) { case 0: // requirement: inst is extant @@ -3312,7 +3312,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It if (parent->IsClassCommon()) { if (!(inst->GetItem()->AugType > 0)) return true; - if (index >= EQEmu::inventory::SocketCount) + if (index > EQEmu::invaug::SOCKET_END) return true; } break; @@ -3326,7 +3326,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It if (parent->IsClassCommon()) { if (!(inst->GetItem()->AugType > 0)) return true; - if (index >= EQEmu::inventory::SocketCount) + if (index > EQEmu::invaug::SOCKET_END) return true; } break; diff --git a/zone/loottables.cpp b/zone/loottables.cpp index 961d66781..70a7e2bc4 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -263,7 +263,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch item->attuned = 0; item->min_level = minlevel; item->max_level = maxlevel; - item->equip_slot = EQEmu::inventory::slotInvalid; + item->equip_slot = EQEmu::invslot::SLOT_INVALID; if (equipit) { uint8 eslot = 0xFF; @@ -282,7 +282,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch // it is an improvement. if (!item2->NoPet) { - for (int i = 0; !found && i < EQEmu::legacy::EQUIPMENT_SIZE; i++) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; !found && i <= EQEmu::invslot::EQUIPMENT_END; i++) { uint32 slots = (1 << i); if (item2->Slots & slots) { if(equipment[i]) @@ -323,7 +323,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch // @merth: IDFile size has been increased, this needs to change uint16 emat; if(item2->Material <= 0 - || item2->Slots & (1 << EQEmu::inventory::slotPrimary | 1 << EQEmu::inventory::slotSecondary)) { + || item2->Slots & (1 << EQEmu::invslot::slotPrimary | 1 << EQEmu::invslot::slotSecondary)) { memset(newid, 0, sizeof(newid)); for(int i=0;i<7;i++){ if (!isalpha(item2->IDFile[i])){ @@ -337,7 +337,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch emat = item2->Material; } - if (foundslot == EQEmu::inventory::slotPrimary) { + if (foundslot == EQEmu::invslot::slotPrimary) { if (item2->Proc.Effect != 0) CastToMob()->AddProcToWeapon(item2->Proc.Effect, true); @@ -350,7 +350,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch if (item2->IsType2HWeapon()) SetTwoHanderEquipped(true); } - else if (foundslot == EQEmu::inventory::slotSecondary + else if (foundslot == EQEmu::invslot::slotSecondary && (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) && (item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield)) { @@ -361,25 +361,25 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch if (item2->Damage > 0) SendAddPlayerState(PlayerState::SecondaryWeaponEquipped); } - else if (foundslot == EQEmu::inventory::slotHead) { + else if (foundslot == EQEmu::invslot::slotHead) { eslot = EQEmu::textures::armorHead; } - else if (foundslot == EQEmu::inventory::slotChest) { + else if (foundslot == EQEmu::invslot::slotChest) { eslot = EQEmu::textures::armorChest; } - else if (foundslot == EQEmu::inventory::slotArms) { + else if (foundslot == EQEmu::invslot::slotArms) { eslot = EQEmu::textures::armorArms; } - else if (foundslot == EQEmu::inventory::slotWrist1 || foundslot == EQEmu::inventory::slotWrist2) { + else if (foundslot == EQEmu::invslot::slotWrist1 || foundslot == EQEmu::invslot::slotWrist2) { eslot = EQEmu::textures::armorWrist; } - else if (foundslot == EQEmu::inventory::slotHands) { + else if (foundslot == EQEmu::invslot::slotHands) { eslot = EQEmu::textures::armorHands; } - else if (foundslot == EQEmu::inventory::slotLegs) { + else if (foundslot == EQEmu::invslot::slotLegs) { eslot = EQEmu::textures::armorLegs; } - else if (foundslot == EQEmu::inventory::slotFeet) { + else if (foundslot == EQEmu::invslot::slotFeet) { eslot = EQEmu::textures::armorFeet; } diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 45ea8472e..7a8d954d8 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -725,14 +725,12 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5); } -void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, - bool attuned) { +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned) { Lua_Safe_Call_Void(); self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned); } -void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, - bool attuned, int to_slot) { +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, int to_slot) { Lua_Safe_Call_Void(); self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot); } diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 3d309c542..da62dc305 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -22,6 +22,7 @@ #include "qglobals.h" #include "encounter.h" #include "lua_encounter.h" +#include "data_bucket.h" struct Events { }; struct Factions { }; @@ -817,6 +818,22 @@ std::string lua_say_link(const char *phrase) { return std::string(text); } +std::string lua_get_data(std::string bucket_key) { + return DataBucket::GetData(bucket_key); +} + +void lua_set_data(std::string bucket_key, std::string bucket_value) { + DataBucket::SetData(bucket_key, bucket_value); +} + +void lua_set_data(std::string bucket_key, std::string bucket_value, std::string expires_at) { + DataBucket::SetData(bucket_key, bucket_value, expires_at); +} + +bool lua_delete_data(std::string bucket_key) { + return DataBucket::DeleteData(bucket_key); +} + const char *lua_get_guild_name_by_id(uint32 guild_id) { return quest_manager.getguildnamebyid(guild_id); } @@ -1658,11 +1675,17 @@ luabind::scope lua_register_general() { luabind::def("say_link", (std::string(*)(const char*,bool,const char*))&lua_say_link), luabind::def("say_link", (std::string(*)(const char*,bool))&lua_say_link), luabind::def("say_link", (std::string(*)(const char*))&lua_say_link), + luabind::def("get_data", (std::string(*)(std::string))&lua_get_data), + luabind::def("set_data", (void(*)(std::string, std::string))&lua_set_data), + luabind::def("set_data", (void(*)(std::string, std::string, std::string))&lua_set_data), + luabind::def("delete_data", (bool(*)(std::string))&lua_delete_data), luabind::def("get_guild_name_by_id", &lua_get_guild_name_by_id), luabind::def("create_instance", &lua_create_instance), luabind::def("destroy_instance", &lua_destroy_instance), luabind::def("update_instance_timer", &lua_update_instance_timer), luabind::def("get_instance_id", &lua_get_instance_id), + luabind::def("get_instance_timer", &lua_get_instance_timer), + luabind::def("get_instance_timer_by_id", &lua_get_instance_timer_by_id), luabind::def("get_characters_in_instance", &lua_get_characters_in_instance), luabind::def("assign_to_instance", &lua_assign_to_instance), luabind::def("assign_group_to_instance", &lua_assign_group_to_instance), @@ -1841,47 +1864,47 @@ luabind::scope lua_register_slot() { return luabind::class_("Slot") .enum_("constants") [ - luabind::value("Charm", static_cast(EQEmu::inventory::slotCharm)), - luabind::value("Ear1", static_cast(EQEmu::inventory::slotEar1)), - luabind::value("Head", static_cast(EQEmu::inventory::slotHead)), - luabind::value("Face", static_cast(EQEmu::inventory::slotFace)), - luabind::value("Ear2", static_cast(EQEmu::inventory::slotEar2)), - luabind::value("Neck", static_cast(EQEmu::inventory::slotNeck)), - luabind::value("Shoulder", static_cast(EQEmu::inventory::slotShoulders)), // deprecated - luabind::value("Shoulders", static_cast(EQEmu::inventory::slotShoulders)), - luabind::value("Arms", static_cast(EQEmu::inventory::slotArms)), - luabind::value("Back", static_cast(EQEmu::inventory::slotBack)), - luabind::value("Bracer1", static_cast(EQEmu::inventory::slotWrist1)), // deprecated - luabind::value("Wrist1", static_cast(EQEmu::inventory::slotWrist1)), - luabind::value("Bracer2", static_cast(EQEmu::inventory::slotWrist2)), // deprecated - luabind::value("Wrist2", static_cast(EQEmu::inventory::slotWrist2)), - luabind::value("Range", static_cast(EQEmu::inventory::slotRange)), - luabind::value("Hands", static_cast(EQEmu::inventory::slotHands)), - luabind::value("Primary", static_cast(EQEmu::inventory::slotPrimary)), - luabind::value("Secondary", static_cast(EQEmu::inventory::slotSecondary)), - luabind::value("Ring1", static_cast(EQEmu::inventory::slotFinger1)), // deprecated - luabind::value("Finger1", static_cast(EQEmu::inventory::slotFinger1)), - luabind::value("Ring2", static_cast(EQEmu::inventory::slotFinger2)), // deprecated - luabind::value("Finger2", static_cast(EQEmu::inventory::slotFinger2)), - luabind::value("Chest", static_cast(EQEmu::inventory::slotChest)), - luabind::value("Legs", static_cast(EQEmu::inventory::slotLegs)), - luabind::value("Feet", static_cast(EQEmu::inventory::slotFeet)), - luabind::value("Waist", static_cast(EQEmu::inventory::slotWaist)), - luabind::value("PowerSource", static_cast(EQEmu::inventory::slotPowerSource)), - luabind::value("Ammo", static_cast(EQEmu::inventory::slotAmmo)), - luabind::value("General1", static_cast(EQEmu::inventory::slotGeneral1)), - luabind::value("General2", static_cast(EQEmu::inventory::slotGeneral2)), - luabind::value("General3", static_cast(EQEmu::inventory::slotGeneral3)), - luabind::value("General4", static_cast(EQEmu::inventory::slotGeneral4)), - luabind::value("General5", static_cast(EQEmu::inventory::slotGeneral5)), - luabind::value("General6", static_cast(EQEmu::inventory::slotGeneral6)), - luabind::value("General7", static_cast(EQEmu::inventory::slotGeneral7)), - luabind::value("General8", static_cast(EQEmu::inventory::slotGeneral8)), - luabind::value("Cursor", static_cast(EQEmu::inventory::slotCursor)), - luabind::value("PersonalBegin", static_cast(EQEmu::legacy::GENERAL_BEGIN)), // deprecated - luabind::value("GeneralBegin", static_cast(EQEmu::legacy::GENERAL_BEGIN)), - luabind::value("PersonalEnd", static_cast(EQEmu::legacy::GENERAL_END)), // deprecated - luabind::value("GeneralEnd", static_cast(EQEmu::legacy::GENERAL_END)), + luabind::value("Charm", static_cast(EQEmu::invslot::slotCharm)), + luabind::value("Ear1", static_cast(EQEmu::invslot::slotEar1)), + luabind::value("Head", static_cast(EQEmu::invslot::slotHead)), + luabind::value("Face", static_cast(EQEmu::invslot::slotFace)), + luabind::value("Ear2", static_cast(EQEmu::invslot::slotEar2)), + luabind::value("Neck", static_cast(EQEmu::invslot::slotNeck)), + luabind::value("Shoulder", static_cast(EQEmu::invslot::slotShoulders)), // deprecated + luabind::value("Shoulders", static_cast(EQEmu::invslot::slotShoulders)), + luabind::value("Arms", static_cast(EQEmu::invslot::slotArms)), + luabind::value("Back", static_cast(EQEmu::invslot::slotBack)), + luabind::value("Bracer1", static_cast(EQEmu::invslot::slotWrist1)), // deprecated + luabind::value("Wrist1", static_cast(EQEmu::invslot::slotWrist1)), + luabind::value("Bracer2", static_cast(EQEmu::invslot::slotWrist2)), // deprecated + luabind::value("Wrist2", static_cast(EQEmu::invslot::slotWrist2)), + luabind::value("Range", static_cast(EQEmu::invslot::slotRange)), + luabind::value("Hands", static_cast(EQEmu::invslot::slotHands)), + luabind::value("Primary", static_cast(EQEmu::invslot::slotPrimary)), + luabind::value("Secondary", static_cast(EQEmu::invslot::slotSecondary)), + luabind::value("Ring1", static_cast(EQEmu::invslot::slotFinger1)), // deprecated + luabind::value("Finger1", static_cast(EQEmu::invslot::slotFinger1)), + luabind::value("Ring2", static_cast(EQEmu::invslot::slotFinger2)), // deprecated + luabind::value("Finger2", static_cast(EQEmu::invslot::slotFinger2)), + luabind::value("Chest", static_cast(EQEmu::invslot::slotChest)), + luabind::value("Legs", static_cast(EQEmu::invslot::slotLegs)), + luabind::value("Feet", static_cast(EQEmu::invslot::slotFeet)), + luabind::value("Waist", static_cast(EQEmu::invslot::slotWaist)), + luabind::value("PowerSource", static_cast(EQEmu::invslot::SLOT_POWER_SOURCE)), + luabind::value("Ammo", static_cast(EQEmu::invslot::slotAmmo)), + luabind::value("General1", static_cast(EQEmu::invslot::slotGeneral1)), + luabind::value("General2", static_cast(EQEmu::invslot::slotGeneral2)), + luabind::value("General3", static_cast(EQEmu::invslot::slotGeneral3)), + luabind::value("General4", static_cast(EQEmu::invslot::slotGeneral4)), + luabind::value("General5", static_cast(EQEmu::invslot::slotGeneral5)), + luabind::value("General6", static_cast(EQEmu::invslot::slotGeneral6)), + luabind::value("General7", static_cast(EQEmu::invslot::slotGeneral7)), + luabind::value("General8", static_cast(EQEmu::invslot::slotGeneral8)), + luabind::value("Cursor", static_cast(EQEmu::invslot::slotCursor)), + luabind::value("PersonalBegin", static_cast(EQEmu::invslot::GENERAL_BEGIN)), // deprecated + luabind::value("GeneralBegin", static_cast(EQEmu::invslot::GENERAL_BEGIN)), + luabind::value("PersonalEnd", static_cast(EQEmu::invslot::GENERAL_END)), // deprecated + luabind::value("GeneralEnd", static_cast(EQEmu::invslot::GENERAL_END)), luabind::value("CursorEnd", 0xFFFE), // deprecated luabind::value("Tradeskill", static_cast(EQEmu::legacy::SLOT_TRADESKILL)), // deprecated luabind::value("Augment", static_cast(EQEmu::legacy::SLOT_AUGMENT)), // deprecated diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 3793e6b9d..50d973b61 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1135,17 +1135,6 @@ bool Lua_Mob::CalculateNewPosition(double x, double y, double z, double speed, b check_z); } -bool Lua_Mob::CalculateNewPosition2(double x, double y, double z, double speed) { - Lua_Safe_Call_Bool(); - return self->CalculateNewPosition2(static_cast(x), static_cast(y), static_cast(z), static_cast(speed)); -} - -bool Lua_Mob::CalculateNewPosition2(double x, double y, double z, double speed, bool check_z) { - Lua_Safe_Call_Bool(); - return self->CalculateNewPosition2(static_cast(x), static_cast(y), static_cast(z), static_cast(speed), - check_z); -} - float Lua_Mob::CalculateDistance(double x, double y, double z) { Lua_Safe_Call_Real(); return self->CalculateDistance(static_cast(x), static_cast(y), static_cast(z)); @@ -2374,8 +2363,6 @@ luabind::scope lua_register_mob() { .def("CalculateHeadingToTarget", (double(Lua_Mob::*)(double,double))&Lua_Mob::CalculateHeadingToTarget) .def("CalculateNewPosition", (bool(Lua_Mob::*)(double,double,double,double))&Lua_Mob::CalculateNewPosition) .def("CalculateNewPosition", (bool(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::CalculateNewPosition) - .def("CalculateNewPosition2", (bool(Lua_Mob::*)(double,double,double,double))&Lua_Mob::CalculateNewPosition2) - .def("CalculateNewPosition2", (bool(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::CalculateNewPosition2) .def("CalculateDistance", (float(Lua_Mob::*)(double,double,double))&Lua_Mob::CalculateDistance) .def("SendTo", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::SendTo) .def("SendToFixZ", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::SendToFixZ) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 17dbc5c43..564277ac7 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -242,8 +242,6 @@ public: double CalculateHeadingToTarget(double in_x, double in_y); bool CalculateNewPosition(double x, double y, double z, double speed); bool CalculateNewPosition(double x, double y, double z, double speed, bool check_z); - bool CalculateNewPosition2(double x, double y, double z, double speed); - bool CalculateNewPosition2(double x, double y, double z, double speed, bool check_z); float CalculateDistance(double x, double y, double z); void SendTo(double x, double y, double z); void SendToFixZ(double x, double y, double z); diff --git a/zone/map.cpp b/zone/map.cpp index 0627c2dc2..a63ea6672 100644 --- a/zone/map.cpp +++ b/zone/map.cpp @@ -1,5 +1,6 @@ #include "../common/global_define.h" #include "../common/misc_functions.h" +#include "../common/compression.h" #include "map.h" #include "raycast_mesh.h" @@ -10,83 +11,6 @@ #include #include #include -#include - - -uint32 EstimateDeflateBuffer(uint32_t len) { - z_stream zstream; - memset(&zstream, 0, sizeof(zstream)); - - zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; - zstream.opaque = Z_NULL; - if (deflateInit(&zstream, Z_FINISH) != Z_OK) - return 0; - - return deflateBound(&zstream, len); -} - -uint32_t DeflateData(const char *buffer, uint32_t len, char *out_buffer, uint32_t out_len_max) { - z_stream zstream; - memset(&zstream, 0, sizeof(zstream)); - int zerror; - - zstream.next_in = const_cast(reinterpret_cast(buffer)); - zstream.avail_in = len; - zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; - zstream.opaque = Z_NULL; - deflateInit(&zstream, Z_FINISH); - - zstream.next_out = reinterpret_cast(out_buffer); - zstream.avail_out = out_len_max; - zerror = deflate(&zstream, Z_FINISH); - - if (zerror == Z_STREAM_END) - { - deflateEnd(&zstream); - return (uint32_t)zstream.total_out; - } - else - { - zerror = deflateEnd(&zstream); - return 0; - } -} - -uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) { - z_stream zstream; - int zerror = 0; - int i; - - zstream.next_in = const_cast(reinterpret_cast(buffer)); - zstream.avail_in = len; - zstream.next_out = reinterpret_cast(out_buffer);; - zstream.avail_out = out_len_max; - zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; - zstream.opaque = Z_NULL; - - i = inflateInit2(&zstream, 15); - if (i != Z_OK) { - return 0; - } - - zerror = inflate(&zstream, Z_FINISH); - if (zerror == Z_STREAM_END) { - inflateEnd(&zstream); - return zstream.total_out; - } - else { - if (zerror == -4 && zstream.msg == 0) - { - return 0; - } - - zerror = inflateEnd(&zstream); - return 0; - } -} struct Map::impl { @@ -293,12 +217,13 @@ Map *Map::LoadMapFile(std::string file) { else { filename = Config->MapDir; } + std::transform(file.begin(), file.end(), file.begin(), ::tolower); - filename += "/"; + filename += "/base/"; filename += file; filename += ".map"; - Log(Logs::General, Logs::Status, "Attempting to load Map File :: '%s'", filename.c_str()); + Log(Logs::General, Logs::Status, "Attempting to load Map File '%s'", filename.c_str()); auto m = new Map(); if (m->Load(filename)) { @@ -330,7 +255,7 @@ bool Map::Load(std::string filename) } if(version == 0x01000000) { - Log(Logs::General, Logs::Status, "Loaded V1 Map File :: '%s'", filename.c_str()); + Log(Logs::General, Logs::Status, "Loaded V1 Map File '%s'", filename.c_str()); bool v = LoadV1(f); fclose(f); @@ -341,7 +266,7 @@ bool Map::Load(std::string filename) return v; } else if(version == 0x02000000) { - Log(Logs::General, Logs::Status, "Loaded V2 Map File :: '%s'", filename.c_str()); + Log(Logs::General, Logs::Status, "Loaded V2 Map File '%s'", filename.c_str()); bool v = LoadV2(f); fclose(f); @@ -459,7 +384,7 @@ bool Map::LoadV2(FILE *f) { std::vector buffer; buffer.resize(buffer_size); - uint32 v = InflateData(&data[0], data_size, &buffer[0], buffer_size); + uint32 v = EQEmu::InflateData(&data[0], data_size, &buffer[0], buffer_size); char *buf = &buffer[0]; uint32 vert_count; diff --git a/zone/merc.cpp b/zone/merc.cpp index 03e618881..a32fab994 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -217,7 +217,7 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) { unsigned int i; //should not include 21 (SLOT_AMMO) - for (i = 0; i < EQEmu::inventory::slotAmmo; i++) { + for (i = 0; i < EQEmu::invslot::slotAmmo; i++) { if(equipment[i] == 0) continue; const EQEmu::ItemData * itm = database.GetItem(equipment[i]); @@ -1487,12 +1487,12 @@ void Merc::AI_Process() { if (WaypointChanged) tar_ndx = 20; - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed()); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetRunspeed()); } else { Mob* follow = entity_list.GetMob(GetFollowID()); if (follow) - CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), GetRunspeed()); + CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), GetRunspeed()); } return; @@ -1559,7 +1559,7 @@ void Merc::AI_Process() { float newZ = 0; FaceTarget(GetTarget()); if (PlotPositionAroundTarget(this, newX, newY, newZ)) { - CalculateNewPosition2(newX, newY, newZ, GetRunspeed()); + CalculateNewPosition(newX, newY, newZ, GetRunspeed()); return; } } @@ -1571,7 +1571,7 @@ void Merc::AI_Process() { float newY = 0; float newZ = 0; if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ)) { - CalculateNewPosition2(newX, newY, newZ, GetRunspeed()); + CalculateNewPosition(newX, newY, newZ, GetRunspeed()); return; } } @@ -1582,7 +1582,7 @@ void Merc::AI_Process() { float newY = 0; float newZ = 0; if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) { - CalculateNewPosition2(newX, newY, newZ, GetRunspeed()); + CalculateNewPosition(newX, newY, newZ, GetRunspeed()); return; } } @@ -1610,24 +1610,24 @@ void Merc::AI_Process() { //try main hand first if(attack_timer.Check()) { - Attack(GetTarget(), EQEmu::inventory::slotPrimary); + Attack(GetTarget(), EQEmu::invslot::slotPrimary); bool tripleSuccess = false; if(GetOwner() && GetTarget() && CanThisClassDoubleAttack()) { if(GetOwner()) { - Attack(GetTarget(), EQEmu::inventory::slotPrimary, true); + Attack(GetTarget(), EQEmu::invslot::slotPrimary, true); } if(GetOwner() && GetTarget() && GetSpecialAbility(SPECATK_TRIPLE)) { tripleSuccess = true; - Attack(GetTarget(), EQEmu::inventory::slotPrimary, true); + Attack(GetTarget(), EQEmu::invslot::slotPrimary, true); } //quad attack, does this belong here?? if(GetOwner() && GetTarget() && GetSpecialAbility(SPECATK_QUAD)) { - Attack(GetTarget(), EQEmu::inventory::slotPrimary, true); + Attack(GetTarget(), EQEmu::invslot::slotPrimary, true); } } @@ -1639,8 +1639,8 @@ void Merc::AI_Process() { if(zone->random.Roll(flurrychance)) { Message_StringID(MT_NPCFlurry, YOU_FLURRY); - Attack(GetTarget(), EQEmu::inventory::slotPrimary, false); - Attack(GetTarget(), EQEmu::inventory::slotPrimary, false); + Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); + Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); } } @@ -1649,7 +1649,7 @@ void Merc::AI_Process() { if (GetTarget() && ExtraAttackChanceBonus) { if(zone->random.Roll(ExtraAttackChanceBonus)) { - Attack(GetTarget(), EQEmu::inventory::slotPrimary, false); + Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); } } } @@ -1685,11 +1685,11 @@ void Merc::AI_Process() { // Max 78% of DW if (zone->random.Roll(DualWieldProbability)) { - Attack(GetTarget(), EQEmu::inventory::slotSecondary); // Single attack with offhand + Attack(GetTarget(), EQEmu::invslot::slotSecondary); // Single attack with offhand if(CanThisClassDoubleAttack()) { if(GetTarget() && GetTarget()->GetHP() > -10) - Attack(GetTarget(), EQEmu::inventory::slotSecondary); // Single attack with offhand + Attack(GetTarget(), EQEmu::invslot::slotSecondary); // Single attack with offhand } } } @@ -1709,7 +1709,7 @@ void Merc::AI_Process() { { if(!IsRooted()) { Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName()); - CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed()); + CalculateNewPosition(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed()); return; } @@ -1781,10 +1781,10 @@ void Merc::AI_Process() { if (WaypointChanged) tar_ndx = 20; - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, speed); } else { - CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed); + CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), speed); } if (rest_timer.Enabled()) @@ -2614,7 +2614,7 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { int16 focus_max_real = 0; //item focus - for (int x = 0; x < EQEmu::legacy::EQUIPMENT_SIZE; ++x) + for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; ++x) { TempItem = nullptr; if (equipment[x] == 0) @@ -5093,7 +5093,7 @@ void Merc::UpdateMercAppearance() { // Copied from Bot Code: uint32 itemID = 0; uint8 materialFromSlot = EQEmu::textures::materialInvalid; - for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) { + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; ++i) { itemID = equipment[i]; if(itemID != 0) { materialFromSlot = EQEmu::InventoryProfile::CalcMaterialFromSlot(i); @@ -5111,8 +5111,8 @@ void Merc::UpdateEquipmentLight() m_Light.Type[EQEmu::lightsource::LightEquipment] = 0; m_Light.Level[EQEmu::lightsource::LightEquipment] = 0; - for (int index = EQEmu::inventory::slotBegin; index < EQEmu::legacy::EQUIPMENT_SIZE; ++index) { - if (index == EQEmu::inventory::slotAmmo) { continue; } + for (int index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::EQUIPMENT_END; ++index) { + if (index == EQEmu::invslot::slotAmmo) { continue; } auto item = database.GetItem(equipment[index]); if (item == nullptr) { continue; } diff --git a/zone/merc.h b/zone/merc.h index abd7e65d6..cf6a14009 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -66,7 +66,7 @@ public: //abstract virtual function implementations requird by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill); virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None); - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr); virtual bool HasRaid() { return false; } virtual bool HasGroup() { return (GetGroup() ? true : false); } @@ -293,7 +293,7 @@ protected: Timer evade_timer; // can be moved to pTimers at some point uint16 skills[EQEmu::skills::HIGHEST_SKILL + 1]; - uint32 equipment[EQEmu::legacy::EQUIPMENT_SIZE]; //this is an array of item IDs + uint32 equipment[EQEmu::invslot::EQUIPMENT_COUNT]; //this is an array of item IDs uint16 d_melee_texture1; //this is an item Material value uint16 d_melee_texture2; //this is an item Material value (offhand) uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation diff --git a/zone/mob.cpp b/zone/mob.cpp index d23aaf0b4..5f998347d 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -116,7 +116,7 @@ Mob::Mob(const char* in_name, fix_z_timer_engaged(100), attack_anim_timer(1000), position_update_melee_push_timer(500), - mHateListCleanup(6000) + hate_list_cleanup_timer(6000) { targeted = 0; tar_ndx = 0; @@ -432,15 +432,7 @@ Mob::Mob(const char* in_name, m_TargetRing = glm::vec3(); flymode = FlyMode3; - // Pathing - PathingLOSState = UnknownLOS; - PathingLoopCount = 0; - PathingLastNodeVisited = -1; - PathingLOSCheckTimer = new Timer(RuleI(Pathing, LOSCheckFrequency)); - PathingRouteUpdateTimerShort = new Timer(RuleI(Pathing, RouteUpdateFrequencyShort)); - PathingRouteUpdateTimerLong = new Timer(RuleI(Pathing, RouteUpdateFrequencyLong)); DistractedFromGrid = false; - PathingTraversedNodes = 0; hate_list.SetHateOwner(this); m_AllowBeneficial = false; @@ -454,6 +446,9 @@ Mob::Mob(const char* in_name, PrimaryAggro = false; AssistAggro = false; npc_assist_cap = 0; + + PathRecalcTimer.reset(new Timer(500)); + PathingLoopCount = 0; } Mob::~Mob() @@ -487,9 +482,6 @@ Mob::~Mob() entity_list.DestroyTempPets(this); } entity_list.UnMarkNPC(GetID()); - safe_delete(PathingLOSCheckTimer); - safe_delete(PathingRouteUpdateTimerShort); - safe_delete(PathingRouteUpdateTimerLong); UninitializeBuffSlots(); #ifdef BOTS @@ -1250,6 +1242,13 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.flymode = 0; } + + if (RuleB(Character, AllowCrossClassTrainers) && ForWho) { + if (ns->spawn.class_ >= WARRIORGM && ns->spawn.class_ <= BERSERKERGM) { + int trainer_class = WARRIORGM + (ForWho->GetClass() - 1); + ns->spawn.class_ = trainer_class; + } + } } void Mob::CreateDespawnPacket(EQApplicationPacket* app, bool Decay) @@ -1679,7 +1678,6 @@ void Mob::ShowBuffList(Client* client) { } void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { - Route.clear(); if(IsNPC()) { @@ -2090,7 +2088,7 @@ bool Mob::IsPlayerRace(uint16 in_race) { uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) { - if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118 || in_race == 23) { + if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118 || in_race == 562) { if (in_gender >= 2) { // Male default for PC Races return 0; @@ -2488,8 +2486,8 @@ bool Mob::CanThisClassDualWield(void) const { return(GetSkill(EQEmu::skills::SkillDualWield) > 0); } else if (CastToClient()->HasSkill(EQEmu::skills::SkillDualWield)) { - const EQEmu::ItemInstance* pinst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); - const EQEmu::ItemInstance* sinst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary); + const EQEmu::ItemInstance* pinst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); + const EQEmu::ItemInstance* sinst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotSecondary); // 2HS, 2HB, or 2HP if(pinst && pinst->IsWeapon()) { @@ -6054,6 +6052,11 @@ void Mob::CommonBreakInvisible() CancelSneakHide(); } +float Mob::GetDefaultRaceSize() const { + return GetRaceGenderDefaultHeight(race, gender); +} + + #ifdef BOTS bool Mob::JoinHealRotationTargetPool(std::shared_ptr* heal_rotation) { diff --git a/zone/mob.h b/zone/mob.h index cb8e7b261..5561ef0da 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -21,7 +21,7 @@ #include "common.h" #include "entity.h" #include "hate_list.h" -#include "pathing.h" +#include "pathfinder_interface.h" #include "position.h" #include "aa_ability.h" #include "aa.h" @@ -184,7 +184,7 @@ public: virtual void RangedAttack(Mob* other) { } virtual void ThrowingAttack(Mob* other) { } // 13 = Primary (default), 14 = secondary - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0; void DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr); int MonkSpecialAttack(Mob* other, uint8 skill_used); @@ -537,7 +537,7 @@ public: inline const float GetTarVZ() const { return m_TargetV.z; } inline const float GetTarVector() const { return tar_vector; } inline const uint8 GetTarNDX() const { return tar_ndx; } - inline const int8 GetFlyMode() const { return flymode; } + inline const int8 GetFlyMode() const { return static_cast(flymode); } bool IsBoat() const; //Group @@ -675,7 +675,7 @@ public: inline AuraMgr &GetAuraMgr() { return aura_mgr; } // mainly used for zone db loading/saving //Procs - void TriggerDefensiveProcs(Mob *on, uint16 hand = EQEmu::inventory::slotPrimary, bool FromSkillProc = false, int damage = 0); + void TriggerDefensiveProcs(Mob *on, uint16 hand = EQEmu::invslot::slotPrimary, bool FromSkillProc = false, int damage = 0); bool AddRangedProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN); bool RemoveRangedProc(uint16 spell_id, bool bAll = false); bool HasRangedProcs() const; @@ -979,16 +979,17 @@ public: inline bool IsBlind() { return spellbonuses.IsBlind; } inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);} - float CalculateHeadingToTarget(float in_x, float in_y) {return HeadingAngleToMob(in_x, in_y); } - bool CalculateNewPosition(float x, float y, float z, int speed, bool checkZ = false, bool calcHeading = true); - virtual bool CalculateNewPosition2(float x, float y, float z, int speed, bool checkZ = true, bool calcHeading = true); + float CalculateHeadingToTarget(float in_x, float in_y) { return HeadingAngleToMob(in_x, in_y); } + virtual bool CalculateNewPosition(float x, float y, float z, int speed, bool checkZ = true, bool calcheading = true); float CalculateDistance(float x, float y, float z); float GetGroundZ(float new_x, float new_y, float z_offset=0.0); void SendTo(float new_x, float new_y, float new_z); void SendToFixZ(float new_x, float new_y, float new_z); float GetZOffset() const; + float GetDefaultRaceSize() const; void FixZ(int32 z_find_offset = 5); - float GetFixedZ(glm::vec3 position, int32 z_find_offset = 5); + float GetFixedZ(glm::vec3 position, int32 z_find_offset = 5); + void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false); inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; } inline uint32 DontBuffMeBefore() const { return pDontBuffMeBefore; } @@ -1285,13 +1286,13 @@ protected: void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false); // hand = SlotCharm? bool PassLimitToSkill(uint16 spell_id, uint16 skill); bool PassLimitClass(uint32 Classes_, uint16 Class_); - void TryDefensiveProc(Mob *on, uint16 hand = EQEmu::inventory::slotPrimary); - void TryWeaponProc(const EQEmu::ItemInstance* inst, const EQEmu::ItemData* weapon, Mob *on, uint16 hand = EQEmu::inventory::slotPrimary); - void TrySpellProc(const EQEmu::ItemInstance* inst, const EQEmu::ItemData* weapon, Mob *on, uint16 hand = EQEmu::inventory::slotPrimary); - void TryWeaponProc(const EQEmu::ItemInstance* weapon, Mob *on, uint16 hand = EQEmu::inventory::slotPrimary); + void TryDefensiveProc(Mob *on, uint16 hand = EQEmu::invslot::slotPrimary); + void TryWeaponProc(const EQEmu::ItemInstance* inst, const EQEmu::ItemData* weapon, Mob *on, uint16 hand = EQEmu::invslot::slotPrimary); + void TrySpellProc(const EQEmu::ItemInstance* inst, const EQEmu::ItemData* weapon, Mob *on, uint16 hand = EQEmu::invslot::slotPrimary); + void TryWeaponProc(const EQEmu::ItemInstance* weapon, Mob *on, uint16 hand = EQEmu::invslot::slotPrimary); void ExecWeaponProc(const EQEmu::ItemInstance* weapon, uint16 spell_id, Mob *on, int level_override = -1); - virtual float GetProcChances(float ProcBonus, uint16 hand = EQEmu::inventory::slotPrimary); - virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = EQEmu::inventory::slotPrimary, Mob *on = nullptr); + virtual float GetProcChances(float ProcBonus, uint16 hand = EQEmu::invslot::slotPrimary); + virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = EQEmu::invslot::slotPrimary, Mob *on = nullptr); virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm? uint16 GetWeaponSpeedbyHand(uint16 hand); #ifdef BOTS @@ -1303,7 +1304,7 @@ protected: float FindGroundZ(float new_x, float new_y, float z_offset=0.0); float FindDestGroundZ(glm::vec3 dest, float z_offset=0.0); glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached); - void PrintRoute(); + glm::vec3 HandleStuckPath(const glm::vec3 &To, const glm::vec3 &From); virtual float GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 ItemProcRate = 0); int16 GetSympatheticSpellProcRate(uint16 spell_id); @@ -1440,6 +1441,7 @@ protected: std::unique_ptr AI_walking_timer; std::unique_ptr AI_feign_remember_timer; std::unique_ptr AI_check_signal_timer; + std::unique_ptr AI_scan_door_open_timer; uint32 pLastFightingDelayMoving; HateList hate_list; std::set feign_memory_list; @@ -1452,9 +1454,7 @@ protected: void AddItemFactionBonus(uint32 pFactionID,int32 bonus); int32 GetItemFactionBonus(uint32 pFactionID); void ClearItemFactionBonuses(); - Timer mHateListCleanup; - - void CalculateFearPosition(); + Timer hate_list_cleanup_timer; bool flee_mode; Timer flee_timer; @@ -1482,7 +1482,6 @@ protected: int npc_assist_cap; Timer assist_cap_timer; // clear assist cap so more nearby mobs can be called for help - int patrol; glm::vec3 m_FearWalkTarget; bool currently_fleeing; @@ -1490,16 +1489,11 @@ protected: // Pathing // glm::vec3 PathingDestination; + IPathfinder::IPath Route; + std::unique_ptr PathRecalcTimer; + bool DistractedFromGrid; glm::vec3 PathingLastPosition; int PathingLoopCount; - int PathingLastNodeVisited; - std::deque Route; - LOSType PathingLOSState; - Timer *PathingLOSCheckTimer; - Timer *PathingRouteUpdateTimerShort; - Timer *PathingRouteUpdateTimerLong; - bool DistractedFromGrid; - int PathingTraversedNodes; uint32 pDontHealMeBefore; uint32 pDontBuffMeBefore; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 134beee0a..2a2023599 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -433,6 +433,7 @@ void Mob::AI_Init() AI_feign_remember_timer.reset(nullptr); AI_scan_area_timer.reset(nullptr); AI_check_signal_timer.reset(nullptr); + AI_scan_door_open_timer.reset(nullptr); minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin); maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax); @@ -476,15 +477,21 @@ void Mob::AI_Start(uint32 iMoveDelay) { else pLastFightingDelayMoving = 0; - pAIControlled = true; + pAIControlled = true; AI_think_timer = std::unique_ptr(new Timer(AIthink_duration)); AI_think_timer->Trigger(); - AI_walking_timer = std::unique_ptr(new Timer(0)); - AI_movement_timer = std::unique_ptr(new Timer(AImovement_duration)); - AI_target_check_timer = std::unique_ptr(new Timer(AItarget_check_duration)); - AI_feign_remember_timer = std::unique_ptr(new Timer(AIfeignremember_delay)); - if(CastToNPC()->WillAggroNPCs()) + AI_walking_timer = std::unique_ptr(new Timer(0)); + AI_movement_timer = std::unique_ptr(new Timer(AImovement_duration)); + AI_target_check_timer = std::unique_ptr(new Timer(AItarget_check_duration)); + AI_feign_remember_timer = std::unique_ptr(new Timer(AIfeignremember_delay)); + AI_scan_door_open_timer = std::unique_ptr(new Timer(AI_scan_door_open_interval)); + + if(!RuleB(Aggro, NPCAggroMaxDistanceEnabled)) { + hate_list_cleanup_timer.Disable(); + } + + if (CastToNPC()->WillAggroNPCs()) AI_scan_area_timer = std::unique_ptr(new Timer(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)))); AI_check_signal_timer = std::unique_ptr(new Timer(AI_check_signal_timer_delay)); @@ -552,6 +559,7 @@ void Mob::AI_Stop() { AI_scan_area_timer.reset(nullptr); AI_feign_remember_timer.reset(nullptr); AI_check_signal_timer.reset(nullptr); + AI_scan_door_open_timer.reset(nullptr); hate_list.WipeHateList(); } @@ -589,10 +597,6 @@ void Client::AI_Stop() { // only call this on a zone shutdown event void Mob::AI_ShutDown() { - safe_delete(PathingLOSCheckTimer); - safe_delete(PathingRouteUpdateTimerShort); - safe_delete(PathingRouteUpdateTimerLong); - attack_timer.Disable(); attack_dw_timer.Disable(); ranged_timer.Disable(); @@ -796,7 +800,7 @@ void Client::AI_Process() CalculateNewFearpoint(); } if(!RuleB(Pathing, Fear) || !zone->pathing) - CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true); + CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true); else { bool WaypointChanged, NodeReached; @@ -807,7 +811,7 @@ void Client::AI_Process() if(WaypointChanged) tar_ndx = 20; - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, speed); } } return; @@ -857,7 +861,7 @@ void Client::AI_Process() if (GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) { if (attack_timer.Check()) { // Should charmed clients not be procing? - DoAttackRounds(GetTarget(), EQEmu::inventory::slotPrimary); + DoAttackRounds(GetTarget(), EQEmu::invslot::slotPrimary); } } @@ -865,7 +869,7 @@ void Client::AI_Process() if (attack_dw_timer.Check()) { if (CheckDualWield()) { // Should charmed clients not be procing? - DoAttackRounds(GetTarget(), EQEmu::inventory::slotSecondary); + DoAttackRounds(GetTarget(), EQEmu::invslot::slotSecondary); } } } @@ -879,7 +883,7 @@ void Client::AI_Process() newspeed *= 2; SetCurrentSpeed(newspeed); if(!RuleB(Pathing, Aggro) || !zone->pathing) - CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), newspeed); + CalculateNewPosition(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), newspeed); else { bool WaypointChanged, NodeReached; @@ -889,7 +893,7 @@ void Client::AI_Process() if(WaypointChanged) tar_ndx = 20; - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, newspeed); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, newspeed); } } } @@ -938,7 +942,7 @@ void Client::AI_Process() nspeed *= 2; SetCurrentSpeed(nspeed); - CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed); + CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed); } } else { if (moved) { @@ -1053,6 +1057,40 @@ void Mob::AI_Process() { engaged = false; } + if (moving) { + if (AI_scan_door_open_timer->Check()) { + + auto &door_list = entity_list.GetDoorsList(); + for (auto itr : door_list) { + Doors *door = itr.second; + + if (door->GetKeyItem()) + continue; + + if (door->GetLockpick()) + continue; + + if (door->IsDoorOpen()) + continue; + + float distance = DistanceSquared(this->m_Position, door->GetPosition()); + float distance_scan_door_open = 20; + + if (distance <= (distance_scan_door_open * distance_scan_door_open)) { + + /** + * Make sure we're opening a door within height relevance and not platforms + * above or below + */ + if (std::abs(this->m_Position.z - door->GetPosition().z) > 10) + continue; + + door->ForceOpen(this); + } + } + } + } + // Begin: Additions for Wiz Fear Code // if(RuleB(Combat, EnableFearPathing)){ @@ -1078,7 +1116,7 @@ void Mob::AI_Process() { } if(!RuleB(Pathing, Fear) || !zone->pathing) { - CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true); + CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true); } else { @@ -1090,7 +1128,7 @@ void Mob::AI_Process() { if(WaypointChanged) tar_ndx = 20; - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetFearSpeed()); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetFearSpeed()); } } return; @@ -1129,7 +1167,7 @@ void Mob::AI_Process() { // NPCs will forget people after 10 mins of not interacting with them or out of range // both of these maybe zone specific, hardcoded for now - if (mHateListCleanup.Check()) { + if (hate_list_cleanup_timer.Check()) { hate_list.RemoveStaleEntries(600000, 600.0f); if (hate_list.IsHateListEmpty()) { AI_Event_NoLongerEngaged(); @@ -1237,7 +1275,7 @@ void Mob::AI_Process() { //try main hand first if (attack_timer.Check()) { DoMainHandAttackRounds(target); - TriggerDefensiveProcs(target, EQEmu::inventory::slotPrimary, false); + TriggerDefensiveProcs(target, EQEmu::invslot::slotPrimary, false); bool specialed = false; // NPCs can only do one of these a round if (GetSpecialAbility(SPECATK_FLURRY)) { @@ -1420,7 +1458,7 @@ void Mob::AI_Process() { if (!IsRooted()) { Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName()); if (!RuleB(Pathing, Aggro) || !zone->pathing) - CalculateNewPosition2(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed()); + CalculateNewPosition(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed()); else { bool WaypointChanged, NodeReached; @@ -1431,7 +1469,7 @@ void Mob::AI_Process() { if (WaypointChanged) tar_ndx = 20; - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed()); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetRunspeed()); } } @@ -1526,8 +1564,7 @@ void Mob::AI_Process() { } else { - CalculateNewPosition2(owner->GetX(), - owner->GetY(), owner->GetZ(), speed); + CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), speed); } } else @@ -1588,7 +1625,7 @@ void Mob::AI_Process() { int speed = GetWalkspeed(); if (dist2 >= followdist + 150) speed = GetRunspeed(); - CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed); + CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), speed); } else { @@ -1671,10 +1708,13 @@ void NPC::AI_DoMovement() { roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y); } + + Log(Logs::Detail, Logs::AI, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)", + roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y); - // Keep calling with updates, using wherever we are in Z. - if (!MakeNewPositionAndSendUpdate(roambox_movingto_x, - roambox_movingto_y, m_Position.z, walksp)) + float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 5) + GetZOffset(); + + if (!CalculateNewPosition(roambox_movingto_x, roambox_movingto_y, new_z, walksp, true)) { this->FixZ(); // FixZ on final arrival point. roambox_movingto_x = roambox_max_x + 1; // force update @@ -1736,7 +1776,7 @@ void NPC::AI_DoMovement() { if (doMove) { // not at waypoint yet or at 0 pause WP, so keep moving if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0)) - CalculateNewPosition2(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true); + CalculateNewPosition(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true); else { bool WaypointChanged; @@ -1748,13 +1788,13 @@ void NPC::AI_DoMovement() { if(NodeReached) entity_list.OpenDoorsNear(CastToNPC()); - CalculateNewPosition2(Goal.x, Goal.y, Goal.z, walksp, true); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, walksp, true); } } } } // endif (gridno > 0) -// handle new quest grid command processing + // handle new quest grid command processing else if (gridno < 0) { // this mob is under quest control if (movetimercompleted==true) @@ -1773,7 +1813,7 @@ void NPC::AI_DoMovement() { { bool CP2Moved; if(!RuleB(Pathing, Guard) || !zone->pathing) - CP2Moved = CalculateNewPosition2(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp); + CP2Moved = CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp); else { if(!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z))) @@ -1786,7 +1826,7 @@ void NPC::AI_DoMovement() { if(NodeReached) entity_list.OpenDoorsNear(CastToNPC()); - CP2Moved = CalculateNewPosition2(Goal.x, Goal.y, Goal.z, walksp); + CP2Moved = CalculateNewPosition(Goal.x, Goal.y, Goal.z, walksp); } else CP2Moved = false; @@ -1992,14 +2032,17 @@ bool NPC::AI_EngagedCastCheck() { // first try innate (spam) spells if(!AICastSpell(GetTarget(), 0, SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root, true)) { - // try casting a heal or gate - if (!AICastSpell(this, AISpellVar.engaged_beneficial_self_chance, SpellType_Heal | SpellType_Escape | SpellType_InCombatBuff)) { - // try casting a heal on nearby - if (!entity_list.AICheckCloseBeneficialSpells(this, AISpellVar.engaged_beneficial_other_chance, MobAISpellRange, SpellType_Heal)) { - //nobody to heal, try some detrimental spells. - if(!AICastSpell(GetTarget(), AISpellVar.engaged_detrimental_chance, SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root)) { - //no spell to cast, try again soon. - AIautocastspell_timer->Start(RandomTimer(AISpellVar.engaged_no_sp_recast_min, AISpellVar.engaged_no_sp_recast_max), false); + // try innate (spam) self targeted spells + if (!AICastSpell(this, 0, SpellType_InCombatBuff, true)) { + // try casting a heal or gate + if (!AICastSpell(this, AISpellVar.engaged_beneficial_self_chance, SpellType_Heal | SpellType_Escape | SpellType_InCombatBuff)) { + // try casting a heal on nearby + if (!entity_list.AICheckCloseBeneficialSpells(this, AISpellVar.engaged_beneficial_other_chance, MobAISpellRange, SpellType_Heal)) { + //nobody to heal, try some detrimental spells. + if(!AICastSpell(GetTarget(), AISpellVar.engaged_detrimental_chance, SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root)) { + //no spell to cast, try again soon. + AIautocastspell_timer->Start(RandomTimer(AISpellVar.engaged_no_sp_recast_min, AISpellVar.engaged_no_sp_recast_max), false); + } } } } @@ -2111,7 +2154,7 @@ bool Mob::Flurry(ExtraAttackOptions *opts) int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1); num_attacks = num_attacks > 0 ? num_attacks : RuleI(Combat, MaxFlurryHits); for (int i = 0; i < num_attacks; i++) - Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts); + Attack(target, EQEmu::invslot::slotPrimary, false, false, false, opts); } return true; } diff --git a/zone/net.cpp b/zone/net.cpp index 80411af7b..f51d50bb4 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -541,11 +541,6 @@ int main(int argc, char** argv) { if (previous_loaded && !current_loaded) { process_timer.Stop(); process_timer.Start(1000, true); - - if (zone && zone->GetZoneID() && zone->GetInstanceVersion()) { - uint32 shutdown_timer = database.getZoneShutDownDelay(zone->GetZoneID(), zone->GetInstanceVersion()); - zone->StartShutdownTimer(shutdown_timer); - } } else if (!previous_loaded && current_loaded) { process_timer.Stop(); diff --git a/zone/npc.cpp b/zone/npc.cpp index 96df168ff..e77ae0618 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -135,7 +135,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if respawn2 = in_respawn; swarm_timer.Disable(); - if (size < 0.0f) + if (size <= 0.0f) size = GetRaceGenderDefaultHeight(race, gender); taunting = false; @@ -837,8 +837,8 @@ void NPC::UpdateEquipmentLight() m_Light.Type[EQEmu::lightsource::LightEquipment] = 0; m_Light.Level[EQEmu::lightsource::LightEquipment] = 0; - for (int index = EQEmu::inventory::slotBegin; index < EQEmu::legacy::EQUIPMENT_SIZE; ++index) { - if (index == EQEmu::inventory::slotAmmo) { continue; } + for (int index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::EQUIPMENT_END; ++index) { + if (index == EQEmu::invslot::slotAmmo) { continue; } auto item = database.GetItem(equipment[index]); if (item == nullptr) { continue; } @@ -985,6 +985,49 @@ bool NPC::SpawnZoneController(){ return true; } +NPC * NPC::SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 grid_id, uint32 grid_number, uint32 pause) { + auto npc_type = new NPCType; + memset(npc_type, 0, sizeof(NPCType)); + + sprintf(npc_type->name, "%u_%u", grid_id, grid_number); + sprintf(npc_type->lastname, "Number: %u Grid: %u Pause: %u", grid_number, grid_id, pause); + + npc_type->cur_hp = 4000000; + npc_type->max_hp = 4000000; + npc_type->race = 2254; + npc_type->gender = 2; + npc_type->class_ = 9; + npc_type->deity = 1; + npc_type->level = 200; + npc_type->npc_id = 0; + npc_type->loottable_id = 0; + npc_type->texture = 1; + npc_type->light = 1; + npc_type->size = 3; + npc_type->runspeed = 0; + npc_type->d_melee_texture1 = 1; + npc_type->d_melee_texture2 = 1; + npc_type->merchanttype = 1; + npc_type->bodytype = 1; + npc_type->show_name = true; + npc_type->STR = 150; + npc_type->STA = 150; + npc_type->DEX = 150; + npc_type->AGI = 150; + npc_type->INT = 150; + npc_type->WIS = 150; + npc_type->CHA = 150; + npc_type->findable = true; + + auto node_position = glm::vec4(position.x, position.y, position.z, position.w); + auto npc = new NPC(npc_type, nullptr, node_position, FlyMode1); + npc->GiveNPCTypeData(npc_type); + + entity_list.AddNPC(npc, true, true); + + return npc; +} + NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) { if(spawncommand == 0 || spawncommand[0] == 0) { return 0; @@ -1648,6 +1691,65 @@ void NPC::PickPocket(Client* thief) thief->SendPickPocketResponse(this, 0, PickPocketFailed); } +void NPC::Disarm(Client* client, int chance) { + // disarm primary if available, otherwise disarm secondary + const EQEmu::ItemData* weapon = NULL; + uint8 eslot = 0xFF; + if (equipment[EQEmu::invslot::slotPrimary] != 0) + eslot = EQEmu::invslot::slotPrimary; + else if (equipment[EQEmu::invslot::slotSecondary] != 0) + eslot = EQEmu::invslot::slotSecondary; + if (eslot != 0xFF) { + if (zone->random.Int(0, 1000) <= chance) { + weapon = database.GetItem(equipment[eslot]); + if (weapon) { + if (!weapon->Magic && weapon->NoDrop == 255) { + int16 charges = -1; + ItemList::iterator cur, end; + cur = itemlist.begin(); + end = itemlist.end(); + // Get charges for the item in the loot table + for (; cur != end; cur++) { + ServerLootItem_Struct* citem = *cur; + if (citem->item_id == weapon->ID) { + charges = citem->charges; + break; + } + } + EQEmu::ItemInstance *inst = NULL; + inst = database.CreateItem(weapon->ID, charges); + // Remove item from loot table + RemoveItem(weapon->ID); + CalcBonuses(); + if (inst) { + // create a ground item + Object* object = new Object(inst, this->GetX(), this->GetY(), this->GetZ(), 0.0f, 300000); + entity_list.AddObject(object, true); + object->StartDecay(); + safe_delete(inst); + } + } + } + // Update Appearance + equipment[eslot] = 0; + int matslot = eslot == EQEmu::invslot::slotPrimary ? EQEmu::textures::weaponPrimary : EQEmu::textures::weaponSecondary; + if (matslot != -1) + SendWearChange(matslot); + if ((CastToMob()->GetBodyType() == BT_Humanoid || CastToMob()->GetBodyType() == BT_Summoned) && eslot == EQEmu::invslot::slotPrimary) + Say("Ahh! My weapon!"); + client->Message_StringID(MT_Skills, DISARM_SUCCESS, this->GetCleanName()); + if (chance != 1000) + client->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 4); + return; + } + client->Message_StringID(MT_Skills, DISARM_FAILED); + if (chance != 1000) + client->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 2); + return; + } + client->Message_StringID(MT_Skills, DISARM_FAILED); +} + void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool remove) { if(reset) { @@ -2715,5 +2817,4 @@ void NPC::ModifyStatsOnCharm(bool bRemoved) // the rest of the stats aren't cached, so lets just do these two instead of full CalcBonuses() SetAttackTimer(); CalcAC(); -} - +} \ No newline at end of file diff --git a/zone/npc.h b/zone/npc.h index 2e264ce24..cba67c698 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -110,10 +110,12 @@ public: virtual ~NPC(); + static NPC *SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 grid_id, uint32 grid_number, uint32 pause); + //abstract virtual function implementations requird by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill); virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None); - virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, + virtual bool Attack(Mob* other, int Hand = EQEmu::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr); virtual bool HasRaid() { return false; } virtual bool HasGroup() { return false; } @@ -276,6 +278,7 @@ public: void SetTaunting(bool tog) {taunting = tog;} bool IsTaunting() const { return taunting; } void PickPocket(Client* thief); + void Disarm(Client* client, int chance); void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); } void AddLootDrop(const EQEmu::ItemData*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0); virtual void DoClassAttacks(Mob *target); @@ -534,7 +537,7 @@ protected: uint16 skills[EQEmu::skills::HIGHEST_SKILL + 1]; - uint32 equipment[EQEmu::legacy::EQUIPMENT_SIZE]; //this is an array of item IDs + uint32 equipment[EQEmu::invslot::EQUIPMENT_COUNT]; //this is an array of item IDs uint32 herosforgemodel; //this is the Hero Forge Armor Model (i.e 63 or 84 or 203) uint16 d_melee_texture1; //this is an item Material value @@ -562,6 +565,8 @@ protected: bool raid_target; bool ignore_despawn; //NPCs with this set to 1 will ignore the despawn value in spawngroup + + private: uint32 loottable_id; bool skip_global_loot; diff --git a/zone/object.cpp b/zone/object.cpp index 0ba5f9fa3..3ad4a6a9c 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -328,7 +328,7 @@ void Object::Delete(bool reset_state) } const EQEmu::ItemInstance* Object::GetItem(uint8 index) { - if (index < EQEmu::legacy::TYPE_WORLD_SIZE) { + if (index < EQEmu::invtype::WORLD_SIZE) { return m_inst->GetItem(index); } @@ -366,7 +366,7 @@ void Object::Close() { EQEmu::ItemInstance* container = this->m_inst; if(container != nullptr) { - for (uint8 i = EQEmu::inventory::containerBegin; i < EQEmu::inventory::ContainerCount; i++) + for (uint8 i = EQEmu::invbag::SLOT_BEGIN; i <= EQEmu::invbag::SLOT_END; i++) { EQEmu::ItemInstance* inst = container->PopItem(i); if(inst != nullptr) @@ -522,11 +522,11 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) // Transfer item to client - sender->PutItemInInventory(EQEmu::inventory::slotCursor, *m_inst, false); - sender->SendItemPacket(EQEmu::inventory::slotCursor, m_inst, ItemPacketTrade); + sender->PutItemInInventory(EQEmu::invslot::slotCursor, *m_inst, false); + sender->SendItemPacket(EQEmu::invslot::slotCursor, m_inst, ItemPacketTrade); if(cursordelete) // delete the item if it's a duplicate lore. We have to do this because the client expects the item packet - sender->DeleteItemInInventory(EQEmu::inventory::slotCursor); + sender->DeleteItemInInventory(EQEmu::invslot::slotCursor); if(!m_ground_spawn) safe_delete(m_inst); @@ -603,7 +603,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) auto outapp = new EQApplicationPacket(OP_ClientReady, 0); sender->QueuePacket(outapp); safe_delete(outapp); - for (uint8 i = EQEmu::inventory::containerBegin; i < EQEmu::inventory::ContainerCount; i++) { + for (uint8 i = EQEmu::invbag::SLOT_BEGIN; i <= EQEmu::invbag::SLOT_END; i++) { const EQEmu::ItemInstance* inst = m_inst->GetItem(i); if (inst) { //sender->GetInv().PutItem(i+4000,inst); diff --git a/zone/pathfinder_interface.cpp b/zone/pathfinder_interface.cpp new file mode 100644 index 000000000..983a85a01 --- /dev/null +++ b/zone/pathfinder_interface.cpp @@ -0,0 +1,22 @@ +#include "../common/seperator.h" +#include "client.h" +#include "pathfinder_null.h" +#include "pathfinder_nav_mesh.h" +#include "pathfinder_waypoint.h" +#include +#include + +IPathfinder *IPathfinder::Load(const std::string &zone) { + struct stat statbuffer; + std::string waypoint_path = fmt::format("maps/path/{0}.path", zone); + std::string navmesh_path = fmt::format("maps/nav/{0}.nav", zone); + if (stat(navmesh_path.c_str(), &statbuffer) == 0) { + return new PathfinderNavmesh(navmesh_path); + } + + if (stat(waypoint_path.c_str(), &statbuffer) == 0) { + return new PathfinderWaypoint(waypoint_path); + } + + return new PathfinderNull(); +} diff --git a/zone/pathfinder_interface.h b/zone/pathfinder_interface.h new file mode 100644 index 000000000..2a874a50d --- /dev/null +++ b/zone/pathfinder_interface.h @@ -0,0 +1,37 @@ +#pragma once + +#include "map.h" +#include + +class Client; +class Seperator; + +class IPathfinder +{ +public: + struct IPathNode + { + IPathNode(const glm::vec3 &p) { + pos = p; + teleport = false; + } + + IPathNode(bool tp) { + teleport = tp; + } + + glm::vec3 pos; + bool teleport; + }; + + typedef std::list IPath; + + IPathfinder() { } + virtual ~IPathfinder() { } + + virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck) = 0; + virtual glm::vec3 GetRandomLocation() = 0; + virtual void DebugCommand(Client *c, const Seperator *sep) = 0; + + static IPathfinder *Load(const std::string &zone); +}; diff --git a/zone/pathfinder_nav_mesh.cpp b/zone/pathfinder_nav_mesh.cpp new file mode 100644 index 000000000..46e4ead56 --- /dev/null +++ b/zone/pathfinder_nav_mesh.cpp @@ -0,0 +1,311 @@ +#include +#include +#include +#include +#include +#include "pathfinder_nav_mesh.h" + +#include "zone.h" +#include "water_map.h" +#include "client.h" +#include "../common/compression.h" + +extern Zone *zone; + +const int MaxNavmeshNodes = 4092; + +struct PathfinderNavmesh::Implementation +{ + dtNavMesh *nav_mesh; + dtNavMeshQuery *query; +}; + +PathfinderNavmesh::PathfinderNavmesh(const std::string &path) +{ + m_impl.reset(new Implementation()); + m_impl->nav_mesh = nullptr; + m_impl->query = nullptr; + Load(path); +} + +PathfinderNavmesh::~PathfinderNavmesh() +{ + Clear(); +} + +IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck) +{ + partial = false; + + if (!m_impl->nav_mesh) { + return IPath(); + } + + if (!m_impl->query) { + m_impl->query = dtAllocNavMeshQuery(); + m_impl->query->init(m_impl->nav_mesh, MaxNavmeshNodes); + } + + glm::vec3 current_location(start.x, start.z, start.y); + glm::vec3 dest_location(end.x, end.z, end.y); + + dtQueryFilter filter; + filter.setIncludeFlags(65535U ^ 2048); + filter.setAreaCost(0, 1.0f); //Normal + filter.setAreaCost(1, 3.0f); //Water + filter.setAreaCost(2, 5.0f); //Lava + filter.setAreaCost(4, 1.0f); //PvP + filter.setAreaCost(5, 2.0f); //Slime + filter.setAreaCost(6, 2.0f); //Ice + filter.setAreaCost(7, 4.0f); //V Water (Frigid Water) + filter.setAreaCost(8, 1.0f); //General Area + filter.setAreaCost(9, 0.1f); //Portal + filter.setAreaCost(10, 0.1f); //Prefer + + dtPolyRef start_ref; + dtPolyRef end_ref; + glm::vec3 ext(5.0f, 100.0f, 5.0f); + + m_impl->query->findNearestPoly(¤t_location[0], &ext[0], &filter, &start_ref, 0); + m_impl->query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0); + + if (!start_ref || !end_ref) { + return IPath(); + } + + int npoly = 0; + dtPolyRef path[1024] = { 0 }; + auto status = m_impl->query->findPath(start_ref, end_ref, ¤t_location[0], &dest_location[0], &filter, path, &npoly, 1024); + + if (npoly) { + glm::vec3 epos = dest_location; + if (path[npoly - 1] != end_ref) { + m_impl->query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0); + partial = true; + + auto dist = DistanceSquared(epos, current_location); + if (dist < 10000.0f) { + stuck = true; + } + } + + float straight_path[2048 * 3]; + unsigned char straight_path_flags[2048]; + + int n_straight_polys; + dtPolyRef straight_path_polys[2048]; + + status = m_impl->query->findStraightPath(¤t_location[0], &epos[0], path, npoly, + straight_path, straight_path_flags, + straight_path_polys, &n_straight_polys, 2048, DT_STRAIGHTPATH_AREA_CROSSINGS); + + if (dtStatusFailed(status)) { + return IPath(); + } + + if (n_straight_polys) { + IPath Route; + for (int i = 0; i < n_straight_polys; ++i) + { + glm::vec3 node; + node.x = straight_path[i * 3]; + node.z = straight_path[i * 3 + 1]; + node.y = straight_path[i * 3 + 2]; + + Route.push_back(node); + + unsigned short flag = 0; + if (dtStatusSucceed(m_impl->nav_mesh->getPolyFlags(straight_path_polys[i], &flag))) { + if (flag & 512) { + Route.push_back(true); + } + } + } + + return Route; + } + } + + IPath Route; + Route.push_back(end); + return Route; +} + +glm::vec3 PathfinderNavmesh::GetRandomLocation() +{ + if (!m_impl->nav_mesh) { + return glm::vec3(); + } + + if (!m_impl->query) { + m_impl->query = dtAllocNavMeshQuery(); + m_impl->query->init(m_impl->nav_mesh, MaxNavmeshNodes); + } + + dtQueryFilter filter; + filter.setIncludeFlags(65535U); + + dtPolyRef randomRef; + float point[3]; + + if (dtStatusSucceed(m_impl->query->findRandomPoint(&filter, []() { + return (float)zone->random.Real(0.0, 1.0); + }, &randomRef, point))) + { + return glm::vec3(point[0], point[2], point[1]); + } + + return glm::vec3(); +} + +void PathfinderNavmesh::DebugCommand(Client *c, const Seperator *sep) +{ + if (sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) + { + c->Message(0, "#path show: Plots a path from the user to their target."); + return; + } + + if (!strcasecmp(sep->arg[1], "show")) + { + if (c->GetTarget() != nullptr) { + auto target = c->GetTarget(); + glm::vec3 start(c->GetX(), c->GetY(), c->GetZ()); + glm::vec3 end(target->GetX(), target->GetY(), target->GetZ()); + + ShowPath(c, start, end); + } + + return; + } +} + +void PathfinderNavmesh::Clear() +{ + if (m_impl->nav_mesh) { + dtFreeNavMesh(m_impl->nav_mesh); + } + + if (m_impl->query) { + dtFreeNavMeshQuery(m_impl->query); + } +} + +void PathfinderNavmesh::Load(const std::string &path) +{ + Clear(); + + FILE *f = fopen(path.c_str(), "rb"); + if (f) { + char magic[9] = { 0 }; + if (fread(magic, 9, 1, f) != 1) { + fclose(f); + return; + } + + if (strncmp(magic, "EQNAVMESH", 9) != 0) + { + fclose(f); + return; + } + + uint32_t version = 0; + if (fread(&version, sizeof(uint32_t), 1, f) != 1) { + fclose(f); + return; + } + + if (version != 2) { + fclose(f); + return; + } + + uint32_t data_size; + if (fread(&data_size, sizeof(data_size), 1, f) != 1) { + fclose(f); + return; + } + + uint32_t buffer_size; + if (fread(&buffer_size, sizeof(buffer_size), 1, f) != 1) { + fclose(f); + return; + } + + std::vector data; + data.resize(data_size); + if (fread(&data[0], data_size, 1, f) != 1) { + fclose(f); + return; + } + + std::vector buffer; + buffer.resize(buffer_size); + uint32_t v = EQEmu::InflateData(&data[0], data_size, &buffer[0], buffer_size); + fclose(f); + + char *buf = &buffer[0]; + m_impl->nav_mesh = dtAllocNavMesh(); + + uint32_t number_of_tiles = *(uint32_t*)buf; + buf += sizeof(uint32_t); + + dtNavMeshParams params = *(dtNavMeshParams*)buf; + buf += sizeof(dtNavMeshParams); + + dtStatus status = m_impl->nav_mesh->init(¶ms); + if (dtStatusFailed(status)) + { + dtFreeNavMesh(m_impl->nav_mesh); + m_impl->nav_mesh = nullptr; + return; + } + + for (unsigned int i = 0; i < number_of_tiles; ++i) + { + uint32_t tile_ref = *(uint32_t*)buf; + buf += sizeof(uint32_t); + + int32_t data_size = *(uint32_t*)buf; + buf += sizeof(uint32_t); + + if (!tile_ref || !data_size) { + dtFreeNavMesh(m_impl->nav_mesh); + m_impl->nav_mesh = nullptr; + return; + } + + unsigned char* data = (unsigned char*)dtAlloc(data_size, DT_ALLOC_PERM); + memcpy(data, buf, data_size); + buf += data_size; + + m_impl->nav_mesh->addTile(data, data_size, DT_TILE_FREE_DATA, tile_ref, 0); + } + + Log(Logs::General, Logs::Status, "Loaded Navmesh V%u file %s", version, path.c_str()); + } +} + +void PathfinderNavmesh::ShowPath(Client * c, const glm::vec3 &start, const glm::vec3 &end) +{ + bool partial = false; + bool stuck = false; + auto path = FindRoute(start, end, partial, stuck); + std::vector points; + + if (!partial) { + FindPerson_Point p; + for (auto &node : path) + { + if (!node.teleport) { + p.x = node.pos.x; + p.y = node.pos.y; + p.z = node.pos.z; + + points.push_back(p); + } + } + } + + c->SendPathPacket(points); +} diff --git a/zone/pathfinder_nav_mesh.h b/zone/pathfinder_nav_mesh.h new file mode 100644 index 000000000..e740e5ca7 --- /dev/null +++ b/zone/pathfinder_nav_mesh.h @@ -0,0 +1,23 @@ +#pragma once + +#include "pathfinder_interface.h" +#include + +class PathfinderNavmesh : public IPathfinder +{ +public: + PathfinderNavmesh(const std::string &path); + virtual ~PathfinderNavmesh(); + + virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck); + virtual glm::vec3 GetRandomLocation(); + virtual void DebugCommand(Client *c, const Seperator *sep); + +private: + void Clear(); + void Load(const std::string &path); + void ShowPath(Client *c, const glm::vec3 &start, const glm::vec3 &end); + + struct Implementation; + std::unique_ptr m_impl; +}; \ No newline at end of file diff --git a/zone/pathfinder_null.cpp b/zone/pathfinder_null.cpp new file mode 100644 index 000000000..dce3d19f5 --- /dev/null +++ b/zone/pathfinder_null.cpp @@ -0,0 +1,16 @@ +#include "pathfinder_null.h" + +IPathfinder::IPath PathfinderNull::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck) +{ + partial = false; + stuck = false; + IPath ret; + ret.push_back(start); + ret.push_back(end); + return ret; +} + +glm::vec3 PathfinderNull::GetRandomLocation() +{ + return glm::vec3(); +} diff --git a/zone/pathfinder_null.h b/zone/pathfinder_null.h new file mode 100644 index 000000000..2c43e3085 --- /dev/null +++ b/zone/pathfinder_null.h @@ -0,0 +1,14 @@ +#pragma once + +#include "pathfinder_interface.h" + +class PathfinderNull : public IPathfinder +{ +public: + PathfinderNull() { } + virtual ~PathfinderNull() { } + + virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck); + virtual glm::vec3 GetRandomLocation(); + virtual void DebugCommand(Client *c, const Seperator *sep) { } +}; \ No newline at end of file diff --git a/zone/pathfinder_waypoint.cpp b/zone/pathfinder_waypoint.cpp new file mode 100644 index 000000000..86dd4a4a4 --- /dev/null +++ b/zone/pathfinder_waypoint.cpp @@ -0,0 +1,564 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pathfinder_waypoint.h" +#include "zone.h" +#include "client.h" +#include "../common/eqemu_logsys.h" +#include "../common/string_util.h" +#include "../common/rulesys.h" + +extern Zone *zone; + +#pragma pack(1) +struct NeighbourNode { + int16 id; + float distance; + uint8 Teleport; + int16 DoorID; +}; + +struct PathNode { + uint16 id; + glm::vec3 v; + float bestz; + NeighbourNode Neighbours[50]; +}; + +struct PathFileHeader { + uint32 version; + uint32 PathNodeCount; +}; +#pragma pack() + +struct Edge +{ + float distance; + bool teleport; + int door_id; +}; + +struct Node +{ + int id; + glm::vec3 v; + float bestz; + std::map edges; +}; + +template +class distance_heuristic : public boost::astar_heuristic +{ +public: + typedef typename boost::graph_traits::vertex_descriptor Vertex; + + distance_heuristic(NodeMap n, Vertex goal) + : m_node(n), m_goal(goal) {} + CostType operator()(Vertex u) + { + CostType dx = m_node[m_goal].v.x - m_node[u].v.x; + CostType dy = m_node[m_goal].v.y - m_node[u].v.y; + CostType dz = m_node[m_goal].v.z - m_node[u].v.z; + return ::sqrt(dx * dx + dy * dy + dz * dz); + } +private: + NodeMap m_node; + Vertex m_goal; +}; + +struct found_goal {}; +template +class astar_goal_visitor : public boost::default_astar_visitor +{ +public: + astar_goal_visitor(Vertex goal) : m_goal(goal) {} + template + void examine_vertex(Vertex u, Graph& g) { + if (u == m_goal) + throw found_goal(); + } +private: + Vertex m_goal; +}; + +typedef boost::geometry::model::point Point; +typedef std::pair RTreeValue; +typedef boost::adjacency_list> GraphType; +typedef boost::property_map::type WeightMap; + +struct PathfinderWaypoint::Implementation { + bool PathFileValid; + boost::geometry::index::rtree> Tree; + GraphType Graph; + std::vector Nodes; + std::string FileName; +}; + +PathfinderWaypoint::PathfinderWaypoint(const std::string &path) +{ + m_impl.reset(new Implementation()); + m_impl->PathFileValid = false; + m_impl->FileName = path; + Load(path); +} + +PathfinderWaypoint::~PathfinderWaypoint() +{ +} + +IPathfinder::IPath PathfinderWaypoint::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck) +{ + stuck = false; + partial = false; + std::vector result_start_n; + m_impl->Tree.query(boost::geometry::index::nearest(Point(start.x, start.y, start.z), 1), std::back_inserter(result_start_n)); + if (result_start_n.size() == 0) { + return IPath(); + } + + std::vector result_end_n; + m_impl->Tree.query(boost::geometry::index::nearest(Point(end.x, end.y, end.z), 1), std::back_inserter(result_end_n)); + if (result_end_n.size() == 0) { + return IPath(); + } + + auto &nearest_start = *result_start_n.begin(); + auto &nearest_end = *result_end_n.begin(); + + if (nearest_start.second == nearest_end.second) { + IPath Route; + Route.push_back(start); + Route.push_back(end); + return Route; + } + + std::vector p(boost::num_vertices(m_impl->Graph)); + try { + boost::astar_search(m_impl->Graph, nearest_start.second, + distance_heuristic(&m_impl->Nodes[0], nearest_end.second), + boost::predecessor_map(&p[0]) + .visitor(astar_goal_visitor(nearest_end.second))); + } + catch (found_goal) + { + IPath Route; + + Route.push_front(end); + for (size_t v = nearest_end.second;; v = p[v]) { + if (p[v] == v) { + Route.push_front(m_impl->Nodes[v].v); + break; + } + else { + auto &node = m_impl->Nodes[v]; + + auto iter = node.edges.find((int)p[v + 1]); + if (iter != node.edges.end()) { + auto &edge = iter->second; + if (edge.teleport) { + Route.push_front(m_impl->Nodes[v].v); + Route.push_front(true); + } + else { + Route.push_front(m_impl->Nodes[v].v); + } + } + else { + Route.push_front(m_impl->Nodes[v].v); + } + } + } + + Route.push_front(start); + return Route; + } + + return IPath(); +} + +glm::vec3 PathfinderWaypoint::GetRandomLocation() +{ + if (m_impl->Nodes.size() > 0) { + auto idx = zone->random.Int(0, (int)m_impl->Nodes.size() - 1); + auto &node = m_impl->Nodes[idx]; + + return node.v; + } + + return glm::vec3(); +} + +void PathfinderWaypoint::DebugCommand(Client *c, const Seperator *sep) +{ + if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) + { + c->Message(0, "Syntax: #path shownodes: Spawns a npc to represent every npc node."); + c->Message(0, "#path show: Plots a path from the user to their target."); + c->Message(0, "#path info node_id: Gives information about node info (requires shownode target)."); + return; + } + + if(!strcasecmp(sep->arg[1], "shownodes")) + { + ShowNodes(); + return; + } + + if (!strcasecmp(sep->arg[1], "show")) + { + if (c->GetTarget() != nullptr) { + auto target = c->GetTarget(); + glm::vec3 start(c->GetX(), c->GetY(), c->GetZ()); + glm::vec3 end(target->GetX(), target->GetY(), target->GetZ()); + + ShowPath(c, start, end); + } + + return; + } + + if (!strcasecmp(sep->arg[1], "reload")) + { + Load(m_impl->FileName); + return; + } + + if (!strcasecmp(sep->arg[1], "info")) + { + NodeInfo(c); + return; + } +} + +void PathfinderWaypoint::Load(const std::string &filename) { + PathFileHeader Head; + Head.PathNodeCount = 0; + Head.version = 2; + + FILE *f = fopen(filename.c_str(), "rb"); + if (f) { + char Magic[10]; + + fread(&Magic, 9, 1, f); + + if (strncmp(Magic, "EQEMUPATH", 9)) + { + Log(Logs::General, Logs::Error, "Bad Magic String in .path file."); + fclose(f); + return; + } + + fread(&Head, sizeof(Head), 1, f); + + Log(Logs::General, Logs::Status, "Path File Header: Version %ld, PathNodes %ld", + (long)Head.version, (long)Head.PathNodeCount); + + if (Head.version == 2) + { + LoadV2(f, Head); + return; + } + else if (Head.version == 3) { + LoadV3(f, Head); + return; + } + else { + Log(Logs::General, Logs::Error, "Unsupported path file version."); + fclose(f); + return; + } + } +} + +void PathfinderWaypoint::LoadV2(FILE *f, const PathFileHeader &header) +{ + std::unique_ptr PathNodes(new PathNode[header.PathNodeCount]); + + fread(PathNodes.get(), sizeof(PathNode), header.PathNodeCount, f); + + int MaxNodeID = header.PathNodeCount - 1; + + m_impl->PathFileValid = true; + + m_impl->Nodes.reserve(header.PathNodeCount); + for (uint32 i = 0; i < header.PathNodeCount; ++i) + { + auto &n = PathNodes[i]; + Node node; + node.id = i; + node.v = n.v; + node.bestz = n.bestz; + m_impl->Nodes.push_back(node); + } + + auto weightmap = boost::get(boost::edge_weight, m_impl->Graph); + for (uint32 i = 0; i < header.PathNodeCount; ++i) { + for (uint32 j = 0; j < 50; ++j) + { + auto &node = m_impl->Nodes[i]; + if (PathNodes[i].Neighbours[j].id > MaxNodeID) + { + Log(Logs::General, Logs::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id); + m_impl->PathFileValid = false; + } + + if (PathNodes[i].Neighbours[j].id > 0) { + Edge edge; + edge.distance = PathNodes[i].Neighbours[j].distance; + edge.door_id = PathNodes[i].Neighbours[j].DoorID; + edge.teleport = PathNodes[i].Neighbours[j].Teleport; + + node.edges[PathNodes[i].Neighbours[j].id] = edge; + } + } + } + + BuildGraph(); + fclose(f); +} + +void PathfinderWaypoint::LoadV3(FILE *f, const PathFileHeader &header) +{ + m_impl->Nodes.reserve(header.PathNodeCount); + + uint32 edge_count = 0; + fread(&edge_count, sizeof(uint32), 1, f); + + for (uint32 i = 0; i < header.PathNodeCount; ++i) + { + uint32 id = 0; + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + float best_z = 0.0f; + + fread(&id, sizeof(uint32), 1, f); + fread(&x, sizeof(float), 1, f); + fread(&y, sizeof(float), 1, f); + fread(&z, sizeof(float), 1, f); + fread(&best_z, sizeof(float), 1, f); + + Node n; + n.id = id; + n.bestz = best_z; + n.v.x = x; + n.v.y = y; + n.v.z = z; + + m_impl->Nodes.push_back(n); + } + + for (uint32 j = 0; j < edge_count; ++j) { + uint32 from = 0; + uint32 to = 0; + int8 teleport = 0; + float distance = 0.0f; + int32 door_id = 0; + + fread(&from, sizeof(uint32), 1, f); + fread(&to, sizeof(uint32), 1, f); + fread(&teleport, sizeof(int8), 1, f); + fread(&distance, sizeof(float), 1, f); + fread(&door_id, sizeof(int32), 1, f); + + Edge e; + e.teleport = teleport > 0 ? true : false; + e.distance = distance; + e.door_id = door_id; + + auto &n = m_impl->Nodes[from]; + n.edges[to] = e; + } + + m_impl->PathFileValid = true; + + BuildGraph(); + fclose(f); +} + +void PathfinderWaypoint::ShowNodes() +{ + for (size_t i = 0; i < m_impl->Nodes.size(); ++i) + { + ShowNode(m_impl->Nodes[i]); + } +} + +void PathfinderWaypoint::ShowPath(Client *c, const glm::vec3 &start, const glm::vec3 &end) +{ + bool partial = false; + bool stuck = false; + auto path = FindRoute(start, end, partial, stuck); + std::vector points; + + FindPerson_Point p; + for (auto &node : path) + { + if (!node.teleport) { + p.x = node.pos.x; + p.y = node.pos.y; + p.z = node.pos.z; + + points.push_back(p); + } + } + + c->SendPathPacket(points); +} + +void PathfinderWaypoint::NodeInfo(Client *c) +{ + if (!c->GetTarget()) { + return; + } + + auto node = FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); + if (node == nullptr) { + return; + } + + c->Message(0, "Pathing node: %i at (%.2f, %.2f, %.2f) with bestz %.2f", + node->id, node->v.x, node->v.y, node->v.z, node->bestz); + + for (auto &edge : node->edges) { + c->Message(0, "id: %i, distance: %.2f, door id: %i, is teleport: %i", + edge.first, + edge.second.distance, + edge.second.door_id, + edge.second.teleport); + } +} + +Node *PathfinderWaypoint::FindPathNodeByCoordinates(float x, float y, float z) +{ + for (auto &node : m_impl->Nodes) { + auto dist = Distance(glm::vec3(x, y, z), node.v); + + if (dist < 0.1) { + return &node; + } + } + + return nullptr; +} + +void PathfinderWaypoint::BuildGraph() +{ + m_impl->Graph = GraphType(); + m_impl->Tree = boost::geometry::index::rtree>(); + + for (auto &node : m_impl->Nodes) { + RTreeValue rtv; + rtv.first = Point(node.v.x, node.v.y, node.v.z); + rtv.second = node.id; + m_impl->Tree.insert(rtv); + boost::add_vertex(m_impl->Graph); + } + + //Populate edges now that we've created all the nodes + auto weightmap = boost::get(boost::edge_weight, m_impl->Graph); + for (auto &node : m_impl->Nodes) { + for (auto &edge : node.edges) { + GraphType::edge_descriptor e; + bool inserted; + boost::tie(e, inserted) = boost::add_edge(node.id, edge.first, m_impl->Graph); + weightmap[e] = edge.second.distance; + } + } +} + +std::string DigitToWord(int i) +{ + std::string digit = std::to_string(i); + std::string ret; + for (size_t idx = 0; idx < digit.length(); ++idx) { + if (!ret.empty()) { + ret += "_"; + } + + switch (digit[idx]) { + case '0': + ret += "Zero"; + break; + case '1': + ret += "One"; + break; + case '2': + ret += "Two"; + break; + case '3': + ret += "Three"; + break; + case '4': + ret += "Four"; + break; + case '5': + ret += "Five"; + break; + case '6': + ret += "Six"; + break; + case '7': + ret += "Seven"; + break; + case '8': + ret += "Eight"; + break; + case '9': + ret += "Nine"; + break; + default: + break; + } + } + + return ret; +} + +void PathfinderWaypoint::ShowNode(const Node &n) { + auto npc_type = new NPCType; + memset(npc_type, 0, sizeof(NPCType)); + + sprintf(npc_type->name, "%s", DigitToWord(n.id).c_str()); + sprintf(npc_type->lastname, "%i", n.id); + npc_type->cur_hp = 4000000; + npc_type->max_hp = 4000000; + npc_type->race = 2254; + npc_type->gender = 2; + npc_type->class_ = 9; + npc_type->deity = 1; + npc_type->level = 75; + npc_type->npc_id = 0; + npc_type->loottable_id = 0; + npc_type->texture = 1; + npc_type->light = 0; + npc_type->runspeed = 0; + npc_type->d_melee_texture1 = 1; + npc_type->d_melee_texture2 = 1; + npc_type->merchanttype = 1; + npc_type->bodytype = 1; + npc_type->show_name = true; + + npc_type->STR = 150; + npc_type->STA = 150; + npc_type->DEX = 150; + npc_type->AGI = 150; + npc_type->INT = 150; + npc_type->WIS = 150; + npc_type->CHA = 150; + + npc_type->findable = 1; + auto position = glm::vec4(n.v.x, n.v.y, n.v.z, 0.0f); + auto npc = new NPC(npc_type, nullptr, position, FlyMode1); + npc->GiveNPCTypeData(npc_type); + + entity_list.AddNPC(npc, true, true); +} diff --git a/zone/pathfinder_waypoint.h b/zone/pathfinder_waypoint.h new file mode 100644 index 000000000..3f6b99c9f --- /dev/null +++ b/zone/pathfinder_waypoint.h @@ -0,0 +1,31 @@ +#pragma once + +#include "pathfinder_interface.h" + +struct PathFileHeader; +struct Node; + +class PathfinderWaypoint : public IPathfinder +{ +public: + PathfinderWaypoint(const std::string &path); + virtual ~PathfinderWaypoint(); + + virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck); + virtual glm::vec3 GetRandomLocation(); + virtual void DebugCommand(Client *c, const Seperator *sep); + +private: + void Load(const std::string &filename); + void LoadV2(FILE *f, const PathFileHeader &header); + void LoadV3(FILE *f, const PathFileHeader &header); + void ShowNodes(); + void ShowPath(Client *c, const glm::vec3 &start, const glm::vec3 &end); + void NodeInfo(Client *c); + Node *FindPathNodeByCoordinates(float x, float y, float z); + void BuildGraph(); + void ShowNode(const Node &n); + + struct Implementation; + std::unique_ptr m_impl; +}; \ No newline at end of file diff --git a/zone/pathing.cpp b/zone/pathing.cpp index 7f2d8c880..4829bcc83 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -1,2289 +1,293 @@ #include "../common/global_define.h" +#include "../common/event/background_task.h" #include "client.h" -#include "doors.h" -#include "pathing.h" -#include "water_map.h" #include "zone.h" - -#include -#include -#include -#include -#include - -#ifdef _WINDOWS -#define snprintf _snprintf -#endif - -//#define PATHDEBUG +#include "water_map.h" extern Zone *zone; -float VectorDistance(glm::vec3 a, glm::vec3 b) -{ - float xdist = a.x - b.x; - float ydist = a.y - b.y; - float zdist = a.z - b.z; - return sqrtf(xdist * xdist + ydist * ydist + zdist * zdist); -} - -float VectorDistanceNoRoot(glm::vec3 a, glm::vec3 b) -{ - float xdist = a.x - b.x; - float ydist = a.y - b.y; - float zdist = a.z - b.z; - return xdist * xdist + ydist * ydist + zdist * zdist; - -} - -PathManager* PathManager::LoadPathFile(const char* ZoneName) -{ - - FILE *PathFile = nullptr; - - char LowerCaseZoneName[64]; - - char ZonePathFileName[256]; - - PathManager* Ret = nullptr; - - strn0cpy(LowerCaseZoneName, ZoneName, 64); - - strlwr(LowerCaseZoneName); - - snprintf(ZonePathFileName, 250, "%s%s.path", Config->MapDir.c_str(), LowerCaseZoneName); - - if((PathFile = fopen(ZonePathFileName, "rb"))) - { - Ret = new PathManager(); - - if(Ret->loadPaths(PathFile)) - { - Log(Logs::General, Logs::Status, "Path File %s loaded.", ZonePathFileName); - - } - else - { - Log(Logs::General, Logs::Error, "Path File %s failed to load.", ZonePathFileName); - safe_delete(Ret); - } - fclose(PathFile); +void AdjustRoute(std::list &nodes, int flymode, float offset) { + if (!zone->HasMap() || !zone->HasWaterMap()) { + return; } - else - { - Log(Logs::General, Logs::Error, "Path File %s not found.", ZonePathFileName); - } - - return Ret; -} - -PathManager::PathManager() -{ - PathNodes = nullptr; - ClosedListFlag = nullptr; - Head.PathNodeCount = 0; - Head.version = 2; - QuickConnectTarget = -1; -} - -PathManager::~PathManager() -{ - safe_delete_array(PathNodes); - safe_delete_array(ClosedListFlag); -} - -bool PathManager::loadPaths(FILE *PathFile) -{ - - char Magic[10]; - - fread(&Magic, 9, 1, PathFile); - - if(strncmp(Magic, "EQEMUPATH", 9)) - { - Log(Logs::General, Logs::Error, "Bad Magic String in .path file."); - return false; - } - - fread(&Head, sizeof(Head), 1, PathFile); - - Log(Logs::General, Logs::Status, "Path File Header: Version %ld, PathNodes %ld", - (long)Head.version, (long)Head.PathNodeCount); - - if(Head.version != 2) - { - Log(Logs::General, Logs::Error, "Unsupported path file version."); - return false; - } - - PathNodes = new PathNode[Head.PathNodeCount]; - - fread(PathNodes, sizeof(PathNode), Head.PathNodeCount, PathFile); - - ClosedListFlag = new int[Head.PathNodeCount]; - -#ifdef PATHDEBUG - PrintPathing(); -#endif - - int MaxNodeID = Head.PathNodeCount - 1; - - bool PathFileValid = true; - - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - for(uint32 j = 0; j < PATHNODENEIGHBOURS; ++j) - { - if(PathNodes[i].Neighbours[j].id > MaxNodeID) - { - Log(Logs::General, Logs::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id); - - PathFileValid = false; + + for (auto &node : nodes) { + if (flymode == 0 || !zone->watermap->InLiquid(node.pos)) { + auto best_z = zone->zonemap->FindBestZ(node.pos, nullptr); + if (best_z != BEST_Z_INVALID) { + node.pos.z = best_z + offset; } } } - - if(!PathFileValid) - { - safe_delete_array(PathNodes); - } - - return PathFileValid; -} - -void PathManager::PrintPathing() -{ - - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - printf("PathNode: %2d id %2d. (%8.3f, %8.3f, %8.3f), BestZ: %8.3f\n", - i, PathNodes[i].id, PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, PathNodes[i].bestz); - - - if(PathNodes[i].Neighbours[0].id == -1) - { - printf(" NO NEIGHBOURS.\n"); - continue; - } - - for(int j=0; j= 0) - printf(" ***** via door %i *****", PathNodes[i].Neighbours[j].DoorID); - - printf("\n"); - } - } -} - -glm::vec3 PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ) -{ - glm::vec3 Result; - - if(NodeNumber < Head.PathNodeCount) - { - Result = PathNodes[NodeNumber].v; - - if(!BestZ) - return Result; - - Result.z = PathNodes[NodeNumber].bestz; - } - - return Result; - -} - -std::deque PathManager::FindRoute(int startID, int endID) -{ - Log(Logs::Detail, Logs::Pathing, "FindRoute from node %i to %i", startID, endID); - - memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount); - - std::deque OpenList, ClosedList; - - std::dequeRoute; - - AStarNode AStarEntry, CurrentNode; - - AStarEntry.PathNodeID = startID; - AStarEntry.Parent = -1; - AStarEntry.HCost = 0; - AStarEntry.GCost = 0; - AStarEntry.Teleport = false; - - OpenList.push_back(AStarEntry); - - while(!OpenList.empty()) - { - // The OpenList is maintained in sorted order, lowest to highest cost. - - CurrentNode = (*OpenList.begin()); - - ClosedList.push_back(CurrentNode); - - ClosedListFlag[CurrentNode.PathNodeID] = true; - - OpenList.pop_front(); - - for(int i = 0; i < PATHNODENEIGHBOURS; ++i) - { - if(PathNodes[CurrentNode.PathNodeID].Neighbours[i].id == -1) - break; - - if(PathNodes[CurrentNode.PathNodeID].Neighbours[i].id == CurrentNode.Parent) - continue; - - if(PathNodes[CurrentNode.PathNodeID].Neighbours[i].id == endID) - { - Route.push_back(CurrentNode.PathNodeID); - - Route.push_back(endID); - - std::deque::iterator RouteIterator; - - while(CurrentNode.PathNodeID != startID) - { - for(RouteIterator = ClosedList.begin(); RouteIterator != ClosedList.end(); ++RouteIterator) - { - if((*RouteIterator).PathNodeID == CurrentNode.Parent) - { - if(CurrentNode.Teleport) - Route.insert(Route.begin(), -1); - - CurrentNode = (*RouteIterator); - - Route.insert(Route.begin(), CurrentNode.PathNodeID); - - break; - } - } - } - - return Route; - } - if(ClosedListFlag[PathNodes[CurrentNode.PathNodeID].Neighbours[i].id]) - continue; - - AStarEntry.PathNodeID = PathNodes[CurrentNode.PathNodeID].Neighbours[i].id; - - AStarEntry.Parent = CurrentNode.PathNodeID; - - AStarEntry.Teleport = PathNodes[CurrentNode.PathNodeID].Neighbours[i].Teleport; - - // HCost is the estimated cost to get from this node to the end. - AStarEntry.HCost = VectorDistance(PathNodes[PathNodes[CurrentNode.PathNodeID].Neighbours[i].id].v, - PathNodes[endID].v); - - AStarEntry.GCost = CurrentNode.GCost + PathNodes[CurrentNode.PathNodeID].Neighbours[i].distance; - - float FCost = AStarEntry.HCost + AStarEntry.GCost; -#ifdef PATHDEBUG - printf("Node: %i, Open Neighbour %i has HCost %8.3f, GCost %8.3f (Total Cost: %8.3f)\n", - CurrentNode.PathNodeID, - PathNodes[CurrentNode.PathNodeID].Neighbours[i].id, - AStarEntry.HCost, - AStarEntry.GCost, - AStarEntry.HCost + AStarEntry.GCost); -#endif - - bool AlreadyInOpenList = false; - - std::deque::iterator OpenListIterator, InsertionPoint = OpenList.end(); - - for(OpenListIterator = OpenList.begin(); OpenListIterator != OpenList.end(); ++OpenListIterator) - { - if((*OpenListIterator).PathNodeID == PathNodes[CurrentNode.PathNodeID].Neighbours[i].id) - { - AlreadyInOpenList = true; - - float GCostToNode = CurrentNode.GCost + PathNodes[CurrentNode.PathNodeID].Neighbours[i].distance; - - if(GCostToNode < (*OpenListIterator).GCost) - { - (*OpenListIterator).Parent = CurrentNode.PathNodeID; - - (*OpenListIterator).GCost = GCostToNode; - - (*OpenListIterator).Teleport = PathNodes[CurrentNode.PathNodeID].Neighbours[i].Teleport; - } - break; - } - else if((InsertionPoint == OpenList.end()) && (((*OpenListIterator).HCost + (*OpenListIterator).GCost) > FCost)) - { - InsertionPoint = OpenListIterator; - } - } - if(!AlreadyInOpenList) - OpenList.insert(InsertionPoint, AStarEntry); - } - - } - Log(Logs::Detail, Logs::Pathing, "Unable to find a route."); - return Route; - -} - -bool CheckLOSBetweenPoints(glm::vec3 start, glm::vec3 end) { - - glm::vec3 hit; - - if((zone->zonemap) && (zone->zonemap->LineIntersectsZone(start, end, 1, &hit))) - return false; - - return true; -} - -auto path_compare = [](const PathNodeSortStruct& a, const PathNodeSortStruct& b) -{ - return a.Distance < b.Distance; -}; - -std::deque PathManager::FindRoute(glm::vec3 Start, glm::vec3 End) -{ - Log(Logs::Detail, Logs::Pathing, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z); - - std::deque noderoute; - - float CandidateNodeRangeXY = RuleR(Pathing, CandidateNodeRangeXY); - - float CandidateNodeRangeZ = RuleR(Pathing, CandidateNodeRangeZ); - - // Find the nearest PathNode the Start has LOS to. - // - // - int ClosestPathNodeToStart = -1; - - std::deque SortedByDistance; - - PathNodeSortStruct TempNode; - - for(uint32 i = 0 ; i < Head.PathNodeCount; ++i) - { - if ((std::abs(Start.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) && - (std::abs(Start.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) && - (std::abs(Start.z - PathNodes[i].v.z) <= CandidateNodeRangeZ)) { - TempNode.id = i; - TempNode.Distance = VectorDistanceNoRoot(Start, PathNodes[i].v); - SortedByDistance.push_back(TempNode); - - } - } - - std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare); - - for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator) - { - Log(Logs::Detail, Logs::Pathing, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id); - - if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Iterator).id].v, 1.0f, nullptr)) - { - ClosestPathNodeToStart = (*Iterator).id; - break; - } - } - - if(ClosestPathNodeToStart <0 ) { - Log(Logs::Detail, Logs::Pathing, "No LOS to any starting Path Node within range."); - return noderoute; - } - - Log(Logs::Detail, Logs::Pathing, "Closest Path Node To Start: %2d", ClosestPathNodeToStart); - - // Find the nearest PathNode the end point has LOS to - - int ClosestPathNodeToEnd = -1; - - SortedByDistance.clear(); - - for(uint32 i = 0 ; i < Head.PathNodeCount; ++i) - { - if ((std::abs(End.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) && - (std::abs(End.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) && - (std::abs(End.z - PathNodes[i].v.z) <= CandidateNodeRangeZ)) { - TempNode.id = i; - TempNode.Distance = VectorDistanceNoRoot(End, PathNodes[i].v); - SortedByDistance.push_back(TempNode); - } - } - - std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare); - - for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator) - { - Log(Logs::Detail, Logs::Pathing, "Checking Reachability of Node %i from End Position.", PathNodes[(*Iterator).id].id); - Log(Logs::Detail, Logs::Pathing, " (%8.3f, %8.3f, %8.3f) to (%8.3f, %8.3f, %8.3f)", - End.x, End.y, End.z, - PathNodes[(*Iterator).id].v.x, PathNodes[(*Iterator).id].v.y, PathNodes[(*Iterator).id].v.z); - - if(!zone->zonemap->LineIntersectsZone(End, PathNodes[(*Iterator).id].v, 1.0f, nullptr)) - { - ClosestPathNodeToEnd = (*Iterator).id; - break; - } - } - - if(ClosestPathNodeToEnd < 0) { - Log(Logs::Detail, Logs::Pathing, "No LOS to any end Path Node within range."); - return noderoute; - } - - Log(Logs::Detail, Logs::Pathing, "Closest Path Node To End: %2d", ClosestPathNodeToEnd); - - if(ClosestPathNodeToStart == ClosestPathNodeToEnd) - { - noderoute.push_back(ClosestPathNodeToStart); - return noderoute; - } - noderoute = FindRoute(ClosestPathNodeToStart, ClosestPathNodeToEnd); - - int NodesToAttemptToCull = RuleI(Pathing, CullNodesFromStart); - - if(NodesToAttemptToCull > 0) - { - int CulledNodes = 0; - - std::deque::iterator First, Second; - - while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull)) - { - First = noderoute.begin(); - - Second = First; - - ++Second; - - if((*Second) < 0) - break; - - if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Second)].v, 1.0f, nullptr) - && zone->pathing->NoHazards(Start, PathNodes[(*Second)].v)) - { - noderoute.erase(First); - - ++CulledNodes; - } - else - break; - } - } - - NodesToAttemptToCull = RuleI(Pathing, CullNodesFromEnd); - - if(NodesToAttemptToCull > 0) - { - int CulledNodes = 0; - - std::deque::iterator First, Second; - - while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull)) - { - First = noderoute.end(); - - --First; - - Second = First; - - --Second; - - if((*Second) < 0) - break; - - if(!zone->zonemap->LineIntersectsZone(End, PathNodes[(*Second)].v, 1.0f, nullptr) - && zone->pathing->NoHazards(End, PathNodes[(*Second)].v)) - { - noderoute.erase(First); - - ++CulledNodes; - } - else - break; - } - } - - return noderoute; -} - -const char* DigitToWord(int i) -{ - switch(i) { - case 0: - return "zero"; - case 1: - return "one"; - case 2: - return "two"; - case 3: - return "three"; - case 4: - return "four"; - case 5: - return "five"; - case 6: - return "six"; - case 7: - return "seven"; - case 8: - return "eight"; - case 9: - return "nine"; - } - return ""; -} - -void PathManager::SpawnPathNodes() -{ - - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - auto npc_type = new NPCType; - memset(npc_type, 0, sizeof(NPCType)); - - if(PathNodes[i].id < 10) - sprintf(npc_type->name, "%s", DigitToWord(PathNodes[i].id)); - else if(PathNodes[i].id < 100) - sprintf(npc_type->name, "%s_%s", DigitToWord(PathNodes[i].id/10), DigitToWord(PathNodes[i].id % 10)); - else - sprintf(npc_type->name, "%s_%s_%s", DigitToWord(PathNodes[i].id/100), DigitToWord((PathNodes[i].id % 100)/10), - DigitToWord(((PathNodes[i].id % 100) %10))); - - sprintf(npc_type->lastname, "%i", PathNodes[i].id); - npc_type->cur_hp = 4000000; - npc_type->max_hp = 4000000; - npc_type->race = 2253; - npc_type->size = 3.0f; - npc_type->gender = 2; - npc_type->class_ = 9; - npc_type->deity= 1; - npc_type->level = 75; - npc_type->npc_id = 0; - npc_type->loottable_id = 0; - npc_type->texture = 1; - npc_type->light = 0; - npc_type->runspeed = 0; - npc_type->d_melee_texture1 = 1; - npc_type->d_melee_texture2 = 1; - npc_type->merchanttype = 1; - npc_type->bodytype = 1; - - npc_type->STR = 150; - npc_type->STA = 150; - npc_type->DEX = 150; - npc_type->AGI = 150; - npc_type->INT = 150; - npc_type->WIS = 150; - npc_type->CHA = 150; - - npc_type->findable = 1; - auto position = glm::vec4(PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0.0f); - auto npc = new NPC(npc_type, nullptr, position, FlyMode1); - npc->GiveNPCTypeData(npc_type); - - entity_list.AddNPC(npc, true, true); - } -} - -void PathManager::MeshTest() -{ - // This will test connectivity between all path nodes - - int TotalTests = 0; - int NoConnections = 0; - - printf("Beginning Pathmanager connectivity tests.\n"); fflush(stdout); - - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - for(uint32 j = 0; j < Head.PathNodeCount; ++j) - { - if(j == i) - continue; - - std::deque Route = FindRoute(PathNodes[i].id, PathNodes[j].id); - - if(Route.empty()) - { - ++NoConnections; - printf("FindRoute(%i, %i) **** NO ROUTE FOUND ****\n", PathNodes[i].id, PathNodes[j].id); - } - ++TotalTests; - } - } - printf("Executed %i route searches.\n", TotalTests); - printf("Failed to find %i routes.\n", NoConnections); - fflush(stdout); -} - -void PathManager::SimpleMeshTest() -{ - // This will test connectivity between the first path node and all other nodes - - int TotalTests = 0; - int NoConnections = 0; - - printf("Beginning Pathmanager connectivity tests.\n"); - fflush(stdout); - - for(uint32 j = 1; j < Head.PathNodeCount; ++j) - { - std::deque Route = FindRoute(PathNodes[0].id, PathNodes[j].id); - - if(Route.empty()) - { - ++NoConnections; - printf("FindRoute(%i, %i) **** NO ROUTE FOUND ****\n", PathNodes[0].id, PathNodes[j].id); - } - ++TotalTests; - } - printf("Executed %i route searches.\n", TotalTests); - printf("Failed to find %i routes.\n", NoConnections); - fflush(stdout); } glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged, bool &NodeReached) { - WaypointChanged = false; - - NodeReached = false; - - glm::vec3 NodeLoc; + glm::vec3 To(ToX, ToY, ToZ); + if (Speed <= 0) { + return To; + } glm::vec3 From(GetX(), GetY(), GetZ()); - glm::vec3 HeadPosition(From.x, From.y, From.z + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION); - - glm::vec3 To(ToX, ToY, ToZ); - - bool SameDestination = (To == PathingDestination); - - if (Speed <= 0) // our speed is 0, we cant move so lets return the dest - return To; // this will also avoid the teleports cleanly - - int NextNode; - - if(To == From) + if (DistanceSquared(To, From) < 1.0f) { + WaypointChanged = false; + NodeReached = true; + Route.clear(); return To; + } - Log(Logs::Detail, Logs::Pathing, "UpdatePath. From(%8.3f, %8.3f, %8.3f) To(%8.3f, %8.3f, %8.3f)", From.x, From.y, From.z, To.x, To.y, To.z); + if (Route.empty()) { + bool partial = false; + bool stuck = false; + Route = zone->pathing->FindRoute(From, To, partial, stuck); + AdjustRoute(Route, flymode, GetZOffset()); - if(From == PathingLastPosition) - { - ++PathingLoopCount; + PathingDestination = To; + WaypointChanged = true; + NodeReached = false; + if (stuck) { + return HandleStuckPath(To, From); + } - if((PathingLoopCount > 5) && !IsRooted()) - { - Log(Logs::Detail, Logs::Pathing, "appears to be stuck. Teleporting them to next position.", GetName()); - - if(Route.empty()) - { - Teleport(To); + if (Route.empty()) { + return To; + } + else { + return (*Route.begin()).pos; + } + } + else { + if (PathRecalcTimer->Check()) { + bool SameDestination = DistanceSquared(To, PathingDestination) < 100.0f; + if (!SameDestination) { + //We had a route but our target position moved too much + bool partial = false; + bool stuck = false; + Route = zone->pathing->FindRoute(From, To, partial, stuck); + AdjustRoute(Route, flymode, GetZOffset()); + PathingDestination = To; WaypointChanged = true; + NodeReached = false; - PathingLoopCount = 0; + if (stuck) { + return HandleStuckPath(To, From); + } - return To; + if (Route.empty()) { + return To; + } + else { + return (*Route.begin()).pos; + } } - NodeLoc = zone->pathing->GetPathNodeCoordinates(Route.front()); + } + + if (!IsRooted()) { + bool AtPrevNode = DistanceSquared(From, PathingLastPosition) < 1.0f; + if (AtPrevNode) { + PathingLoopCount++; + auto front = (*Route.begin()).pos; + + if (PathingLoopCount > 5) { + Teleport(front); + SendPosition(); + Route.pop_front(); + + WaypointChanged = true; + NodeReached = true; + PathingLoopCount = 0; + } + + return front; + } + else { + PathingLastPosition = From; + PathingLoopCount = 0; + } + } + else { + PathingLastPosition = From; + PathingLoopCount = 0; + } + + bool AtNextNode = false; + if (flymode == 1) { + AtNextNode = DistanceSquared(From, (*Route.begin()).pos) < 4.0f; + } + else { + float z_dist = From.z - (*Route.begin()).pos.z; + z_dist *= z_dist; + AtNextNode = DistanceSquaredNoZ(From, (*Route.begin()).pos) < 4.0f && z_dist < 25.0f; + } + + if (AtNextNode) { + WaypointChanged = false; + NodeReached = true; Route.pop_front(); - ++PathingTraversedNodes; - - Teleport(NodeLoc); - - WaypointChanged = true; - - PathingLoopCount = 0; - - return NodeLoc; - } - } - else - { - PathingLoopCount = 0; - - PathingLastPosition = From; - } - - if(!Route.empty()) - { - - // If we are already pathing, and the destination is the same as before ... - if(SameDestination) - { - Log(Logs::Detail, Logs::Pathing, " Still pathing to the same destination."); - - // Get the coordinates of the first path node we are going to. - NextNode = Route.front(); - - NodeLoc = zone->pathing->GetPathNodeCoordinates(NextNode); - - // May need to refine this as rounding errors may mean we never have equality - // We have reached the path node. - if(NodeLoc.x == From.x && NodeLoc.y == From.y) - { - Log(Logs::Detail, Logs::Pathing, " Arrived at node %i", NextNode); - - NodeReached = true; - - PathingLastNodeVisited = Route.front(); - // We only check for LOS again after traversing more than 1 node, otherwise we can get into - // a loop where we have a hazard and so run to a path node far enough away from the hazard, and - // then run right back towards the same hazard again. - // - // An exception is when we are about to head for the last node. We always check LOS then. This - // is because we are seeking a path to the node nearest to our target. This node may be behind the - // target, and we may run past the target if we don't check LOS at this point. - int RouteSize = Route.size(); - - Log(Logs::Detail, Logs::Pathing, "Route size is %i", RouteSize); - - if((RouteSize == 2) - || ((PathingTraversedNodes >= RuleI(Pathing, MinNodesTraversedForLOSCheck)) - && (RouteSize <= RuleI(Pathing, MinNodesLeftForLOSCheck)) - && PathingLOSCheckTimer->Check())) - { - Log(Logs::Detail, Logs::Pathing, " Checking distance to target."); - float Distance = VectorDistanceNoRoot(From, To); - - Log(Logs::Detail, Logs::Pathing, " Distance between From and To (NoRoot) is %8.3f", Distance); - - if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) && - (std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThresholdNew))) { - if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr)) - PathingLOSState = HaveLOS; - else - PathingLOSState = NoLOS; - Log(Logs::Detail, Logs::Pathing, "NoLOS"); - - if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To)) - { - Log(Logs::Detail, Logs::Pathing, " No hazards. Running directly to target."); - Route.clear(); - - return To; - } - else - { - Log(Logs::Detail, Logs::Pathing, " Continuing on node path."); - } - } - else - PathingLOSState = UnknownLOS; - } - // We are on the same route, no LOS (or not checking this time, so pop off the node we just reached - // - Route.pop_front(); - - ++PathingTraversedNodes; - + if (Route.empty()) { + bool partial = false; + bool stuck = false; + Route = zone->pathing->FindRoute(From, To, partial, stuck); + AdjustRoute(Route, flymode, GetZOffset()); + PathingDestination = To; WaypointChanged = true; - // If there are more nodes on the route, return the coords of the next node - if(!Route.empty()) - { - NextNode = Route.front(); - - if(NextNode == -1) - { - // -1 indicates a teleport to the next node - Route.pop_front(); - - if(Route.empty()) - { - Log(Logs::Detail, Logs::Pathing, "Missing node after teleport."); - return To; - } - - NextNode = Route.front(); - - NodeLoc = zone->pathing->GetPathNodeCoordinates(NextNode); - - Teleport(NodeLoc); - - Log(Logs::Detail, Logs::Pathing, " TELEPORTED to %8.3f, %8.3f, %8.3f\n", NodeLoc.x, NodeLoc.y, NodeLoc.z); - - Route.pop_front(); - - if(Route.empty()) - return To; - - NextNode = Route.front(); - } - zone->pathing->OpenDoors(PathingLastNodeVisited, NextNode, this); - - Log(Logs::Detail, Logs::Pathing, " Now moving to node %i", NextNode); - - return zone->pathing->GetPathNodeCoordinates(NextNode); - } - else - { - // we have run all the nodes, all that is left is the direct path from the last node - // to the destination - Log(Logs::Detail, Logs::Pathing, " Reached end of node path, running direct to target."); - + if (stuck) { + return HandleStuckPath(To, From); + } + + if(Route.empty()) { return To; } + else { + return (*Route.begin()).pos; + } } - // At this point, we are still on the previous path, but not reached a node yet. - // The route shouldn't be empty, but check anyway. - // - int RouteSize = Route.size(); - - if((PathingTraversedNodes >= RuleI(Pathing, MinNodesTraversedForLOSCheck)) - && (RouteSize <= RuleI(Pathing, MinNodesLeftForLOSCheck)) - && PathingLOSCheckTimer->Check()) - { - Log(Logs::Detail, Logs::Pathing, " Checking distance to target."); - - float Distance = VectorDistanceNoRoot(From, To); - - Log(Logs::Detail, Logs::Pathing, " Distance between From and To (NoRoot) is %8.3f", Distance); - - if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) && - (std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThresholdNew))) { - if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr)) - PathingLOSState = HaveLOS; - else - PathingLOSState = NoLOS; - Log(Logs::Detail, Logs::Pathing, "NoLOS"); - - if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To)) - { - Log(Logs::Detail, Logs::Pathing, " No hazards. Running directly to target."); - Route.clear(); + else { + auto node = *Route.begin(); + if (node.teleport) { + Route.pop_front(); + if (Route.empty()) { return To; } - else - { - Log(Logs::Detail, Logs::Pathing, " Continuing on node path."); - } - } - else - PathingLOSState = UnknownLOS; - } - return NodeLoc; - } - else - { - // We get here if we were already pathing, but our destination has now changed. - // - Log(Logs::Detail, Logs::Pathing, " Target has changed position."); - // Update our record of where we are going to. - PathingDestination = To; - // Check if we now have LOS etc to the new destination. - if(PathingLOSCheckTimer->Check()) - { - float Distance = VectorDistanceNoRoot(From, To); - if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) && - (std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThresholdNew))) { - Log(Logs::Detail, Logs::Pathing, " Checking for short LOS at distance %8.3f.", Distance); - if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr)) - PathingLOSState = HaveLOS; - else - PathingLOSState = NoLOS; + auto nextNode = *Route.begin(); - Log(Logs::Detail, Logs::Pathing, "NoLOS"); - - if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To)) - { - Log(Logs::Detail, Logs::Pathing, " No hazards. Running directly to target."); - Route.clear(); - return To; - } - else - { - Log(Logs::Detail, Logs::Pathing, " Continuing on node path."); - } - } - } - - // If the player is moving, we don't want to recalculate our route too frequently. - // - if(static_cast(Route.size()) <= RuleI(Pathing, RouteUpdateFrequencyNodeCount)) - { - if(!PathingRouteUpdateTimerShort->Check()) - { - Log(Logs::Detail, Logs::Pathing, "Short route update timer not yet expired."); - return zone->pathing->GetPathNodeCoordinates(Route.front()); - } - Log(Logs::Detail, Logs::Pathing, "Short route update timer expired."); - } - else - { - if(!PathingRouteUpdateTimerLong->Check()) - { - Log(Logs::Detail, Logs::Pathing, "Long route update timer not yet expired."); - return zone->pathing->GetPathNodeCoordinates(Route.front()); - } - Log(Logs::Detail, Logs::Pathing, "Long route update timer expired."); - } - - // We are already pathing, destination changed, no LOS. Find the nearest node to our destination. - int DestinationPathNode= zone->pathing->FindNearestPathNode(To); - - // Destination unreachable via pathing, return direct route. - if(DestinationPathNode == -1) - { - Log(Logs::Detail, Logs::Pathing, " Unable to find path node for new destination. Running straight to target."); - Route.clear(); - return To; - } - // If the nearest path node to our new destination is the same as for the previous - // one, we will carry on on our path. - if(DestinationPathNode == Route.back()) - { - Log(Logs::Detail, Logs::Pathing, " Same destination Node (%i). Continue with current path.", DestinationPathNode); - - NodeLoc = zone->pathing->GetPathNodeCoordinates(Route.front()); - - // May need to refine this as rounding errors may mean we never have equality - // Check if we have reached a path node. - if(NodeLoc.x == From.x && NodeLoc.y == From.y) - { - Log(Logs::Detail, Logs::Pathing, " Arrived at node %i, moving to next one.\n", Route.front()); - - NodeReached = true; - - PathingLastNodeVisited = Route.front(); + Teleport(nextNode.pos); Route.pop_front(); - ++PathingTraversedNodes; - - WaypointChanged = true; - - if(!Route.empty()) - { - NextNode = Route.front(); - - if(NextNode == -1) - { - // -1 indicates a teleport to the next node - Route.pop_front(); - - if(Route.empty()) - { - Log(Logs::Detail, Logs::Pathing, "Missing node after teleport."); - return To; - } - - NextNode = Route.front(); - - NodeLoc = zone->pathing->GetPathNodeCoordinates(NextNode); - - Teleport(NodeLoc); - - Log(Logs::Detail, Logs::Pathing, " TELEPORTED to %8.3f, %8.3f, %8.3f\n", NodeLoc.x, NodeLoc.y, NodeLoc.z); - - Route.pop_front(); - - if(Route.empty()) - return To; - - NextNode = Route.front(); - } - // Return the coords of our next path node on the route. - Log(Logs::Detail, Logs::Pathing, " Now moving to node %i", NextNode); - - zone->pathing->OpenDoors(PathingLastNodeVisited, NextNode, this); - - return zone->pathing->GetPathNodeCoordinates(NextNode); - } - else - { - Log(Logs::Detail, Logs::Pathing, " Reached end of path grid. Running direct to target."); + if (Route.empty()) { return To; } + + return (*Route.begin()).pos; } - return NodeLoc; - } - else - { - Log(Logs::Detail, Logs::Pathing, " Target moved. End node is different. Clearing route."); - Route.clear(); - // We will now fall through to get a new route. + return node.pos; + } + } + else { + WaypointChanged = false; + NodeReached = false; + return (*Route.begin()).pos; + } + } + + return To; +} + +glm::vec3 Mob::HandleStuckPath(const glm::vec3 &To, const glm::vec3 &From) +{ + bool partial = false; + bool stuck = false; + auto r = zone->pathing->FindRoute(To, From, partial, stuck); + Route.clear(); + + if (r.size() < 1) { + Teleport(To); + return To; + } + + auto iter = r.rbegin(); + auto final_node = (*iter); + Teleport(final_node.pos); + + if (r.size() < 2) { + return final_node.pos; + } + else { + iter++; + return (*iter).pos; + } +} + +void CullPoints(std::vector &points) { + if (!zone->HasMap()) { + return; + } + + size_t i = 0; + for (; i < points.size(); ++i) { + auto &p = points[i]; + + for (;;) { + if (i + 2 >= points.size()) { + return; } - } + if (points.size() < 36) { + return; + } + auto &p1 = points[i + 1]; + auto &p2 = points[i + 2]; - } - Log(Logs::Detail, Logs::Pathing, " Our route list is empty."); - - if((SameDestination) && !PathingLOSCheckTimer->Check()) - { - Log(Logs::Detail, Logs::Pathing, " Destination same as before, LOS check timer not reached. Returning To."); - return To; - } - - PathingLOSState = UnknownLOS; - - PathingDestination = To; - - WaypointChanged = true; - - float Distance = VectorDistanceNoRoot(From, To); - - if ((Distance <= RuleR(Pathing, MinDistanceForLOSCheckLong)) && - (std::abs(From.z - To.z) <= RuleR(Pathing, ZDiffThresholdNew))) { - Log(Logs::Detail, Logs::Pathing, " Checking for long LOS at distance %8.3f.", Distance); - - if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr)) - PathingLOSState = HaveLOS; - else - PathingLOSState = NoLOS; - - Log(Logs::Detail, Logs::Pathing, "NoLOS"); - - if((PathingLOSState == HaveLOS) && zone->pathing->NoHazards(From, To)) - { - Log(Logs::Detail, Logs::Pathing, "Target is reachable. Running directly there."); - return To; - } - } - Log(Logs::Detail, Logs::Pathing, " Calculating new route to target."); - - Route = zone->pathing->FindRoute(From, To); - - PathingTraversedNodes = 0; - - if(Route.empty()) - { - Log(Logs::Detail, Logs::Pathing, " No route available, running direct."); - - return To; - } - - if(SameDestination && (Route.front() == PathingLastNodeVisited)) - { - Log(Logs::Detail, Logs::Pathing, " Probable loop detected. Same destination and Route.front() == PathingLastNodeVisited."); - - Route.clear(); - - return To; - } - NodeLoc = zone->pathing->GetPathNodeCoordinates(Route.front()); - - Log(Logs::Detail, Logs::Pathing, " New route determined, heading for node %i", Route.front()); - - PathingLoopCount = 0; - - return NodeLoc; - -} - -int PathManager::FindNearestPathNode(glm::vec3 Position) -{ - - // Find the nearest PathNode we have LOS to. - // - // - - float CandidateNodeRangeXY = RuleR(Pathing, CandidateNodeRangeXY); - - float CandidateNodeRangeZ = RuleR(Pathing, CandidateNodeRangeZ); - - int ClosestPathNodeToStart = -1; - - std::deque SortedByDistance; - - PathNodeSortStruct TempNode; - - for(uint32 i = 0 ; i < Head.PathNodeCount; ++i) - { - if ((std::abs(Position.x - PathNodes[i].v.x) <= CandidateNodeRangeXY) && - (std::abs(Position.y - PathNodes[i].v.y) <= CandidateNodeRangeXY) && - (std::abs(Position.z - PathNodes[i].v.z) <= CandidateNodeRangeZ)) { - TempNode.id = i; - TempNode.Distance = VectorDistanceNoRoot(Position, PathNodes[i].v); - SortedByDistance.push_back(TempNode); - - } - } - - std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare); - - for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator) - { - Log(Logs::Detail, Logs::Pathing, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id); - - if(!zone->zonemap->LineIntersectsZone(Position, PathNodes[(*Iterator).id].v, 1.0f, nullptr)) - { - ClosestPathNodeToStart = (*Iterator).id; - break; - } - } - - if(ClosestPathNodeToStart <0 ) { - Log(Logs::Detail, Logs::Pathing, "No LOS to any starting Path Node within range."); - return -1; - } - return ClosestPathNodeToStart; -} - -bool PathManager::NoHazards(glm::vec3 From, glm::vec3 To) -{ - // Test the Z coordinate at the mid point. - // - glm::vec3 MidPoint((From.x + To.x) / 2, (From.y + To.y) / 2, From.z); - - float NewZ = zone->zonemap->FindBestZ(MidPoint, nullptr); - - if (std::abs(NewZ - From.z) > RuleR(Pathing, ZDiffThresholdNew)) { - Log(Logs::Detail, Logs::Pathing, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Z Change is %8.3f", - From.x, From.y, From.z, MidPoint.x, MidPoint.y, MidPoint.z, NewZ - From.z); - - return false; - } - else - { - Log(Logs::Detail, Logs::Pathing, "No HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Z Change is %8.3f", - From.x, From.y, From.z, MidPoint.x, MidPoint.y, MidPoint.z, NewZ - From.z); - } - - return true; -} - -bool PathManager::NoHazardsAccurate(glm::vec3 From, glm::vec3 To) -{ - float stepx, stepy, stepz, curx, cury, curz; - glm::vec3 cur = From; - float last_z = From.z; - float step_size = 1.0; - - curx = From.x; - cury = From.y; - curz = From.z; - - do - { - stepx = (float)To.x - curx; - stepy = (float)To.y - cury; - stepz = (float)To.z - curz; - float factor = sqrt(stepx*stepx + stepy*stepy + stepz*stepz); - stepx = (stepx / factor)*step_size; - stepy = (stepy / factor)*step_size; - stepz = (stepz / factor)*step_size; - - glm::vec3 TestPoint(curx, cury, curz); - float NewZ = zone->zonemap->FindBestZ(TestPoint, nullptr); - if (std::abs(NewZ - last_z) > 5.0f) { - Log(Logs::Detail, Logs::Pathing, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Best Z %8.3f, Z Change is %8.3f", - From.x, From.y, From.z, TestPoint.x, TestPoint.y, TestPoint.z, NewZ, NewZ - From.z); - return false; - } - last_z = NewZ; - - if (zone->watermap) - { - auto from = glm::vec3(From.x, From.y, From.z); - auto to = glm::vec3(To.x, To.y, To.z); - if (zone->watermap->InLiquid(from) || zone->watermap->InLiquid(to)) - { + if (zone->zonemap->CheckLoS(glm::vec3(p.x, p.y, p.z), glm::vec3(p2.x, p2.y, p2.z))) { + points.erase(points.begin() + i + 1); + Log(Logs::General, Logs::Status, "Culled find path point %u, connecting %u->%u instead.", i + 1, i, i + 2); + } + else { break; } - auto testPointNewZ = glm::vec3(TestPoint.x, TestPoint.y, NewZ); - if (zone->watermap->InLiquid(testPointNewZ)) - { - glm::vec3 TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f); - glm::vec3 TestPointWaterDest = TestPointWater; - glm::vec3 hit; - TestPointWaterDest.z -= 500; - float best_z2 = -999990; - if (zone->zonemap->LineIntersectsZone(TestPointWater, TestPointWaterDest, 1.0f, &hit)) - { - best_z2 = hit.z; - } - if (best_z2 == -999990) - { - Log(Logs::Detail, Logs::Pathing, " HAZARD DETECTED, really deep water/lava!"); - return false; - } - else - { - if (std::abs(NewZ - best_z2) > RuleR(Pathing, ZDiffThresholdNew)) { - Log(Logs::Detail, Logs::Pathing, - " HAZARD DETECTED, water is fairly deep at %8.3f units deep", - std::abs(NewZ - best_z2)); - return false; - } - else - { - Log(Logs::Detail, Logs::Pathing, - " HAZARD NOT DETECTED, water is shallow at %8.3f units deep", - std::abs(NewZ - best_z2)); - } - } - } - else - { - Log(Logs::Detail, Logs::Pathing, "Hazard point not in water or lava!"); - } } - else - { - Log(Logs::Detail, Logs::Pathing, "No water map loaded for hazards!"); - } - - curx += stepx; - cury += stepy; - curz += stepz; - - cur.x = curx; - cur.y = cury; - cur.z = curz; - - if (std::abs(curx - To.x) < step_size) - cur.x = To.x; - if (std::abs(cury - To.y) < step_size) - cur.y = To.y; - if (std::abs(curz - To.z) < step_size) - cur.z = To.z; - - } while (cur.x != To.x || cur.y != To.y || cur.z != To.z); - return true; -} - -void Mob::PrintRoute() -{ - - printf("Route is : "); - - for(auto Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator) - { - printf("%i, ", (*Iterator)); } - - printf("\n"); - } -void PathManager::OpenDoors(int Node1, int Node2, Mob *ForWho) -{ - if(!ForWho || (Node1 >= Head.PathNodeCount) || (Node2 >= Head.PathNodeCount) || (Node1 < 0) || (Node2 < 0)) - return; +void Client::SendPathPacket(const std::vector &points) { + EQ::BackgroundTask task([](EQEmu::Any &data) { + auto &points = EQEmu::any_cast&>(data); + CullPoints(points); + }, [this](EQEmu::Any &data) { + auto &points = EQEmu::any_cast&>(data); - for(int i = 0; i < PATHNODENEIGHBOURS; ++i) - { - if(PathNodes[Node1].Neighbours[i].id == -1) - return; - - if(PathNodes[Node1].Neighbours[i].id != Node2) - continue; - - if(PathNodes[Node1].Neighbours[i].DoorID >= 0) - { - Doors *d = entity_list.FindDoor(PathNodes[Node1].Neighbours[i].DoorID); - - if(d && !d->IsDoorOpen() ) - { - Log(Logs::Detail, Logs::Pathing, "Opening door %i for %s", PathNodes[Node1].Neighbours[i].DoorID, ForWho->GetName()); - - d->ForceOpen(ForWho); + if (points.size() < 2) { + if (Admin() > 10) { + Message(MT_System, "Too few points"); } + + EQApplicationPacket outapp(OP_FindPersonReply, 0); + QueuePacket(&outapp); return; } - } -} -//this assumes that the first point in the list is the player's -//current position, I dont know how well it works if its not. -void Client::SendPathPacket(std::vector &points) { - if(points.size() < 2) { - //empty length packet == not found. - EQApplicationPacket outapp(OP_FindPersonReply, 0); - QueuePacket(&outapp); - return; - } + if (points.size() > 36) { + if (Admin() > 10) { + Message(MT_System, "Too many points %u", points.size()); + } - int len = sizeof(FindPersonResult_Struct) + (points.size()+1) * sizeof(FindPerson_Point); - auto outapp = new EQApplicationPacket(OP_FindPersonReply, len); - FindPersonResult_Struct* fpr=(FindPersonResult_Struct*)outapp->pBuffer; + EQApplicationPacket outapp(OP_FindPersonReply, 0); + QueuePacket(&outapp); + return; + } - std::vector::iterator cur, end; - cur = points.begin(); - end = points.end(); - unsigned int r; - for(r = 0; cur != end; ++cur, r++) { + if (Admin() > 10) { + Message(MT_System, "Total points %u", points.size()); + } + + int len = sizeof(FindPersonResult_Struct) + (points.size() + 1) * sizeof(FindPerson_Point); + auto outapp = new EQApplicationPacket(OP_FindPersonReply, len); + FindPersonResult_Struct* fpr = (FindPersonResult_Struct*)outapp->pBuffer; + + std::vector::iterator cur, end; + cur = points.begin(); + end = points.end(); + unsigned int r; + for (r = 0; cur != end; ++cur, r++) { + fpr->path[r] = *cur; + + } + //put the last element into the destination field + --cur; fpr->path[r] = *cur; + fpr->dest = *cur; - } - //put the last element into the destination field - --cur; - fpr->path[r] = *cur; - fpr->dest = *cur; - - FastQueuePacket(&outapp); - - + FastQueuePacket(&outapp); + }, points); } - -PathNode* PathManager::FindPathNodeByCoordinates(float x, float y, float z) -{ - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - if((PathNodes[i].v.x == x) && (PathNodes[i].v.y == y) && (PathNodes[i].v.z == z)) - return &PathNodes[i]; - - return nullptr; -} - -int PathManager::GetRandomPathNode() -{ - return zone->random.Int(0, Head.PathNodeCount - 1); - -} - -void PathManager::ShowPathNodeNeighbours(Client *c) -{ - if(!c || !c->GetTarget()) - return; - - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - - if(!Node) - { - c->Message(0, "Unable to find path node."); - return; - } - c->Message(0, "Path node %4i", Node->id); - - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - char Name[64]; - - if(PathNodes[i].id < 10) - sprintf(Name, "%s000", DigitToWord(PathNodes[i].id)); - else if(PathNodes[i].id < 100) - sprintf(Name, "%s_%s000", DigitToWord(PathNodes[i].id / 10), DigitToWord(PathNodes[i].id % 10)); - else - sprintf(Name, "%s_%s_%s000", DigitToWord(PathNodes[i].id/100), DigitToWord((PathNodes[i].id % 100)/10), - DigitToWord(((PathNodes[i].id % 100) %10))); - - Mob *m = entity_list.GetMob(Name); - - if(m) - m->ChangeSize(3.0f); - } - - std::stringstream Neighbours; - - for(int i = 0; i < PATHNODENEIGHBOURS; ++i) - { - if(Node->Neighbours[i].id == -1) - break; - Neighbours << Node->Neighbours[i].id << ", "; - - char Name[64]; - - if(Node->Neighbours[i].id < 10) - sprintf(Name, "%s000", DigitToWord(Node->Neighbours[i].id)); - else if(Node->Neighbours[i].id < 100) - sprintf(Name, "%s_%s000", DigitToWord(Node->Neighbours[i].id / 10), DigitToWord(Node->Neighbours[i].id % 10)); - else - sprintf(Name, "%s_%s_%s000", DigitToWord(Node->Neighbours[i].id/100), DigitToWord((Node->Neighbours[i].id % 100)/10), - DigitToWord(((Node->Neighbours[i].id % 100) %10))); - - Mob *m = entity_list.GetMob(Name); - - if(m) - m->ChangeSize(5.0f); - } - c->Message(0, "Neighbours: %s", Neighbours.str().c_str()); -} - -void PathManager::NodeInfo(Client *c) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - c->Message(0, "Pathing node: %i at (%.2f, %.2f, %.2f) with bestz %.2f", - Node->id, Node->v.x, Node->v.y, Node->v.z, Node->bestz); - - bool neighbour = false; - for(int x = 0; x < 50; ++x) - { - if(Node->Neighbours[x].id != -1) - { - if(!neighbour) - { - c->Message(0, "Neighbours found:"); - neighbour = true; - } - c->Message(0, "id: %i, distance: %.2f, door id: %i, is teleport: %i", - Node->Neighbours[x].id, Node->Neighbours[x].distance, - Node->Neighbours[x].DoorID, Node->Neighbours[x].Teleport); - } - } - - if(!neighbour) - { - c->Message(0, "No neighbours found!"); - } - return; -} - -void PathManager::DumpPath(std::string filename) -{ - std::ofstream o_file; - - std::string file_to_write = StringFormat("%s%s", Config->MapDir.c_str(), filename.c_str()); - - o_file.open(file_to_write.c_str(), std::ios_base::binary | std::ios_base::trunc | std::ios_base::out); - o_file.write("EQEMUPATH", 9); - o_file.write((const char*)&Head, sizeof(Head)); - o_file.write((const char*)PathNodes, (sizeof(PathNode)*Head.PathNodeCount)); - o_file.close(); -} - -int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 requested_id) -{ - int32 new_id = -1; - if(requested_id != 0) - { - new_id = requested_id; - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - if(PathNodes[i].id == requested_id) - { - new_id = -1; - break; - } - } - } - - if(new_id == -1) - { - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - if(PathNodes[i].id - new_id > 1) { - new_id = PathNodes[i].id - 1; - break; - } - - if(PathNodes[i].id > new_id) - new_id = PathNodes[i].id; - } - new_id++; - } - - PathNode new_node; - new_node.v.x = x; - new_node.v.y = y; - new_node.v.z = z; - new_node.bestz = best_z; - new_node.id = (uint16)new_id; - for(int x = 0; x < PATHNODENEIGHBOURS; ++x) - { - new_node.Neighbours[x].id = -1; - new_node.Neighbours[x].distance = 0.0; - new_node.Neighbours[x].DoorID = -1; - new_node.Neighbours[x].Teleport = 0; - } - - Head.PathNodeCount++; - if(Head.PathNodeCount > 1) - { - auto t_PathNodes = new PathNode[Head.PathNodeCount]; - for(uint32 x = 0; x < (Head.PathNodeCount - 1); ++x) - { - t_PathNodes[x].v.x = PathNodes[x].v.x; - t_PathNodes[x].v.y = PathNodes[x].v.y; - t_PathNodes[x].v.z = PathNodes[x].v.z; - t_PathNodes[x].bestz = PathNodes[x].bestz; - t_PathNodes[x].id = PathNodes[x].id; - for(int n = 0; n < PATHNODENEIGHBOURS; ++n) - { - t_PathNodes[x].Neighbours[n].distance = PathNodes[x].Neighbours[n].distance; - t_PathNodes[x].Neighbours[n].DoorID = PathNodes[x].Neighbours[n].DoorID; - t_PathNodes[x].Neighbours[n].id = PathNodes[x].Neighbours[n].id; - t_PathNodes[x].Neighbours[n].Teleport = PathNodes[x].Neighbours[n].Teleport; - } - - } - - int32 index = (Head.PathNodeCount - 1); - t_PathNodes[index].v.x = new_node.v.x; - t_PathNodes[index].v.y = new_node.v.y; - t_PathNodes[index].v.z = new_node.v.z; - t_PathNodes[index].bestz = new_node.bestz; - t_PathNodes[index].id = new_node.id; - for(int n = 0; n < PATHNODENEIGHBOURS; ++n) - { - t_PathNodes[index].Neighbours[n].distance = new_node.Neighbours[n].distance; - t_PathNodes[index].Neighbours[n].DoorID = new_node.Neighbours[n].DoorID; - t_PathNodes[index].Neighbours[n].id = new_node.Neighbours[n].id; - t_PathNodes[index].Neighbours[n].Teleport = new_node.Neighbours[n].Teleport; - } - - delete[] PathNodes; - PathNodes = t_PathNodes; - - auto npc_type = new NPCType; - memset(npc_type, 0, sizeof(NPCType)); - if(new_id < 10) - sprintf(npc_type->name, "%s", DigitToWord(new_id)); - else if(new_id < 100) - sprintf(npc_type->name, "%s_%s", DigitToWord(new_id/10), DigitToWord(new_id % 10)); - else - sprintf(npc_type->name, "%s_%s_%s", DigitToWord(new_id/100), DigitToWord((new_id % 100)/10), - DigitToWord(((new_id % 100) %10))); - - sprintf(npc_type->lastname, "%i", new_id); - npc_type->cur_hp = 4000000; - npc_type->max_hp = 4000000; - npc_type->race = 2253; - npc_type->size = 3.0f; - npc_type->gender = 2; - npc_type->class_ = 9; - npc_type->deity= 1; - npc_type->level = 75; - npc_type->npc_id = 0; - npc_type->loottable_id = 0; - npc_type->texture = 1; - npc_type->light = 0; - npc_type->runspeed = 0; - npc_type->d_melee_texture1 = 1; - npc_type->d_melee_texture2 = 1; - npc_type->merchanttype = 1; - npc_type->bodytype = 1; - npc_type->STR = 150; - npc_type->STA = 150; - npc_type->DEX = 150; - npc_type->AGI = 150; - npc_type->INT = 150; - npc_type->WIS = 150; - npc_type->CHA = 150; - npc_type->findable = 1; - - auto position = glm::vec4(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f); - auto npc = new NPC(npc_type, nullptr, position, FlyMode1); - npc->GiveNPCTypeData(npc_type); - entity_list.AddNPC(npc, true, true); - - safe_delete_array(ClosedListFlag); - ClosedListFlag = new int[Head.PathNodeCount]; - return new_id; - } - else - { - PathNodes = new PathNode[Head.PathNodeCount]; - PathNodes[0].v.x = new_node.v.x; - PathNodes[0].v.y = new_node.v.y; - PathNodes[0].v.z = new_node.v.z; - PathNodes[0].bestz = new_node.bestz; - PathNodes[0].id = new_node.id; - for(int n = 0; n < PATHNODENEIGHBOURS; ++n) - { - PathNodes[0].Neighbours[n].distance = new_node.Neighbours[n].distance; - PathNodes[0].Neighbours[n].DoorID = new_node.Neighbours[n].DoorID; - PathNodes[0].Neighbours[n].id = new_node.Neighbours[n].id; - PathNodes[0].Neighbours[n].Teleport = new_node.Neighbours[n].Teleport; - } - - auto npc_type = new NPCType; - memset(npc_type, 0, sizeof(NPCType)); - if(new_id < 10) - sprintf(npc_type->name, "%s", DigitToWord(new_id)); - else if(new_id < 100) - sprintf(npc_type->name, "%s_%s", DigitToWord(new_id/10), DigitToWord(new_id % 10)); - else - sprintf(npc_type->name, "%s_%s_%s", DigitToWord(new_id/100), DigitToWord((new_id % 100)/10), - DigitToWord(((new_id % 100) %10))); - - sprintf(npc_type->lastname, "%i", new_id); - npc_type->cur_hp = 4000000; - npc_type->max_hp = 4000000; - npc_type->race = 2253; - npc_type->size = 3.0f; - npc_type->gender = 2; - npc_type->class_ = 9; - npc_type->deity= 1; - npc_type->level = 75; - npc_type->npc_id = 0; - npc_type->loottable_id = 0; - npc_type->texture = 1; - npc_type->light = 0; - npc_type->runspeed = 0; - npc_type->d_melee_texture1 = 1; - npc_type->d_melee_texture2 = 1; - npc_type->merchanttype = 1; - npc_type->bodytype = 1; - npc_type->STR = 150; - npc_type->STA = 150; - npc_type->DEX = 150; - npc_type->AGI = 150; - npc_type->INT = 150; - npc_type->WIS = 150; - npc_type->CHA = 150; - npc_type->findable = 1; - - auto position = glm::vec4(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f); - auto npc = new NPC(npc_type, nullptr, position, FlyMode1); - npc->GiveNPCTypeData(npc_type); - entity_list.AddNPC(npc, true, true); - - ClosedListFlag = new int[Head.PathNodeCount]; - - return new_id; - } -} - -bool PathManager::DeleteNode(Client *c) -{ - if(!c) - { - return false; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return false; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return false; - } - - return DeleteNode(Node->id); -} - -bool PathManager::DeleteNode(int32 id) -{ - //if the current list is > 1 in size create a new list of size current size - 1 - //transfer all but the current node to this new list and delete our current list - //set this new list to be our current list - //else if the size is 1 just delete our current list and set it to zero. - //go through and delete all ref in neighbors... - - if(Head.PathNodeCount > 1) - { - auto t_PathNodes = new PathNode[Head.PathNodeCount - 1]; - uint32 index = 0; - for(uint32 x = 0; x < Head.PathNodeCount; x++) - { - if(PathNodes[x].id != id) - { - t_PathNodes[index].id = PathNodes[x].id; - t_PathNodes[index].v.x = PathNodes[x].v.x; - t_PathNodes[index].v.y = PathNodes[x].v.y; - t_PathNodes[index].v.z = PathNodes[x].v.z; - t_PathNodes[index].bestz = PathNodes[x].bestz; - for(int n = 0; n < PATHNODENEIGHBOURS; ++n) - { - t_PathNodes[index].Neighbours[n].distance = PathNodes[x].Neighbours[n].distance; - t_PathNodes[index].Neighbours[n].DoorID = PathNodes[x].Neighbours[n].DoorID; - t_PathNodes[index].Neighbours[n].id = PathNodes[x].Neighbours[n].id; - t_PathNodes[index].Neighbours[n].Teleport = PathNodes[x].Neighbours[n].Teleport; - } - index++; - } - } - Head.PathNodeCount--; - delete[] PathNodes; - PathNodes = t_PathNodes; - - for(uint32 y = 0; y < Head.PathNodeCount; ++y) - { - for(int n = 0; n < PATHNODENEIGHBOURS; ++n) - { - if(PathNodes[y].Neighbours[n].id == id) - { - PathNodes[y].Neighbours[n].Teleport = 0; - PathNodes[y].Neighbours[n].DoorID = -1; - PathNodes[y].Neighbours[n].distance = 0.0; - PathNodes[y].Neighbours[n].id = -1; - } - } - } - safe_delete_array(ClosedListFlag); - ClosedListFlag = new int[Head.PathNodeCount]; - } - else - { - delete[] PathNodes; - PathNodes = nullptr; - } - return true; -} - -void PathManager::ConnectNodeToNode(Client *c, int32 Node2, int32 teleport, int32 doorid) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - c->Message(0, "Connecting %i to %i", Node->id, Node2); - - if(doorid == 0) - ConnectNodeToNode(Node->id, Node2, teleport); - else - ConnectNodeToNode(Node->id, Node2, teleport, doorid); -} - -void PathManager::ConnectNodeToNode(int32 Node1, int32 Node2, int32 teleport, int32 doorid) -{ - PathNode *a = nullptr; - PathNode *b = nullptr; - for(uint32 x = 0; x < Head.PathNodeCount; ++x) - { - if(PathNodes[x].id == Node1) - { - a = &PathNodes[x]; - if(b) - break; - } - else if(PathNodes[x].id == Node2) - { - b = &PathNodes[x]; - if(a) - break; - } - } - - if(a == nullptr || b == nullptr) - return; - - bool connect_a_to_b = true; - if(NodesConnected(a, b)) - connect_a_to_b = false; - - bool connect_b_to_a = true; - if(NodesConnected(b, a)) - connect_b_to_a = false; - - - if(connect_a_to_b) - { - for(int a_i = 0; a_i < PATHNODENEIGHBOURS; ++a_i) - { - if(a->Neighbours[a_i].id == -1) - { - a->Neighbours[a_i].id = b->id; - a->Neighbours[a_i].DoorID = doorid; - a->Neighbours[a_i].Teleport = teleport; - a->Neighbours[a_i].distance = VectorDistance(a->v, b->v); - break; - } - } - } - - if(connect_b_to_a) - { - for(int b_i = 0; b_i < PATHNODENEIGHBOURS; ++b_i) - { - if(b->Neighbours[b_i].id == -1) - { - b->Neighbours[b_i].id = a->id; - b->Neighbours[b_i].DoorID = doorid; - b->Neighbours[b_i].Teleport = teleport; - b->Neighbours[b_i].distance = VectorDistance(a->v, b->v); - break; - } - } - } -} - -void PathManager::ConnectNode(Client *c, int32 Node2, int32 teleport, int32 doorid) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - c->Message(0, "Connecting %i to %i", Node->id, Node2); - - if(doorid == 0) - ConnectNode(Node->id, Node2, teleport); - else - ConnectNode(Node->id, Node2, teleport, doorid); -} - -void PathManager::ConnectNode(int32 Node1, int32 Node2, int32 teleport, int32 doorid) -{ - PathNode *a = nullptr; - PathNode *b = nullptr; - for(uint32 x = 0; x < Head.PathNodeCount; ++x) - { - if(PathNodes[x].id == Node1) - { - a = &PathNodes[x]; - if(b) - break; - } - else if(PathNodes[x].id == Node2) - { - b = &PathNodes[x]; - if(a) - break; - } - } - - if(a == nullptr || b == nullptr) - return; - - bool connect_a_to_b = true; - if(NodesConnected(a, b)) - connect_a_to_b = false; - - if(connect_a_to_b) - { - for(int a_i = 0; a_i < PATHNODENEIGHBOURS; ++a_i) - { - if(a->Neighbours[a_i].id == -1) - { - a->Neighbours[a_i].id = b->id; - a->Neighbours[a_i].DoorID = doorid; - a->Neighbours[a_i].Teleport = teleport; - a->Neighbours[a_i].distance = VectorDistance(a->v, b->v); - break; - } - } - } -} - -void PathManager::DisconnectNodeToNode(Client *c, int32 Node2) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - DisconnectNodeToNode(Node->id, Node2); -} - -void PathManager::DisconnectNodeToNode(int32 Node1, int32 Node2) -{ - PathNode *a = nullptr; - PathNode *b = nullptr; - for(uint32 x = 0; x < Head.PathNodeCount; ++x) - { - if(PathNodes[x].id == Node1) - { - a = &PathNodes[x]; - if(b) - break; - } - else if(PathNodes[x].id == Node2) - { - b = &PathNodes[x]; - if(a) - break; - } - } - - if(a == nullptr || b == nullptr) - return; - - bool disconnect_a_from_b = false; - if(NodesConnected(a, b)) - disconnect_a_from_b = true; - - bool disconnect_b_from_a = false; - if(NodesConnected(b, a)) - disconnect_b_from_a = true; - - if(disconnect_a_from_b) - { - for(int a_i = 0; a_i < PATHNODENEIGHBOURS; ++a_i) - { - if(a->Neighbours[a_i].id == b->id) - { - a->Neighbours[a_i].distance = 0.0; - a->Neighbours[a_i].DoorID = -1; - a->Neighbours[a_i].id = -1; - a->Neighbours[a_i].Teleport = 0; - break; - } - } - } - - if(disconnect_b_from_a) - { - for(int b_i = 0; b_i < PATHNODENEIGHBOURS; ++b_i) - { - if(b->Neighbours[b_i].id == a->id) - { - b->Neighbours[b_i].distance = 0.0; - b->Neighbours[b_i].DoorID = -1; - b->Neighbours[b_i].id = -1; - b->Neighbours[b_i].Teleport = 0; - break; - } - } - } -} - -void PathManager::MoveNode(Client *c) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - Node->v.x = c->GetX(); - Node->v.y = c->GetY(); - Node->v.z = c->GetZ(); - - if(zone->zonemap) - { - glm::vec3 loc(c->GetX(), c->GetY(), c->GetZ()); - Node->bestz = zone->zonemap->FindBestZ(loc, nullptr); - } - else - { - Node->bestz = Node->v.z; - } -} - -void PathManager::DisconnectAll(Client *c) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - for(int x = 0; x < PATHNODENEIGHBOURS; ++x) - { - Node->Neighbours[x].distance = 0; - Node->Neighbours[x].Teleport = 0; - Node->Neighbours[x].DoorID = -1; - Node->Neighbours[x].id = -1; - } - - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - if(PathNodes[i].id == Node->id) - continue; - - for(int ix = 0; ix < PATHNODENEIGHBOURS; ++ix) - { - if(PathNodes[i].Neighbours[ix].id == Node->id) - { - PathNodes[i].Neighbours[ix].distance = 0; - PathNodes[i].Neighbours[ix].Teleport = 0; - PathNodes[i].Neighbours[ix].id = -1; - PathNodes[i].Neighbours[ix].DoorID = -1; - } - } - } -} - -//checks if anything in a points to b -bool PathManager::NodesConnected(PathNode *a, PathNode *b) -{ - if(!a) - return false; - - if(!b) - return false; - - for(int x = 0; x < PATHNODENEIGHBOURS; ++x) - { - if(a->Neighbours[x].id == b->id) - return true; - } - return false; -} - -bool PathManager::CheckLosFN(glm::vec3 a, glm::vec3 b) -{ - if(zone->zonemap) - { - glm::vec3 hit; - - glm::vec3 myloc; - glm::vec3 oloc; - - myloc.x = a.x; - myloc.y = a.y; - myloc.z = a.z; - - oloc.x = b.x; - oloc.y = b.y; - oloc.z = b.z; - - - if(zone->zonemap->LineIntersectsZone(myloc, oloc, 1.0f, nullptr)) - { - return false; - } - } - return true; -} - -void PathManager::ProcessNodesAndSave(std::string filename) -{ - if(zone->zonemap) - { - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - for(int in = 0; in < PATHNODENEIGHBOURS; ++in) - { - PathNodes[i].Neighbours[in].distance = 0.0; - PathNodes[i].Neighbours[in].DoorID = -1; - PathNodes[i].Neighbours[in].id = -1; - PathNodes[i].Neighbours[in].Teleport = 0; - } - } - - for(uint32 x = 0; x < Head.PathNodeCount; ++x) - { - for(uint32 y = 0; y < Head.PathNodeCount; ++y) - { - if(y == x) //can't connect to ourselves. - continue; - - if(!NodesConnected(&PathNodes[x], &PathNodes[y])) - { - if(VectorDistance(PathNodes[x].v, PathNodes[y].v) <= 200) - { - if(CheckLosFN(PathNodes[x].v, PathNodes[y].v)) - { - if(NoHazardsAccurate(PathNodes[x].v, PathNodes[y].v)) - { - ConnectNodeToNode(PathNodes[x].id, PathNodes[y].id, 0, 0); - } - } - } - } - } - } - } - DumpPath(filename); -} - -void PathManager::ResortConnections() -{ - NeighbourNode Neigh[PATHNODENEIGHBOURS]; - for(uint32 x = 0; x < Head.PathNodeCount; ++x) - { - int index = 0; - for(int y = 0; y < PATHNODENEIGHBOURS; ++y) - { - Neigh[y].distance = 0; - Neigh[y].DoorID = -1; - Neigh[y].id = -1; - Neigh[y].Teleport = 0; - } - - for(int z = 0; z < PATHNODENEIGHBOURS; ++z) - { - if(PathNodes[x].Neighbours[z].id != -1) - { - Neigh[index].id = PathNodes[x].Neighbours[z].id; - Neigh[index].distance = PathNodes[x].Neighbours[z].distance; - Neigh[index].DoorID = PathNodes[x].Neighbours[z].DoorID; - Neigh[index].Teleport = PathNodes[x].Neighbours[z].Teleport; - index++; - } - } - - for(int i = 0; i < PATHNODENEIGHBOURS; ++i) - { - PathNodes[x].Neighbours[i].distance = 0; - PathNodes[x].Neighbours[i].DoorID = -1; - PathNodes[x].Neighbours[i].id = -1; - PathNodes[x].Neighbours[i].Teleport = 0; - } - - for(int z = 0; z < PATHNODENEIGHBOURS; ++z) - { - PathNodes[x].Neighbours[z].distance = Neigh[z].distance; - PathNodes[x].Neighbours[z].DoorID = Neigh[z].DoorID; - PathNodes[x].Neighbours[z].id = Neigh[z].id; - PathNodes[x].Neighbours[z].Teleport = Neigh[z].Teleport; - } - } -} - -void PathManager::QuickConnect(Client *c, bool set) -{ - if(!c) - { - return; - } - - if(!c->GetTarget()) - { - c->Message(0, "You must target a node."); - return; - } - - PathNode *Node = zone->pathing->FindPathNodeByCoordinates(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ()); - if(!Node) - { - return; - } - - if(set) - { - c->Message(0, "Setting %i to the quick connect target", Node->id); - QuickConnectTarget = Node->id; - } - else - { - if(QuickConnectTarget >= 0) - { - ConnectNodeToNode(QuickConnectTarget, Node->id); - } - } -} - -struct InternalPathSort -{ - int16 old_id; - int16 new_id; -}; - -void PathManager::SortNodes() -{ - std::vector sorted_vals; - for(uint32 x = 0; x < Head.PathNodeCount; ++x) - { - InternalPathSort tmp; - tmp.old_id = PathNodes[x].id; - sorted_vals.push_back(tmp); - } - - auto t_PathNodes = new PathNode[Head.PathNodeCount]; - memcpy(t_PathNodes, PathNodes, sizeof(PathNode)*Head.PathNodeCount); - for(uint32 i = 0; i < Head.PathNodeCount; ++i) - { - for(size_t j = 0; j < sorted_vals.size(); ++j) - { - if(sorted_vals[j].old_id == PathNodes[i].id) - { - if(i != PathNodes[i].id) - { - printf("Assigning new id of index %i differs from old id %i\n", i, PathNodes[i].id); - } - sorted_vals[j].new_id = i; - } - } - t_PathNodes[i].id = i; - } - - for(uint32 y = 0; y < Head.PathNodeCount; ++y) - { - for(int z = 0; z < PATHNODENEIGHBOURS; ++z) - { - if(PathNodes[y].Neighbours[z].id != -1) - { - int new_val = -1; - for(size_t c = 0; c < sorted_vals.size(); ++c) - { - if(PathNodes[y].Neighbours[z].id == sorted_vals[c].old_id) - { - new_val = sorted_vals[c].new_id; - break; - } - } - if(new_val != -1) - { - if(t_PathNodes[y].Neighbours[z].id != new_val) - { - printf("changing neighbor value to %i from %i\n", new_val, t_PathNodes[y].Neighbours[z].id); - } - t_PathNodes[y].Neighbours[z].id = new_val; - } - } - } - } - safe_delete_array(PathNodes); - PathNodes = t_PathNodes; -} - diff --git a/zone/pathing.h b/zone/pathing.h deleted file mode 100644 index d65ebfdcf..000000000 --- a/zone/pathing.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef PATHING_H -#define PATHING_H - -#include "map.h" -#include "zone_config.h" -#include - -extern const ZoneConfig *Config; - -class Client; -class Mob; - -#define PATHNODENEIGHBOURS 50 - -#pragma pack(1) - -struct AStarNode -{ - int PathNodeID; - int Parent; - float HCost; - float GCost; - bool Teleport; -}; - -struct NeighbourNode { - int16 id; - float distance; - uint8 Teleport; - int16 DoorID; -}; - -struct PathNode { - uint16 id; - glm::vec3 v; - float bestz; - NeighbourNode Neighbours[PATHNODENEIGHBOURS]; -}; - -struct PathFileHeader { - uint32 version; - uint32 PathNodeCount; -}; - -#pragma pack() - -struct PathNodeSortStruct -{ - int id; - float Distance; -}; - -enum LOSType{ UnknownLOS, HaveLOS, NoLOS }; - -class PathManager { - -public: - PathManager(); - ~PathManager(); - - - static PathManager *LoadPathFile(const char *ZoneName); - bool loadPaths(FILE *fp); - void PrintPathing(); - std::deque FindRoute(glm::vec3 Start, glm::vec3 End); - std::deque FindRoute(int startID, int endID); - - glm::vec3 GetPathNodeCoordinates(int NodeNumber, bool BestZ = true); - bool CheckLosFN(glm::vec3 a, glm::vec3 b); - void SpawnPathNodes(); - void MeshTest(); - void SimpleMeshTest(); - int FindNearestPathNode(glm::vec3 Position); - bool NoHazards(glm::vec3 From, glm::vec3 To); - bool NoHazardsAccurate(glm::vec3 From, glm::vec3 To); - void OpenDoors(int Node1, int Node2, Mob* ForWho); - - PathNode* FindPathNodeByCoordinates(float x, float y, float z); - void ShowPathNodeNeighbours(Client *c); - int GetRandomPathNode(); - - void NodeInfo(Client *c); - int32 AddNode(float x, float y, float z, float best_z, int32 requested_id = 0); //return -1 on failure, else returns the id of this node - bool DeleteNode(Client *c); - bool DeleteNode(int32 id); //returns true on success, false on failure, tries to delete a node from this map - void ConnectNodeToNode(Client *c, int32 Node2, int32 teleport = 0, int32 doorid = -1); //connects a node both ways - void ConnectNodeToNode(int32 Node1, int32 Node2, int32 teleport = 0, int32 doorid = -1); - void ConnectNode(Client *c, int32 Node2, int32 teleport = 0, int32 doorid = -1); //connects a node one way - void ConnectNode(int32 Node1, int32 Node2, int32 teleport = 0, int32 doorid = -1); - void DisconnectNodeToNode(Client *c, int32 Node2); - void DisconnectNodeToNode(int32 Node1, int32 Node2); - void MoveNode(Client *c); - void DisconnectAll(Client *c); - bool NodesConnected(PathNode *a, PathNode *b); - void DumpPath(std::string filename); - void ProcessNodesAndSave(std::string filename); - void ResortConnections(); - void QuickConnect(Client *c, bool set = false); - void SortNodes(); - -private: - PathFileHeader Head; - PathNode *PathNodes; - int QuickConnectTarget; - - int *ClosedListFlag; -}; - - -#endif - diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 622551ce0..47d5dd89a 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -37,26 +39,24 @@ #include "client.h" #include "titles.h" -#ifdef THIS /* this macro seems to leak out on some systems */ +#ifdef THIS /* this macro seems to leak out on some systems */ #undef THIS #endif XS(XS_Client_SendSound); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendSound) -{ +XS(XS_Client_SendSound) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::SendSound(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendSound(); @@ -65,48 +65,44 @@ XS(XS_Client_SendSound) } XS(XS_Client_Save); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Save) -{ +XS(XS_Client_Save) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::Save(THIS, iCommitNow)"); + Perl_croak(aTHX_ "Usage: Client::Save(THIS, uint8 commit_now)"); { - Client * THIS; - bool RETVAL; - uint8 iCommitNow = (uint8)SvUV(ST(1)); + Client *THIS; + bool RETVAL; + uint8 iCommitNow = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Save(iCommitNow); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_SaveBackup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SaveBackup) -{ +XS(XS_Client_SaveBackup) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::SaveBackup(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SaveBackup(); @@ -115,22 +111,20 @@ XS(XS_Client_SaveBackup) } XS(XS_Client_Connected); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Connected) -{ +XS(XS_Client_Connected) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Connected(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Connected(); @@ -141,22 +135,20 @@ XS(XS_Client_Connected) } XS(XS_Client_InZone); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_InZone) -{ +XS(XS_Client_InZone) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::InZone(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->InZone(); @@ -167,21 +159,19 @@ XS(XS_Client_InZone) } XS(XS_Client_Kick); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Kick) -{ +XS(XS_Client_Kick) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Kick(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Kick(); @@ -190,21 +180,19 @@ XS(XS_Client_Kick) } XS(XS_Client_Disconnect); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Disconnect) -{ +XS(XS_Client_Disconnect) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Disconnect(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Disconnect(); @@ -213,22 +201,20 @@ XS(XS_Client_Disconnect) } XS(XS_Client_IsLD); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsLD) -{ +XS(XS_Client_IsLD) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsLD(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsLD(); @@ -239,21 +225,19 @@ XS(XS_Client_IsLD) } XS(XS_Client_WorldKick); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_WorldKick) -{ +XS(XS_Client_WorldKick) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::WorldKick(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->WorldKick(); @@ -262,47 +246,44 @@ XS(XS_Client_WorldKick) } XS(XS_Client_GetAnon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAnon) -{ +XS(XS_Client_GetAnon) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetAnon(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAnon(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_Duck); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Duck) -{ +XS(XS_Client_Duck) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Duck(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Duck(); @@ -311,21 +292,19 @@ XS(XS_Client_Duck) } XS(XS_Client_Stand); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Stand) -{ +XS(XS_Client_Stand) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Stand(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Stand(); @@ -334,22 +313,20 @@ XS(XS_Client_Stand) } XS(XS_Client_SetGM); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetGM) -{ +XS(XS_Client_SetGM) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetGM(THIS, toggle)"); + Perl_croak(aTHX_ "Usage: Client::SetGM(THIS, bool toggle)"); { - Client * THIS; - bool toggle = (bool)SvTRUE(ST(1)); + Client *THIS; + bool toggle = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetGM(toggle); @@ -358,22 +335,20 @@ XS(XS_Client_SetGM) } XS(XS_Client_SetPVP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetPVP) -{ +XS(XS_Client_SetPVP) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetPVP(THIS, toggle)"); + Perl_croak(aTHX_ "Usage: Client::SetPVP(THIS, bool toggle)"); { - Client * THIS; - bool toggle = (bool)SvTRUE(ST(1)); + Client *THIS; + bool toggle = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetPVP(toggle); @@ -382,22 +357,20 @@ XS(XS_Client_SetPVP) } XS(XS_Client_GetPVP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetPVP) -{ +XS(XS_Client_GetPVP) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetPVP(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPVP(); @@ -408,22 +381,20 @@ XS(XS_Client_GetPVP) } XS(XS_Client_GetGM); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetGM) -{ +XS(XS_Client_GetGM) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetGM(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGM(); @@ -434,22 +405,20 @@ XS(XS_Client_GetGM) } XS(XS_Client_SetBaseClass); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetBaseClass) -{ +XS(XS_Client_SetBaseClass) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetBaseClass(THIS, i)"); + Perl_croak(aTHX_ "Usage: Client::SetBaseClass(THIS, uint32 class_id)"); { - Client * THIS; - uint32 i = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 i = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetBaseClass(i); @@ -458,22 +427,20 @@ XS(XS_Client_SetBaseClass) } XS(XS_Client_SetBaseRace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetBaseRace) -{ +XS(XS_Client_SetBaseRace) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetBaseRace(THIS, i)"); + Perl_croak(aTHX_ "Usage: Client::SetBaseRace(THIS, uint32 race_id)"); { - Client * THIS; - uint32 i = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 i = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetBaseRace(i); @@ -482,22 +449,20 @@ XS(XS_Client_SetBaseRace) } XS(XS_Client_SetBaseGender); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetBaseGender) -{ +XS(XS_Client_SetBaseGender) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetBaseGender(THIS, i)"); + Perl_croak(aTHX_ "Usage: Client::SetBaseGender(THIS, uint32 gender_id)"); { - Client * THIS; - uint32 i = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 i = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetBaseGender(i); @@ -506,468 +471,449 @@ XS(XS_Client_SetBaseGender) } XS(XS_Client_GetBaseFace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseFace) -{ +XS(XS_Client_GetBaseFace) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseFace(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseFace(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetLanguageSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLanguageSkill) -{ +XS(XS_Client_GetLanguageSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetLanguageSkill(THIS, n)"); + Perl_croak(aTHX_ "Usage: Client::GetLanguageSkill(THIS, uint16 lanuage_id)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; - uint16 n = (uint16)SvUV(ST(1)); + uint16 n = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLanguageSkill(n); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetLastName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLastName) -{ +XS(XS_Client_GetLastName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetLastName(THIS)"); { - Client * THIS; - Const_char * RETVAL; + Client *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLastName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Client_GetLDoNPointsTheme); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLDoNPointsTheme) -{ +XS(XS_Client_GetLDoNPointsTheme) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetLDoNPointsTheme(THIS, theme)"); + Perl_croak(aTHX_ "Usage: Client::GetLDoNPointsTheme(THIS, int32 theme)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; - int32 theme_out = (int32)SvIV(ST(1)); + int32 theme_out = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLDoNPointsTheme(theme_out); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseSTR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseSTR) -{ +XS(XS_Client_GetBaseSTR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseSTR(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseSTR(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseSTA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseSTA) -{ +XS(XS_Client_GetBaseSTA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseSTA(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseSTA(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseCHA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseCHA) -{ +XS(XS_Client_GetBaseCHA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseCHA(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseCHA(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseDEX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseDEX) -{ +XS(XS_Client_GetBaseDEX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseDEX(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseDEX(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseINT); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseINT) -{ +XS(XS_Client_GetBaseINT) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseINT(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseINT(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseAGI); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseAGI) -{ +XS(XS_Client_GetBaseAGI) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseAGI(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseAGI(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBaseWIS); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBaseWIS) -{ +XS(XS_Client_GetBaseWIS) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBaseWIS(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseWIS(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetWeight); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetWeight) -{ +XS(XS_Client_GetWeight) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetWeight(THIS)"); { - Client * THIS; - uint16 RETVAL; + Client *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetWeight(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetEXP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetEXP) -{ +XS(XS_Client_GetEXP) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetEXP(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEXP(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetAAExp); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAAExp) -{ +XS(XS_Client_GetAAExp) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetAAExp(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAAXP(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetAAPercent); -XS(XS_Client_GetAAPercent) -{ +XS(XS_Client_GetAAPercent) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetAAPercent(THIS)"); { - Client* THIS; + Client *THIS; uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAAPercent(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetTotalSecondsPlayed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetTotalSecondsPlayed) -{ +XS(XS_Client_GetTotalSecondsPlayed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetTotalSecondsPlayed(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTotalSecondsPlayed(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_UpdateLDoNPoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UpdateLDoNPoints) -{ +XS(XS_Client_UpdateLDoNPoints) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::UpdateLDoNPoints(THIS, points, theme)"); + Perl_croak(aTHX_ "Usage: Client::UpdateLDoNPoints(THIS, int32 points, uint32 theme)"); { - Client * THIS; - bool RETVAL; - int32 points = (int32)SvIV(ST(1)); - uint32 theme = (uint32)SvUV(ST(2)); + Client *THIS; + bool RETVAL; + int32 points = (int32) SvIV(ST(1)); + uint32 theme = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->UpdateLDoNPoints(points, theme); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_SetDeity); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetDeity) -{ +XS(XS_Client_SetDeity) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetDeity(THIS, i)"); + Perl_croak(aTHX_ "Usage: Client::SetDeity(THIS, uint32 deity_id)"); { - Client * THIS; - uint32 i = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 i = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetDeity(i); @@ -976,36 +922,34 @@ XS(XS_Client_SetDeity) } XS(XS_Client_AddEXP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AddEXP) -{ +XS(XS_Client_AddEXP) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: Client::AddEXP(THIS, add_exp, conlevel= 0xFF, resexp= false)"); + Perl_croak(aTHX_ "Usage: Client::AddEXP(THIS, uint32 experience_points)"); { - Client * THIS; - uint32 add_exp = (uint32)SvUV(ST(1)); - uint8 conlevel; - bool resexp; + Client *THIS; + uint32 add_exp = (uint32) SvUV(ST(1)); + uint8 conlevel; + bool resexp; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) conlevel = 0xFF; else { - conlevel = (uint8)SvUV(ST(2)); + conlevel = (uint8) SvUV(ST(2)); } if (items < 4) resexp = false; else { - resexp = (bool)SvTRUE(ST(3)); + resexp = (bool) SvTRUE(ST(3)); } THIS->AddEXP(add_exp, conlevel, resexp); @@ -1014,30 +958,29 @@ XS(XS_Client_AddEXP) } XS(XS_Client_SetEXP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetEXP) -{ +XS(XS_Client_SetEXP) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Client::SetEXP(THIS, set_exp, set_aaxp, resexp=false)"); + Perl_croak(aTHX_ + "Usage: Client::SetEXP(THIS, uint32 experience_points, uint32 aa_experience_points, [bool resexp=false])"); { - Client * THIS; - uint32 set_exp = (uint32)SvUV(ST(1)); - uint32 set_aaxp = (uint32)SvUV(ST(2)); - bool resexp; + Client *THIS; + uint32 set_exp = (uint32) SvUV(ST(1)); + uint32 set_aaxp = (uint32) SvUV(ST(2)); + bool resexp; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) resexp = false; else { - resexp = (bool)SvTRUE(ST(3)); + resexp = (bool) SvTRUE(ST(3)); } THIS->SetEXP(set_exp, set_aaxp, resexp); @@ -1046,56 +989,55 @@ XS(XS_Client_SetEXP) } XS(XS_Client_SetBindPoint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetBindPoint) -{ +XS(XS_Client_SetBindPoint) { dXSARGS; if (items < 1 || items > 6) - Perl_croak(aTHX_ "Usage: Client::SetBindPoint(THIS, to_zone= -1, to_instance = 0, new_x= 0.0f, new_y= 0.0f, new_z= 0.0f)"); + Perl_croak(aTHX_ + "Usage: Client::SetBindPoint(THIS, int to_zone = -1, int to_instance = 0, float new_x = 0.0f, float new_y = 0.0f, float new_z = 0.0f)"); { - Client * THIS; - int to_zone; - int to_instance; - float new_x; - float new_y; - float new_z; + Client *THIS; + int to_zone; + int to_instance; + float new_x; + float new_y; + float new_z; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) to_zone = -1; else { - to_zone = (int)SvIV(ST(1)); + to_zone = (int) SvIV(ST(1)); } - if(items < 3) + if (items < 3) to_instance = 0; else { - to_instance = (int)SvIV(ST(2)); + to_instance = (int) SvIV(ST(2)); } if (items < 4) new_x = 0.0f; else { - new_x = (float)SvNV(ST(3)); + new_x = (float) SvNV(ST(3)); } if (items < 5) new_y = 0.0f; else { - new_y = (float)SvNV(ST(4)); + new_y = (float) SvNV(ST(4)); } if (items < 6) new_z = 0.0f; else { - new_z = (float)SvNV(ST(5)); + new_z = (float) SvNV(ST(5)); } THIS->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, new_z)); @@ -1104,211 +1046,205 @@ XS(XS_Client_SetBindPoint) } XS(XS_Client_GetBindX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBindX) -{ +XS(XS_Client_GetBindX) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::GetBindX(index)"); + Perl_croak(aTHX_ "Usage: Client::GetBindX(int index = 0)"); { - Client * THIS; - int index = 0; + Client *THIS; + int index = 0; float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 1) index = 0; else if (items == 2) { - index = (uint32)SvUV(ST(1)); + index = (uint32) SvUV(ST(1)); } RETVAL = THIS->GetBindX(index); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBindY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBindY) -{ +XS(XS_Client_GetBindY) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::GetBindY(index)"); + Perl_croak(aTHX_ "Usage: Client::GetBindY(int index = 0)"); { - Client * THIS; - int index = 0; + Client *THIS; + int index = 0; float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 1) index = 0; else if (items == 2) { - index = (uint32)SvUV(ST(1));; + index = (uint32) SvUV(ST(1));; } RETVAL = THIS->GetBindY(index); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBindZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBindZ) -{ +XS(XS_Client_GetBindZ) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::GetBindZ(index)"); + Perl_croak(aTHX_ "Usage: Client::GetBindZ(int index = 0)"); { - Client * THIS; - int index = 0; + Client *THIS; + int index = 0; float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 1) index = 0; else if (items == 2) { - index = (uint32)SvUV(ST(1)); + index = (uint32) SvUV(ST(1)); } RETVAL = THIS->GetBindZ(index); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBindHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBindHeading) -{ +XS(XS_Client_GetBindHeading) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::GetBindHeading(index)"); + Perl_croak(aTHX_ "Usage: Client::GetBindHeading(int index = 0)"); { - Client * THIS; - int index = 0; + Client *THIS; + int index = 0; float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 1) index = 0; else if (items == 2) { - index = (uint32)SvUV(ST(1)); + index = (uint32) SvUV(ST(1)); } RETVAL = THIS->GetBindHeading(index); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Client_GetBindZoneID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBindZoneID) -{ +XS(XS_Client_GetBindZoneID) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::GetBindZoneID(index)"); + Perl_croak(aTHX_ "Usage: Client::GetBindZoneID(int index = 0)"); { - Client * THIS; + Client *THIS; uint32 index = 0; uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 1) index = 0; else if (items == 2) { - index = (uint32)SvUV(ST(1)); + index = (uint32) SvUV(ST(1)); } RETVAL = THIS->GetBindZoneID(index); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_MovePC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_MovePC) -{ +XS(XS_Client_MovePC) { dXSARGS; if (items != 6) - Perl_croak(aTHX_ "Usage: Client::MovePC(THIS, zoneID, x, y, z, heading)"); + Perl_croak(aTHX_ "Usage: Client::MovePC(THIS, uint32 zone_id, float x, float y, float z, float heading)"); { - Client * THIS; - uint32 zoneID = (uint32)SvUV(ST(1)); - float x = (float)SvNV(ST(2)); - float y = (float)SvNV(ST(3)); - float z = (float)SvNV(ST(4)); - float heading = (float)SvNV(ST(5)); + Client *THIS; + uint32 zoneID = (uint32) SvUV(ST(1)); + float x = (float) SvNV(ST(2)); + float y = (float) SvNV(ST(3)); + float z = (float) SvNV(ST(4)); + float heading = (float) SvNV(ST(5)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (THIS->IsClient()) { THIS->MovePC(zoneID, x, y, z, heading); - } - else { + } else { if (THIS->IsMerc()) { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference"); + Log(Logs::Detail, Logs::None, + "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference"); + } else if (THIS->IsNPC()) { + Log(Logs::Detail, Logs::None, + "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference"); } - else if (THIS->IsNPC()) { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference"); - } - #ifdef BOTS - else if (THIS->IsBot()) { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference"); - } - #endif +#ifdef BOTS + else if (THIS->IsBot()) { + Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference"); + } +#endif else { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference"); + Log(Logs::Detail, Logs::None, + "[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference"); } Perl_croak(aTHX_ "THIS is not of type Client"); @@ -1319,46 +1255,46 @@ XS(XS_Client_MovePC) } XS(XS_Client_MovePCInstance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_MovePCInstance) -{ +XS(XS_Client_MovePCInstance) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Client::MovePCInstance(THIS, zoneID, instanceID, x, y, z, heading)"); + Perl_croak(aTHX_ + "Usage: Client::MovePCInstance(THIS, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading)"); { - Client * THIS; - uint32 zoneID = (uint32)SvUV(ST(1)); - uint32 instanceID = (uint32)SvUV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); - float heading = (float)SvNV(ST(6)); + Client *THIS; + uint32 zoneID = (uint32) SvUV(ST(1)); + uint32 instanceID = (uint32) SvUV(ST(2)); + float x = (float) SvNV(ST(3)); + float y = (float) SvNV(ST(4)); + float z = (float) SvNV(ST(5)); + float heading = (float) SvNV(ST(6)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (THIS->IsClient()) { THIS->MovePC(zoneID, instanceID, x, y, z, heading); - } - else { + } else { if (THIS->IsMerc()) { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference"); + Log(Logs::Detail, Logs::None, + "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference"); + } else if (THIS->IsNPC()) { + Log(Logs::Detail, Logs::None, + "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference"); } - else if (THIS->IsNPC()) { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference"); - } - #ifdef BOTS - else if (THIS->IsBot()) { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference"); - } - #endif +#ifdef BOTS + else if (THIS->IsBot()) { + Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference"); + } +#endif else { - Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference"); + Log(Logs::Detail, Logs::None, + "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference"); } Perl_croak(aTHX_ "THIS is not of type Client"); @@ -1370,22 +1306,20 @@ XS(XS_Client_MovePCInstance) } XS(XS_Client_ChangeLastName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ChangeLastName) -{ +XS(XS_Client_ChangeLastName) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::ChangeLastName(THIS, in_lastname)"); + Perl_croak(aTHX_ "Usage: Client::ChangeLastName(THIS, string last_name)"); { - Client * THIS; - char* in_lastname = (char *)SvPV_nolen(ST(1)); + Client *THIS; + char *in_lastname = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ChangeLastName(in_lastname); @@ -1394,68 +1328,66 @@ XS(XS_Client_ChangeLastName) } XS(XS_Client_GetFactionLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetFactionLevel) -{ +XS(XS_Client_GetFactionLevel) { dXSARGS; if (items != 8) - Perl_croak(aTHX_ "Usage: Client::GetFactionLevel(THIS, char_id, npc_id, p_race, p_class, p_deity, pFaction, tnpc)"); + Perl_croak(aTHX_ + "Usage: Client::GetFactionLevel(THIS, uint32 character_id, uint32 npc_id, uint32 player_race_id, uint32 player_class_id, uint32 player_deity_id, uint32 player_faction_id, Mob*)"); { - Client * THIS; - FACTION_VALUE RETVAL; + Client *THIS; + FACTION_VALUE RETVAL; dXSTARG; - uint32 char_id = (uint32)SvUV(ST(1)); - uint32 npc_id = (uint32)SvUV(ST(2)); - uint32 p_race = (uint32)SvUV(ST(3)); - uint32 p_class = (uint32)SvUV(ST(4)); - uint32 p_deity = (uint32)SvUV(ST(5)); - int32 pFaction = (int32)SvIV(ST(6)); - Mob* tnpc; + uint32 char_id = (uint32) SvUV(ST(1)); + uint32 npc_id = (uint32) SvUV(ST(2)); + uint32 p_race = (uint32) SvUV(ST(3)); + uint32 p_class = (uint32) SvUV(ST(4)); + uint32 p_deity = (uint32) SvUV(ST(5)); + int32 pFaction = (int32) SvIV(ST(6)); + Mob *tnpc; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(7), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(7))); - tnpc = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(7))); + tnpc = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "tnpc is not of type Mob"); - if(tnpc == nullptr) + if (tnpc == nullptr) Perl_croak(aTHX_ "tnpc is nullptr, avoiding crash."); RETVAL = THIS->GetFactionLevel(char_id, npc_id, p_race, p_class, p_deity, pFaction, tnpc); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetFactionLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetFactionLevel) -{ +XS(XS_Client_SetFactionLevel) { dXSARGS; if (items != 6) - Perl_croak(aTHX_ "Usage: Client::SetFactionLevel(THIS, char_id, npc_id, char_class, char_race, char_deity)"); + Perl_croak(aTHX_ + "Usage: Client::SetFactionLevel(THIS, uint32 character_id, uint32 npc_id, uint8 character_class, uint8 character_race, uint8 character_deity)"); { - Client * THIS; - uint32 char_id = (uint32)SvUV(ST(1)); - uint32 npc_id = (uint32)SvUV(ST(2)); - uint8 char_class = (uint8)SvUV(ST(3)); - uint8 char_race = (uint8)SvUV(ST(4)); - uint8 char_deity = (uint8)SvUV(ST(5)); + Client *THIS; + uint32 char_id = (uint32) SvUV(ST(1)); + uint32 npc_id = (uint32) SvUV(ST(2)); + uint8 char_class = (uint8) SvUV(ST(3)); + uint8 char_race = (uint8) SvUV(ST(4)); + uint8 char_deity = (uint8) SvUV(ST(5)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetFactionLevel(char_id, npc_id, char_class, char_race, char_deity); @@ -1464,34 +1396,33 @@ XS(XS_Client_SetFactionLevel) } XS(XS_Client_SetFactionLevel2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetFactionLevel2) -{ +XS(XS_Client_SetFactionLevel2) { dXSARGS; if (items < 7 || items > 8) - Perl_croak(aTHX_ "Usage: Client::SetFactionLevel2(THIS, char_id, faction_id, char_class, char_race, char_deity, value, temp)"); + Perl_croak(aTHX_ + "Usage: Client::SetFactionLevel2(THIS, uint32 character_id, int32 faction_id, uint8 character_class, uint8 character_race, uint8 character_deity, int32 value, uint8 temp)"); { - Client * THIS; - uint32 char_id = (uint32)SvUV(ST(1)); - int32 faction_id = (int32)SvIV(ST(2)); - uint8 char_class = (uint8)SvUV(ST(3)); - uint8 char_race = (uint8)SvUV(ST(4)); - uint8 char_deity = (uint8)SvUV(ST(5)); - int32 value = (int32)SvIV(ST(6)); - uint8 temp; + Client *THIS; + uint32 char_id = (uint32) SvUV(ST(1)); + int32 faction_id = (int32) SvIV(ST(2)); + uint8 char_class = (uint8) SvUV(ST(3)); + uint8 char_race = (uint8) SvUV(ST(4)); + uint8 char_deity = (uint8) SvUV(ST(5)); + int32 value = (int32) SvIV(ST(6)); + uint8 temp; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 7) temp = 0; else { - temp = (uint8)SvUV(ST(7)); + temp = (uint8) SvUV(ST(7)); } THIS->SetFactionLevel2(char_id, faction_id, char_class, char_race, char_deity, value, temp); @@ -1500,158 +1431,152 @@ XS(XS_Client_SetFactionLevel2) } XS(XS_Client_GetRawItemAC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetRawItemAC) -{ +XS(XS_Client_GetRawItemAC) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetRawItemAC(THIS)"); { - Client * THIS; - int16 RETVAL; + Client *THIS; + int16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRawItemAC(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_AccountID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AccountID) -{ +XS(XS_Client_AccountID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::AccountID(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->AccountID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_AccountName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AccountName) -{ +XS(XS_Client_AccountName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::AccountName(THIS)"); { - Client * THIS; - Const_char * RETVAL; + Client *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->AccountName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Client_Admin); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Admin) -{ +XS(XS_Client_Admin) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Admin(THIS)"); { - Client * THIS; - int16 RETVAL; + Client *THIS; + int16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Admin(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_CharacterID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_CharacterID) -{ +XS(XS_Client_CharacterID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::CharacterID(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CharacterID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_UpdateAdmin); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UpdateAdmin) -{ +XS(XS_Client_UpdateAdmin) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::UpdateAdmin(THIS, iFromDB= true)"); + Perl_croak(aTHX_ "Usage: Client::UpdateAdmin(THIS, bool from_db = true)"); { - Client * THIS; - bool iFromDB; + Client *THIS; + bool iFromDB; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) iFromDB = true; else { - iFromDB = (bool)SvTRUE(ST(1)); + iFromDB = (bool) SvTRUE(ST(1)); } THIS->UpdateAdmin(iFromDB); @@ -1660,28 +1585,26 @@ XS(XS_Client_UpdateAdmin) } XS(XS_Client_UpdateWho); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UpdateWho) -{ +XS(XS_Client_UpdateWho) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::UpdateWho(THIS, remove= 0)"); + Perl_croak(aTHX_ "Usage: Client::UpdateWho(THIS, uint8 remove = 0)"); { - Client * THIS; - uint8 remove; + Client *THIS; + uint8 remove; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) remove = 0; else { - remove = (uint8)SvUV(ST(1)); + remove = (uint8) SvUV(ST(1)); } THIS->UpdateWho(remove); @@ -1690,135 +1613,129 @@ XS(XS_Client_UpdateWho) } XS(XS_Client_GuildRank); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GuildRank) -{ +XS(XS_Client_GuildRank) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GuildRank(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GuildRank(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GuildID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GuildID) -{ +XS(XS_Client_GuildID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GuildID(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GuildID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetFace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetFace) -{ +XS(XS_Client_GetFace) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetFace(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetFace(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_TakeMoneyFromPP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_TakeMoneyFromPP) -{ +XS(XS_Client_TakeMoneyFromPP) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::TakeMoneyFromPP(THIS, copper, updateclient=false)"); + Perl_croak(aTHX_ "Usage: Client::TakeMoneyFromPP(THIS, uint32 copper, bool update_client = false)"); { - Client * THIS; - bool RETVAL; - bool updateclient = false; - uint32 copper = (uint32)SvUV(ST(1)); + Client *THIS; + bool RETVAL; + bool updateclient = false; + uint32 copper = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 2) - updateclient = (bool)SvTRUE(ST(2)); + updateclient = (bool) SvTRUE(ST(2)); RETVAL = THIS->TakeMoneyFromPP(copper, updateclient); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_AddMoneyToPP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AddMoneyToPP) -{ +XS(XS_Client_AddMoneyToPP) { dXSARGS; if (items != 6) - Perl_croak(aTHX_ "Usage: Client::AddMoneyToPP(THIS, copper, silver, gold, platinum, updateclient)"); + Perl_croak(aTHX_ + "Usage: Client::AddMoneyToPP(THIS, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool update_client)"); { - Client * THIS; - uint32 copper = (uint32)SvUV(ST(1)); - uint32 silver = (uint32)SvUV(ST(2)); - uint32 gold = (uint32)SvUV(ST(3)); - uint32 platinum = (uint32)SvUV(ST(4)); - bool updateclient = (bool)SvTRUE(ST(5)); + Client *THIS; + uint32 copper = (uint32) SvUV(ST(1)); + uint32 silver = (uint32) SvUV(ST(2)); + uint32 gold = (uint32) SvUV(ST(3)); + uint32 platinum = (uint32) SvUV(ST(4)); + bool updateclient = (bool) SvTRUE(ST(5)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddMoneyToPP(copper, silver, gold, platinum, updateclient); @@ -1827,22 +1744,20 @@ XS(XS_Client_AddMoneyToPP) } XS(XS_Client_TGB); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_TGB) -{ +XS(XS_Client_TGB) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::TGB(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->TGB(); @@ -1853,48 +1768,45 @@ XS(XS_Client_TGB) } XS(XS_Client_GetSkillPoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetSkillPoints) -{ +XS(XS_Client_GetSkillPoints) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetSkillPoints(THIS)"); { - Client * THIS; - uint16 RETVAL; + Client *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSkillPoints(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetSkillPoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetSkillPoints) -{ +XS(XS_Client_SetSkillPoints) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetSkillPoints(THIS, inp)"); { - Client * THIS; - int inp = (int)SvIV(ST(1)); + Client *THIS; + int inp = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSkillPoints(inp); @@ -1903,29 +1815,27 @@ XS(XS_Client_SetSkillPoints) } XS(XS_Client_IncreaseSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IncreaseSkill) -{ +XS(XS_Client_IncreaseSkill) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::IncreaseSkill(THIS, skill_id, value= 1)"); + Perl_croak(aTHX_ "Usage: Client::IncreaseSkill(THIS, int skill_id, int value = 1)"); { - Client * THIS; - int skill_id = (int)SvIV(ST(1)); - int value; + Client *THIS; + int skill_id = (int) SvIV(ST(1)); + int value; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) value = 1; else { - value = (int)SvIV(ST(2)); + value = (int) SvIV(ST(2)); } THIS->IncreaseSkill(skill_id, value); @@ -1934,29 +1844,27 @@ XS(XS_Client_IncreaseSkill) } XS(XS_Client_IncreaseLanguageSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IncreaseLanguageSkill) -{ +XS(XS_Client_IncreaseLanguageSkill) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::IncreaseLanguageSkill(THIS, skill_id, value= 1)"); + Perl_croak(aTHX_ "Usage: Client::IncreaseLanguageSkill(THIS, int skill_id, int value = 1)"); { - Client * THIS; - int skill_id = (int)SvIV(ST(1)); - int value; + Client *THIS; + int skill_id = (int) SvIV(ST(1)); + int value; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) value = 1; else { - value = (int)SvIV(ST(2)); + value = (int) SvIV(ST(2)); } THIS->IncreaseLanguageSkill(skill_id, value); @@ -1965,131 +1873,123 @@ XS(XS_Client_IncreaseLanguageSkill) } XS(XS_Client_GetSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetSkill) -{ +XS(XS_Client_GetSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetSkill(THIS, skill_id)"); + Perl_croak(aTHX_ "Usage: Client::GetSkill(THIS, uint16 skill_id)"); { - Client * THIS; - uint16 RETVAL; + Client *THIS; + uint16 RETVAL; dXSTARG; - EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1)); + EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSkill(skill_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetRawSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetRawSkill) -{ +XS(XS_Client_GetRawSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetRawSkill(THIS, skill_id)"); + Perl_croak(aTHX_ "Usage: Client::GetRawSkill(THIS, int skill_id)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; - EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1)); + EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRawSkill(skill_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_HasSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_HasSkill) -{ +XS(XS_Client_HasSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::HasSkill(THIS, skill_id)"); + Perl_croak(aTHX_ "Usage: Client::HasSkill(THIS, int skill_id)"); { - Client * THIS; - bool RETVAL; - EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1)); + Client *THIS; + bool RETVAL; + EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->HasSkill(skill_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_CanHaveSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_CanHaveSkill) -{ +XS(XS_Client_CanHaveSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::CanHaveSkill(THIS, skill_id)"); + Perl_croak(aTHX_ "Usage: Client::CanHaveSkill(THIS, int skill_id)"); { - Client * THIS; - bool RETVAL; - EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1)); + Client *THIS; + bool RETVAL; + EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanHaveSkill(skill_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_SetSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetSkill) -{ +XS(XS_Client_SetSkill) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetSkill(THIS, skill_num, value)"); + Perl_croak(aTHX_ "Usage: Client::SetSkill(THIS, int skill_id, uint16 value)"); { - Client * THIS; - EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType)SvUV(ST(1)); - uint16 value = (uint16)SvUV(ST(2)); + Client *THIS; + EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType) SvUV(ST(1)); + uint16 value = (uint16) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSkill(skill_num, value); @@ -2098,23 +1998,21 @@ XS(XS_Client_SetSkill) } XS(XS_Client_AddSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AddSkill) -{ +XS(XS_Client_AddSkill) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::AddSkill(THIS, skillid, value)"); + Perl_croak(aTHX_ "Usage: Client::AddSkill(THIS, int skill_id, uint16 value)"); { - Client * THIS; - EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType)SvUV(ST(1)); - uint16 value = (uint16)SvUV(ST(2)); + Client *THIS; + EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType) SvUV(ST(1)); + uint16 value = (uint16) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddSkill(skillid, value); @@ -2123,22 +2021,20 @@ XS(XS_Client_AddSkill) } XS(XS_Client_CheckSpecializeIncrease); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_CheckSpecializeIncrease) -{ +XS(XS_Client_CheckSpecializeIncrease) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::CheckSpecializeIncrease(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Client::CheckSpecializeIncrease(THIS, uint16 spell_id)"); { - Client * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); + Client *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->CheckSpecializeIncrease(spell_id); @@ -2147,119 +2043,113 @@ XS(XS_Client_CheckSpecializeIncrease) } XS(XS_Client_CheckIncreaseSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_CheckIncreaseSkill) -{ +XS(XS_Client_CheckIncreaseSkill) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::CheckIncreaseSkill(THIS, skillid, chancemodi= 0)"); + Perl_croak(aTHX_ "Usage: Client::CheckIncreaseSkill(THIS, int skill_id, int chance_modifier = 0)"); { - Client * THIS; - bool RETVAL; - EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType)SvUV(ST(1)); - int chancemodi; + Client *THIS; + bool RETVAL; + EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType) SvUV(ST(1)); + int chancemodi; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) chancemodi = 0; else { - chancemodi = (int)SvIV(ST(2)); + chancemodi = (int) SvIV(ST(2)); } RETVAL = THIS->CheckIncreaseSkill(skillid, nullptr, chancemodi); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_SetLanguageSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetLanguageSkill) -{ +XS(XS_Client_SetLanguageSkill) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetLanguageSkill(THIS, langid, value)"); + Perl_croak(aTHX_ "Usage: Client::SetLanguageSkill(THIS, int language_id, int value)"); { - Client * THIS; - int langid = (int)SvIV(ST(1)); - int value = (int)SvIV(ST(2)); + Client *THIS; + int langid = (int) SvIV(ST(1)); + int value = (int) SvIV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetLanguageSkill(langid, value); } XSRETURN_EMPTY; + } XS(XS_Client_MaxSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_MaxSkill) -{ +XS(XS_Client_MaxSkill) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: Client::MaxSkill(THIS, skillid, class, level)"); + Perl_croak(aTHX_ "Usage: Client::MaxSkill(THIS, uint16 skill_id, uint16 class_id, uint16 level)"); { - Client * THIS; - uint16 RETVAL; - EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType)SvUV(ST(1)); - uint16 class_ = 0; - uint16 level = 0; + Client *THIS; + uint16 RETVAL; + EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType) SvUV(ST(1)); + uint16 class_ = 0; + uint16 level = 0; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items > 2) - class_ = (uint16)SvUV(ST(2)); + if (items > 2) + class_ = (uint16) SvUV(ST(2)); else class_ = THIS->GetClass(); - if(items > 3) - level = (uint16)SvUV(ST(3)); + if (items > 3) + level = (uint16) SvUV(ST(3)); else level = THIS->GetLevel(); RETVAL = THIS->MaxSkill(skillid, class_, level); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GMKill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GMKill) -{ +XS(XS_Client_GMKill) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GMKill(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->GMKill(); @@ -2268,22 +2158,20 @@ XS(XS_Client_GMKill) } XS(XS_Client_IsMedding); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsMedding) -{ +XS(XS_Client_IsMedding) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsMedding(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsMedding(); @@ -2294,48 +2182,45 @@ XS(XS_Client_IsMedding) } XS(XS_Client_GetDuelTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetDuelTarget) -{ +XS(XS_Client_GetDuelTarget) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetDuelTarget(THIS)"); { - Client * THIS; - uint16 RETVAL; + Client *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDuelTarget(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_IsDueling); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsDueling) -{ +XS(XS_Client_IsDueling) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsDueling(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsDueling(); @@ -2346,22 +2231,20 @@ XS(XS_Client_IsDueling) } XS(XS_Client_SetDuelTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetDuelTarget) -{ +XS(XS_Client_SetDuelTarget) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetDuelTarget(THIS, set_id)"); { - Client * THIS; - uint16 set_id = (uint16)SvUV(ST(1)); + Client *THIS; + uint16 set_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetDuelTarget(set_id); @@ -2370,22 +2253,20 @@ XS(XS_Client_SetDuelTarget) } XS(XS_Client_SetDueling); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetDueling) -{ +XS(XS_Client_SetDueling) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetDueling(THIS, duel)"); { - Client * THIS; - bool duel = (bool)SvTRUE(ST(1)); + Client *THIS; + bool duel = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetDueling(duel); @@ -2394,21 +2275,19 @@ XS(XS_Client_SetDueling) } XS(XS_Client_ResetAA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ResetAA) -{ +XS(XS_Client_ResetAA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::ResetAA(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ResetAA(); @@ -2417,30 +2296,28 @@ XS(XS_Client_ResetAA) } XS(XS_Client_MemSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_MemSpell) -{ +XS(XS_Client_MemSpell) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Client::MemSpell(THIS, spell_id, slot, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::MemSpell(THIS, uint16 spell_id, int slot, [bool update_client = true])"); { - Client * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); - int slot = (int)SvIV(ST(2)); - bool update_client; + Client *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); + int slot = (int) SvIV(ST(2)); + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) update_client = true; else { - update_client = (bool)SvTRUE(ST(3)); + update_client = (bool) SvTRUE(ST(3)); } THIS->MemSpell(spell_id, slot, update_client); @@ -2449,29 +2326,27 @@ XS(XS_Client_MemSpell) } XS(XS_Client_UnmemSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UnmemSpell) -{ +XS(XS_Client_UnmemSpell) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::UnmemSpell(THIS, slot, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::UnmemSpell(THIS, int slot, [bool update_client = true])"); { - Client * THIS; - int slot = (int)SvIV(ST(1)); - bool update_client; + Client *THIS; + int slot = (int) SvIV(ST(1)); + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) update_client = true; else { - update_client = (bool)SvTRUE(ST(2)); + update_client = (bool) SvTRUE(ST(2)); } THIS->UnmemSpell(slot, update_client); @@ -2480,22 +2355,20 @@ XS(XS_Client_UnmemSpell) } XS(XS_Client_UnmemSpellBySpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UnmemSpellBySpellID) -{ +XS(XS_Client_UnmemSpellBySpellID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::UnmemSpellBySpellID(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Client::UnmemSpellBySpellID(THIS, int32 spell_id)"); { - Client * THIS; - int32 spell_id = (int32)SvIV(ST(1)); + Client *THIS; + int32 spell_id = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->UnmemSpellBySpellID(spell_id); @@ -2504,28 +2377,26 @@ XS(XS_Client_UnmemSpellBySpellID) } XS(XS_Client_UnmemSpellAll); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UnmemSpellAll) -{ +XS(XS_Client_UnmemSpellAll) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::UnmemSpellAll(THIS, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::UnmemSpellAll(THIS, [bool update_client = true])"); { - Client * THIS; - bool update_client; + Client *THIS; + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) update_client = true; else { - update_client = (bool)SvTRUE(ST(1)); + update_client = (bool) SvTRUE(ST(1)); } THIS->UnmemSpellAll(update_client); @@ -2534,30 +2405,28 @@ XS(XS_Client_UnmemSpellAll) } XS(XS_Client_ScribeSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ScribeSpell) -{ +XS(XS_Client_ScribeSpell) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Client::ScribeSpell(THIS, spell_id, slot, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::ScribeSpell(THIS, uint16 spell_id, int slot, [bool update_client = true])"); { - Client * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); - int slot = (int)SvIV(ST(2)); - bool update_client; + Client *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); + int slot = (int) SvIV(ST(2)); + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) update_client = true; else { - update_client = (bool)SvTRUE(ST(3)); + update_client = (bool) SvTRUE(ST(3)); } THIS->ScribeSpell(spell_id, slot, update_client); @@ -2566,29 +2435,27 @@ XS(XS_Client_ScribeSpell) } XS(XS_Client_UnscribeSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UnscribeSpell) -{ +XS(XS_Client_UnscribeSpell) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::UnscribeSpell(THIS, slot, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::UnscribeSpell(THIS, int slot, [bool update_client = true])"); { - Client * THIS; - int slot = (int)SvIV(ST(1)); - bool update_client; + Client *THIS; + int slot = (int) SvIV(ST(1)); + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) update_client = true; else { - update_client = (bool)SvTRUE(ST(2)); + update_client = (bool) SvTRUE(ST(2)); } THIS->UnscribeSpell(slot, update_client); @@ -2597,28 +2464,26 @@ XS(XS_Client_UnscribeSpell) } XS(XS_Client_UnscribeSpellAll); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UnscribeSpellAll) -{ +XS(XS_Client_UnscribeSpellAll) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::UnscribeSpellAll(THIS, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::UnscribeSpellAll(THIS, [bool update_client = true])"); { - Client * THIS; - bool update_client; + Client *THIS; + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) update_client = true; else { - update_client = (bool)SvTRUE(ST(1)); + update_client = (bool) SvTRUE(ST(1)); } THIS->UnscribeSpellAll(update_client); @@ -2627,22 +2492,20 @@ XS(XS_Client_UnscribeSpellAll) } XS(XS_Client_TrainDiscBySpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_TrainDiscBySpellID) -{ +XS(XS_Client_TrainDiscBySpellID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::TrainDiscBySpellID(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Client::TrainDiscBySpellID(THIS, int32 spell_id)"); { - Client * THIS; - int32 spell_id = (int32)SvIV(ST(1)); + Client *THIS; + int32 spell_id = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->TrainDiscBySpellID(spell_id); @@ -2651,56 +2514,53 @@ XS(XS_Client_TrainDiscBySpellID) } XS(XS_Client_GetDiscSlotBySpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetDiscSlotBySpellID) -{ +XS(XS_Client_GetDiscSlotBySpellID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetDiscSlotBySpellID(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Client::GetDiscSlotBySpellID(THIS, int32 spell_id)"); { - Client * THIS; - int RETVAL; - int32 spell_id = (int32)SvIV(ST(1)); + Client *THIS; + int RETVAL; + int32 spell_id = (int32) SvIV(ST(1)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDiscSlotBySpellID(spell_id); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_UntrainDisc); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UntrainDisc) -{ +XS(XS_Client_UntrainDisc) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Client::UntrainDisc(THIS, slot, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::UntrainDisc(THIS, int slot, [bool update_client = true])"); { - Client * THIS; - int slot = (int)SvIV(ST(1)); - bool update_client; + Client *THIS; + int slot = (int) SvIV(ST(1)); + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) update_client = true; else { - update_client = (bool)SvTRUE(ST(2)); + update_client = (bool) SvTRUE(ST(2)); } THIS->UntrainDisc(slot, update_client); @@ -2709,28 +2569,26 @@ XS(XS_Client_UntrainDisc) } XS(XS_Client_UntrainDiscAll); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UntrainDiscAll) -{ +XS(XS_Client_UntrainDiscAll) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::UntrainDiscAll(THIS, update_client= true)"); + Perl_croak(aTHX_ "Usage: Client::UntrainDiscAll(THIS, [update_client = true])"); { - Client * THIS; - bool update_client; + Client *THIS; + bool update_client; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) update_client = true; else { - update_client = (bool)SvTRUE(ST(1)); + update_client = (bool) SvTRUE(ST(1)); } THIS->UntrainDiscAll(update_client); @@ -2739,22 +2597,20 @@ XS(XS_Client_UntrainDiscAll) } XS(XS_Client_IsSitting); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsSitting) -{ +XS(XS_Client_IsSitting) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsSitting(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsSitting(); @@ -2765,22 +2621,20 @@ XS(XS_Client_IsSitting) } XS(XS_Client_IsBecomeNPC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsBecomeNPC) -{ +XS(XS_Client_IsBecomeNPC) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsBecomeNPC(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsBecomeNPC(); @@ -2791,48 +2645,45 @@ XS(XS_Client_IsBecomeNPC) } XS(XS_Client_GetBecomeNPCLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetBecomeNPCLevel) -{ +XS(XS_Client_GetBecomeNPCLevel) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetBecomeNPCLevel(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBecomeNPCLevel(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetBecomeNPC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetBecomeNPC) -{ +XS(XS_Client_SetBecomeNPC) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetBecomeNPC(THIS, flag)"); { - Client * THIS; - bool flag = (bool)SvTRUE(ST(1)); + Client *THIS; + bool flag = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetBecomeNPC(flag); @@ -2841,22 +2692,20 @@ XS(XS_Client_SetBecomeNPC) } XS(XS_Client_SetBecomeNPCLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetBecomeNPCLevel) -{ +XS(XS_Client_SetBecomeNPCLevel) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetBecomeNPCLevel(THIS, level)"); { - Client * THIS; - uint8 level = (uint8)SvUV(ST(1)); + Client *THIS; + uint8 level = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetBecomeNPCLevel(level); @@ -2865,22 +2714,20 @@ XS(XS_Client_SetBecomeNPCLevel) } XS(XS_Client_SetFeigned); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetFeigned) -{ +XS(XS_Client_SetFeigned) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetFeigned(THIS, in_feigned)"); { - Client * THIS; - bool in_feigned = (bool)SvTRUE(ST(1)); + Client *THIS; + bool in_feigned = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetFeigned(in_feigned); @@ -2889,22 +2736,20 @@ XS(XS_Client_SetFeigned) } XS(XS_Client_GetFeigned); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetFeigned) -{ +XS(XS_Client_GetFeigned) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetFeigned(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetFeigned(); @@ -2915,22 +2760,20 @@ XS(XS_Client_GetFeigned) } XS(XS_Client_AutoSplitEnabled); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AutoSplitEnabled) -{ +XS(XS_Client_AutoSplitEnabled) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::AutoSplitEnabled(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->AutoSplitEnabled(); @@ -2941,22 +2784,20 @@ XS(XS_Client_AutoSplitEnabled) } XS(XS_Client_SetHorseId); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetHorseId) -{ +XS(XS_Client_SetHorseId) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetHorseId(THIS, horseid_in)"); { - Client * THIS; - uint16 horseid_in = (uint16)SvUV(ST(1)); + Client *THIS; + uint16 horseid_in = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetHorseId(horseid_in); @@ -2965,84 +2806,80 @@ XS(XS_Client_SetHorseId) } XS(XS_Client_GetHorseId); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetHorseId) -{ +XS(XS_Client_GetHorseId) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetHorseId(THIS)"); { - Client * THIS; - uint16 RETVAL; + Client *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHorseId(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_NukeItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_NukeItem) -{ +XS(XS_Client_NukeItem) { dXSARGS; if (items != 3 && items != 2) - Perl_croak(aTHX_ "Usage: Client::NukeItem(THIS, itemnum, [where_to_check])"); + Perl_croak(aTHX_ "Usage: Client::NukeItem(THIS, uint32 item_id, [uint8 slot_to_check])"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; - uint32 itemnum = (uint32)SvUV(ST(1)); - uint8 where_to_check; + uint32 itemnum = (uint32) SvUV(ST(1)); + uint8 where_to_check; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items < 3){ + if (items < 3) { where_to_check = 0xFF; } - if(items == 3){ - where_to_check = (uint8)SvUV(ST(2)); + if (items == 3) { + where_to_check = (uint8) SvUV(ST(2)); } RETVAL = THIS->NukeItem(itemnum, where_to_check); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetTint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetTint) -{ +XS(XS_Client_SetTint) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetTint(THIS, slot_id, color)"); + Perl_croak(aTHX_ "Usage: Client::SetTint(THIS, int16 slot_id, uint32 color)"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); - uint32 color = (uint32)SvUV(ST(2)); + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + uint32 color = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetTint(slot_id, color); @@ -3051,23 +2888,21 @@ XS(XS_Client_SetTint) } XS(XS_Client_SetMaterial); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetMaterial) -{ +XS(XS_Client_SetMaterial) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetMaterial(THIS, slot_id, item_id)"); + Perl_croak(aTHX_ "Usage: Client::SetMaterial(THIS, int16 slot_id, uint32 item_id)"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); - uint32 item_id = (uint32)SvUV(ST(2)); + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + uint32 item_id = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetMaterial(slot_id, item_id); @@ -3076,21 +2911,19 @@ XS(XS_Client_SetMaterial) } XS(XS_Client_Undye); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Undye) -{ +XS(XS_Client_Undye) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Undye(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Undye(); @@ -3099,91 +2932,88 @@ XS(XS_Client_Undye) } XS(XS_Client_GetItemIDAt); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetItemIDAt) -{ +XS(XS_Client_GetItemIDAt) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetItemIDAt(THIS, slot_id)"); + Perl_croak(aTHX_ "Usage: Client::GetItemIDAt(THIS, int16 slot_id)"); { - Client * THIS; - int32 RETVAL; + Client *THIS; + int32 RETVAL; dXSTARG; - int16 slot_id = (int16)SvIV(ST(1)); + int16 slot_id = (int16) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetItemIDAt(slot_id); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetAugmentIDAt); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAugmentIDAt) -{ +XS(XS_Client_GetAugmentIDAt) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::GetAugmentIDAt(THIS, slot_id, augslot)"); + Perl_croak(aTHX_ "Usage: Client::GetAugmentIDAt(THIS, int16 slot_id, int16 aug_slot)"); { - Client * THIS; - int32 RETVAL; + Client *THIS; + int32 RETVAL; dXSTARG; - int16 slot_id = (int16)SvIV(ST(1)); - int16 augslot = (uint8)SvIV(ST(2)); + int16 slot_id = (int16) SvIV(ST(1)); + int16 augslot = (uint8) SvIV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAugmentIDAt(slot_id, augslot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_DeleteItemInInventory); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_DeleteItemInInventory) -{ +XS(XS_Client_DeleteItemInInventory) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: Client::DeleteItemInInventory(THIS, slot_id, quantity= 0, client_update= false)"); + Perl_croak(aTHX_ + "Usage: Client::DeleteItemInInventory(THIS, int16 slot_id, [int8 quantity = 0], [bool client_update = false])"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); - int8 quantity; - bool client_update; + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + int8 quantity; + bool client_update; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) quantity = 0; else { - quantity = (int8)SvIV(ST(2)); + quantity = (int8) SvIV(ST(2)); } if (items < 4) client_update = false; else { - client_update = (bool)SvTRUE(ST(3)); + client_update = (bool) SvTRUE(ST(3)); } THIS->DeleteItemInInventory(slot_id, quantity, client_update); @@ -3192,55 +3022,54 @@ XS(XS_Client_DeleteItemInInventory) } XS(XS_Client_SummonItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SummonItem) -{ +XS(XS_Client_SummonItem) { dXSARGS; if (items < 2 || items > 10) - Perl_croak(aTHX_ "Usage: Client::SummonItem(THIS, item_id, charges=0, attune=0, aug1=0, aug2=0, aug3=0, aug4=0, aug5=0, slot_id=30)"); + Perl_croak(aTHX_ + "Usage: Client::SummonItem(THIS, uint32 item_id, [int16 charges = -1], [bool attune = false], [uint32 aug1 = 0], [uint32 aug2 = 0], [uint32 aug3 = 0], [uint32 aug4 = 0], [uint32 aug5 = 0], [uint16 slot_id = 30])"); { - Client * THIS; - uint32 item_id = (uint32)SvUV(ST(1)); - int16 charges = -1; - bool attune = false; - uint32 aug1 = 0; - uint32 aug2 = 0; - uint32 aug3 = 0; - uint32 aug4 = 0; - uint32 aug5 = 0; - uint16 slot_id = 30; + Client *THIS; + uint32 item_id = (uint32) SvUV(ST(1)); + int16 charges = -1; + bool attune = false; + uint32 aug1 = 0; + uint32 aug2 = 0; + uint32 aug3 = 0; + uint32 aug4 = 0; + uint32 aug5 = 0; + uint16 slot_id = 30; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 2) { - charges = (int16)SvIV(ST(2)); + charges = (int16) SvIV(ST(2)); } if (items > 3) { - attune = (bool)SvTRUE(ST(3)); + attune = (bool) SvTRUE(ST(3)); } if (items > 4) { - aug1 = (uint32)SvUV(ST(4)); + aug1 = (uint32) SvUV(ST(4)); } if (items > 5) { - aug2 = (uint32)SvUV(ST(5)); + aug2 = (uint32) SvUV(ST(5)); } if (items > 6) { - aug3 = (uint32)SvUV(ST(6)); + aug3 = (uint32) SvUV(ST(6)); } if (items > 7) { - aug4 = (uint32)SvUV(ST(7)); + aug4 = (uint32) SvUV(ST(7)); } if (items > 8) { - aug5 = (uint32)SvUV(ST(8)); + aug5 = (uint32) SvUV(ST(8)); } if (items > 9) { - slot_id = (uint16)SvUV(ST(9)); + slot_id = (uint16) SvUV(ST(9)); } THIS->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attune, slot_id); @@ -3249,23 +3078,21 @@ XS(XS_Client_SummonItem) } XS(XS_Client_SetStats); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetStats) -{ +XS(XS_Client_SetStats) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetStats(THIS, type, increase_val)"); + Perl_croak(aTHX_ "Usage: Client::SetStats(THIS, uint8 type, uint16 increase_val)"); { - Client * THIS; - uint8 type = (uint8)SvUV(ST(1)); - int16 increase_val = (int16)SvIV(ST(2)); + Client *THIS; + uint8 type = (uint8) SvUV(ST(1)); + int16 increase_val = (int16) SvIV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetStats(type, increase_val); @@ -3274,23 +3101,21 @@ XS(XS_Client_SetStats) } XS(XS_Client_IncStats); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IncStats) -{ +XS(XS_Client_IncStats) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::IncStats(THIS, type, increase_val)"); + Perl_croak(aTHX_ "Usage: Client::IncStats(THIS, uint8 type, uint16 increase_val)"); { - Client * THIS; - uint8 type = (uint8)SvUV(ST(1)); - int16 increase_val = (int16)SvIV(ST(2)); + Client *THIS; + uint8 type = (uint8) SvUV(ST(1)); + int16 increase_val = (int16) SvIV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->IncStats(type, increase_val); @@ -3299,22 +3124,20 @@ XS(XS_Client_IncStats) } XS(XS_Client_DropItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_DropItem) -{ +XS(XS_Client_DropItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::DropItem(THIS, slot_id)"); + Perl_croak(aTHX_ "Usage: Client::DropItem(THIS, int16 slot_id)"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->DropItem(slot_id); @@ -3323,21 +3146,19 @@ XS(XS_Client_DropItem) } XS(XS_Client_BreakInvis); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_BreakInvis) -{ +XS(XS_Client_BreakInvis) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::BreakInvis(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->BreakInvis(); @@ -3346,47 +3167,43 @@ XS(XS_Client_BreakInvis) } XS(XS_Client_GetGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetGroup) -{ +XS(XS_Client_GetGroup) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetGroup(THIS)"); { - Client * THIS; - Group * RETVAL; + Client *THIS; + Group *RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGroup(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Group", (void*)RETVAL); + sv_setref_pv(ST(0), "Group", (void *) RETVAL); } XSRETURN(1); } XS(XS_Client_LeaveGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_LeaveGroup) -{ +XS(XS_Client_LeaveGroup) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::LeaveGroup(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->LeaveGroup(); @@ -3395,48 +3212,44 @@ XS(XS_Client_LeaveGroup) } XS(XS_Client_GetRaid); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetRaid) -{ +XS(XS_Client_GetRaid) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetRaid(THIS)"); { - Client * THIS; - Raid * RETVAL; + Client *THIS; + Raid *RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRaid(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Raid", (void*)RETVAL); + sv_setref_pv(ST(0), "Raid", (void *) RETVAL); } XSRETURN(1); } XS(XS_Client_IsGrouped); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsGrouped) -{ +XS(XS_Client_IsGrouped) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsGrouped(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsGrouped(); @@ -3447,22 +3260,20 @@ XS(XS_Client_IsGrouped) } XS(XS_Client_IsRaidGrouped); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsRaidGrouped) -{ +XS(XS_Client_IsRaidGrouped) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::IsRaidGrouped(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsRaidGrouped(); @@ -3473,22 +3284,20 @@ XS(XS_Client_IsRaidGrouped) } XS(XS_Client_Hungry); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Hungry) -{ +XS(XS_Client_Hungry) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Hungry(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Hungry(); @@ -3499,22 +3308,20 @@ XS(XS_Client_Hungry) } XS(XS_Client_Thirsty); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Thirsty) -{ +XS(XS_Client_Thirsty) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Thirsty(THIS)"); { - Client * THIS; - bool RETVAL; + Client *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Thirsty(); @@ -3525,103 +3332,97 @@ XS(XS_Client_Thirsty) } XS(XS_Client_GetInstrumentMod); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetInstrumentMod) -{ +XS(XS_Client_GetInstrumentMod) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetInstrumentMod(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Client::GetInstrumentMod(THIS, uint16 spell_id)"); { - Client * THIS; - uint16 RETVAL; + Client *THIS; + uint16 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); + uint16 spell_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetInstrumentMod(spell_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_DecreaseByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_DecreaseByID) -{ +XS(XS_Client_DecreaseByID) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::DecreaseByID(THIS, type, amt)"); + Perl_croak(aTHX_ "Usage: Client::DecreaseByID(THIS, uint32 type, unit8 amount)"); { - Client * THIS; - bool RETVAL; - uint32 type = (uint32)SvUV(ST(1)); - uint8 amt = (uint8)SvUV(ST(2)); + Client *THIS; + bool RETVAL; + uint32 type = (uint32) SvUV(ST(1)); + uint8 amt = (uint8) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DecreaseByID(type, amt); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_SlotConvert2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SlotConvert2) -{ +XS(XS_Client_SlotConvert2) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SlotConvert2(THIS, slot)"); + Perl_croak(aTHX_ "Usage: Client::SlotConvert2(THIS, uint8 slot)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; - uint8 slot = (uint8)SvUV(ST(1)); + uint8 slot = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->SlotConvert2(slot); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_Escape); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Escape) -{ +XS(XS_Client_Escape) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::Escape(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Escape(); @@ -3630,21 +3431,19 @@ XS(XS_Client_Escape) } XS(XS_Client_RemoveNoRent); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_RemoveNoRent) -{ +XS(XS_Client_RemoveNoRent) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::RemoveNoRent(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveNoRent(); @@ -3653,21 +3452,19 @@ XS(XS_Client_RemoveNoRent) } XS(XS_Client_GoFish); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GoFish) -{ +XS(XS_Client_GoFish) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GoFish(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->GoFish(); @@ -3676,21 +3473,19 @@ XS(XS_Client_GoFish) } XS(XS_Client_ForageItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ForageItem) -{ +XS(XS_Client_ForageItem) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::ForageItem(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ForageItem(); @@ -3699,68 +3494,64 @@ XS(XS_Client_ForageItem) } XS(XS_Client_CalcPriceMod); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_CalcPriceMod) -{ +XS(XS_Client_CalcPriceMod) { dXSARGS; if (items < 1 || items > 3) - Perl_croak(aTHX_ "Usage: Client::CalcPriceMod(THIS, other= 0, reverse= false)"); + Perl_croak(aTHX_ "Usage: Client::CalcPriceMod(THIS, Mob*, [bool reverse = false])"); { - Client * THIS; - float RETVAL; + Client *THIS; + float RETVAL; dXSTARG; - Mob* other; - bool reverse; + Mob *other; + bool reverse; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) other = 0; else { if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); } if (items < 3) reverse = false; else { - reverse = (bool)SvTRUE(ST(2)); + reverse = (bool) SvTRUE(ST(2)); } RETVAL = THIS->CalcPriceMod(other, reverse); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Client_ResetTrade); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ResetTrade) -{ +XS(XS_Client_ResetTrade) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::ResetTrade(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ResetTrade(); @@ -3769,77 +3560,72 @@ XS(XS_Client_ResetTrade) } XS(XS_Client_UseDiscipline); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UseDiscipline) -{ +XS(XS_Client_UseDiscipline) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::UseDiscipline(THIS, spell_id, target)"); + Perl_croak(aTHX_ "Usage: Client::UseDiscipline(THIS, int32 spell_id, int32 target)"); { - Client * THIS; - bool RETVAL; - uint32 spell_id = (uint32)SvUV(ST(1)); - uint32 target = (uint32)SvUV(ST(2)); + Client *THIS; + bool RETVAL; + uint32 spell_id = (uint32) SvUV(ST(1)); + uint32 target = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->UseDiscipline(spell_id, target); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_GetCharacterFactionLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetCharacterFactionLevel) -{ +XS(XS_Client_GetCharacterFactionLevel) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetCharacterFactionLevel(THIS, faction_id)"); + Perl_croak(aTHX_ "Usage: Client::GetCharacterFactionLevel(THIS, int32 faction_id)"); { - Client * THIS; - int32 RETVAL; + Client *THIS; + int32 RETVAL; dXSTARG; - int32 faction_id = (int32)SvIV(ST(1)); + int32 faction_id = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCharacterFactionLevel(faction_id); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetZoneFlag); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetZoneFlag) -{ +XS(XS_Client_SetZoneFlag) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetZoneFlag(THIS, zone_id)"); + Perl_croak(aTHX_ "Usage: Client::SetZoneFlag(THIS, uint32 zone_id)"); { - Client * THIS; - uint32 zone_id = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 zone_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetZoneFlag(zone_id); @@ -3848,22 +3634,20 @@ XS(XS_Client_SetZoneFlag) } XS(XS_Client_ClearZoneFlag); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ClearZoneFlag) -{ +XS(XS_Client_ClearZoneFlag) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::ClearZoneFlag(THIS, zone_id)"); + Perl_croak(aTHX_ "Usage: Client::ClearZoneFlag(THIS, uint32 zone_id)"); { - Client * THIS; - uint32 zone_id = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 zone_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearZoneFlag(zone_id); @@ -3872,58 +3656,53 @@ XS(XS_Client_ClearZoneFlag) } XS(XS_Client_HasZoneFlag); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_HasZoneFlag) -{ +XS(XS_Client_HasZoneFlag) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::HasZoneFlag(THIS, zone_id)"); + Perl_croak(aTHX_ "Usage: Client::HasZoneFlag(THIS, uint32 zone_id)"); { - Client * THIS; - bool RETVAL; - uint32 zone_id = (uint32)SvUV(ST(1)); + Client *THIS; + bool RETVAL; + uint32 zone_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->HasZoneFlag(zone_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_SendZoneFlagInfo); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendZoneFlagInfo) -{ +XS(XS_Client_SendZoneFlagInfo) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SendZoneFlagInfo(THIS, to)"); + Perl_croak(aTHX_ "Usage: Client::SendZoneFlagInfo(THIS, Client* to)"); { - Client * THIS; - Client * to; + Client *THIS; + Client *to; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - to = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + to = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "to is not of type Client"); - if(to == nullptr) + if (to == nullptr) Perl_croak(aTHX_ "to is nullptr, avoiding crash."); THIS->SendZoneFlagInfo(to); @@ -3932,21 +3711,19 @@ XS(XS_Client_SendZoneFlagInfo) } XS(XS_Client_LoadZoneFlags); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_LoadZoneFlags) -{ +XS(XS_Client_LoadZoneFlags) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::LoadZoneFlags(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->LoadZoneFlags(); @@ -3955,32 +3732,30 @@ XS(XS_Client_LoadZoneFlags) } XS(XS_Client_SetAATitle); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetAATitle) -{ +XS(XS_Client_SetAATitle) { dXSARGS; if ((items < 2) || (items > 3)) - Perl_croak(aTHX_ "Usage: Client::SetAATitle(THIS, txt, [save])"); + Perl_croak(aTHX_ "Usage: Client::SetAATitle(THIS, string text, [bool save = false])"); { - Client * THIS; - char * txt = (char *)SvPV_nolen(ST(1)); + Client *THIS; + char *txt = (char *) SvPV_nolen(ST(1)); bool SaveTitle = false; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(strlen(txt) > 31) + if (strlen(txt) > 31) Perl_croak(aTHX_ "Title must be 31 characters or less"); - if(items == 3) + if (items == 3) SaveTitle = (SvIV(ST(2)) != 0); - if(!SaveTitle) + if (!SaveTitle) THIS->SetAATitle(txt); else title_manager.CreateNewPlayerTitle(THIS, txt); @@ -3989,53 +3764,51 @@ XS(XS_Client_SetAATitle) } XS(XS_Client_GetClientVersion); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetClientVersion) -{ +XS(XS_Client_GetClientVersion) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetClientVersion(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = static_cast(THIS->ClientVersion()); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetClientVersionBit); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetClientVersionBit) -{ +XS(XS_Client_GetClientVersionBit) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetClientVersionBit(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->ClientVersionBit(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -4044,28 +3817,27 @@ XS(XS_Client_SetTitleSuffix); XS(XS_Client_SetTitleSuffix) { dXSARGS; if ((items < 2) || (items > 3)) - Perl_croak(aTHX_ "Usage: Client::SetTitleSuffix(THIS, txt, [save])"); + Perl_croak(aTHX_ "Usage: Client::SetTitleSuffix(THIS, string text, [bool save = false])"); { - Client * THIS; - char * txt = (char *)SvPV_nolen(ST(1)); + Client *THIS; + char *txt = (char *) SvPV_nolen(ST(1)); bool SaveSuffix = false; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(strlen(txt) > 31) + if (strlen(txt) > 31) Perl_croak(aTHX_ "Title must be 31 characters or less"); - if(items == 3) + if (items == 3) SaveSuffix = (SvIV(ST(2)) != 0); - if(!SaveSuffix) + if (!SaveSuffix) THIS->SetTitleSuffix(txt); else title_manager.CreateNewPlayerSuffix(THIS, txt); @@ -4076,19 +3848,18 @@ XS(XS_Client_SetTitleSuffix) { XS(XS_Client_SetAAPoints); XS(XS_Client_SetAAPoints) { dXSARGS; - if(items != 2) - Perl_croak(aTHX_ "Usage: Client::SetAAPoints(THIS, points)"); + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::SetAAPoints(THIS, uint32 points)"); { - Client * THIS; + Client *THIS; uint32 points = SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetAAPoints(points); @@ -4099,24 +3870,24 @@ XS(XS_Client_SetAAPoints) { XS(XS_Client_GetAAPoints); XS(XS_Client_GetAAPoints) { dXSARGS; - if(items != 1) + if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetAAPoints(THIS)"); dXSTARG; { - Client * THIS; + Client *THIS; uint32 RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAAPoints(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -4124,24 +3895,24 @@ XS(XS_Client_GetAAPoints) { XS(XS_Client_GetSpentAA); XS(XS_Client_GetSpentAA) { dXSARGS; - if(items != 1) + if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetSpentAA(THIS)"); dXSTARG; { - Client * THIS; + Client *THIS; uint32 RETVAL; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpentAA(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -4149,19 +3920,18 @@ XS(XS_Client_GetSpentAA) { XS(XS_Client_AddAAPoints); XS(XS_Client_AddAAPoints) { dXSARGS; - if(items != 2) - Perl_croak(aTHX_ "Usage: Client::AddAAPoints(THIS, number)"); + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::AddAAPoints(THIS, uint32 points)"); { - Client * THIS; + Client *THIS; uint32 points = SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddAAPoints(points); @@ -4172,18 +3942,17 @@ XS(XS_Client_AddAAPoints) { XS(XS_Client_RefundAA); XS(XS_Client_RefundAA) { dXSARGS; - if(items != 1) + if (items != 1) Perl_croak(aTHX_ "Usage: Client::RefundAA(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RefundAA(); @@ -4192,278 +3961,262 @@ XS(XS_Client_RefundAA) { } XS(XS_Client_GetModCharacterFactionLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetModCharacterFactionLevel) -{ +XS(XS_Client_GetModCharacterFactionLevel) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetModCharacterFactionLevel(THIS, faction_id)"); + Perl_croak(aTHX_ "Usage: Client::GetModCharacterFactionLevel(THIS, int32 faction_id)"); { - Client * THIS; - int32 RETVAL; + Client *THIS; + int32 RETVAL; dXSTARG; - int32 faction_id = (int32)SvIV(ST(1)); + int32 faction_id = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetModCharacterFactionLevel(faction_id); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetLDoNWins); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLDoNWins) -{ +XS(XS_Client_GetLDoNWins) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetLDoNWins(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLDoNWins(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetLDoNLosses); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLDoNLosses) -{ +XS(XS_Client_GetLDoNLosses) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetLDoNLosses(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLDoNLosses(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetLDoNWinsTheme); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLDoNWinsTheme) -{ +XS(XS_Client_GetLDoNWinsTheme) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetLDoNWinsTheme(THIS, theme)"); + Perl_croak(aTHX_ "Usage: Client::GetLDoNWinsTheme(THIS, int32 theme)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; - int32 theme_out = (int32)SvIV(ST(1)); + int32 theme_out = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLDoNWinsTheme(theme_out); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetLDoNLossesTheme); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetLDoNLossesTheme) -{ +XS(XS_Client_GetLDoNLossesTheme) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetLDoNLossesTheme(THIS, theme)"); + Perl_croak(aTHX_ "Usage: Client::GetLDoNLossesTheme(THIS, int32 theme)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; - int32 theme_out = (int32)SvIV(ST(1)); + int32 theme_out = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLDoNLossesTheme(theme_out); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetItemAt); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetItemAt) -{ +XS(XS_Client_GetItemAt) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetItemAt(THIS, slot)"); + Perl_croak(aTHX_ "Usage: Client::GetItemAt(THIS, uint32 slot)"); { - Client * THIS; - EQEmu::ItemInstance * RETVAL; - uint32 slot = (int32)SvIV(ST(1)); + Client *THIS; + EQEmu::ItemInstance *RETVAL; + uint32 slot = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetInv().GetItem(slot); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "QuestItem", (void*)RETVAL); + sv_setref_pv(ST(0), "QuestItem", (void *) RETVAL); } XSRETURN(1); } XS(XS_Client_GetAugmentAt); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAugmentAt) -{ +XS(XS_Client_GetAugmentAt) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::GetAugmentAt(THIS, slot, aug_slot)"); + Perl_croak(aTHX_ "Usage: Client::GetAugmentAt(THIS, uint32 slot, uint32 aug_slot)"); { - Client * THIS; - EQEmu::ItemInstance * RETVAL; - uint32 slot = (int32)SvIV(ST(1)); - uint32 aug_slot = (int32)SvIV(ST(1)); + Client *THIS; + EQEmu::ItemInstance *RETVAL; + uint32 slot = (int32) SvIV(ST(1)); + uint32 aug_slot = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - EQEmu::ItemInstance * inst = THIS->GetInv().GetItem(slot); - if(inst) - { + EQEmu::ItemInstance *inst = THIS->GetInv().GetItem(slot); + if (inst) { RETVAL = inst->GetAugment(aug_slot); - } - else - { + } else { RETVAL = nullptr; } ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "QuestItem", (void*)RETVAL); + sv_setref_pv(ST(0), "QuestItem", (void *) RETVAL); } XSRETURN(1); } XS(XS_Client_GetStartZone); -XS(XS_Client_GetStartZone) -{ +XS(XS_Client_GetStartZone) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetStartZone(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetStartZone(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetStartZone); -XS(XS_Client_SetStartZone) -{ +XS(XS_Client_SetStartZone) { dXSARGS; if (items != 2 && items != 5) - Perl_croak(aTHX_ "Usage: Client::SetStartZone(THIS, zoneid [, x, y, z])"); + Perl_croak(aTHX_ + "Usage: Client::SetStartZone(THIS, uint32 zone_id, [float x = 0], [float y = 0], [float z = 0])"); { - Client * THIS; - uint32 zoneid = (uint32)SvUV(ST(1)); - float x = 0; - float y = 0; - float z = 0; + Client *THIS; + uint32 zoneid = (uint32) SvUV(ST(1)); + float x = 0; + float y = 0; + float z = 0; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items == 5) { + if (items == 5) { x = SvNV(ST(2)); y = SvNV(ST(3)); z = SvNV(ST(4)); } - THIS->SetStartZone(zoneid,x,y,z); + THIS->SetStartZone(zoneid, x, y, z); } XSRETURN_EMPTY; } XS(XS_Client_KeyRingAdd); -XS(XS_Client_KeyRingAdd) -{ +XS(XS_Client_KeyRingAdd) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::KeyRingAdd(THIS, item_id)"); + Perl_croak(aTHX_ "Usage: Client::KeyRingAdd(THIS, uint32 item_id)"); { - Client * THIS; - uint32 item_id = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 item_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->KeyRingAdd(item_id);; @@ -4472,49 +4225,45 @@ XS(XS_Client_KeyRingAdd) } XS(XS_Client_KeyRingCheck); -XS(XS_Client_KeyRingCheck) -{ +XS(XS_Client_KeyRingCheck) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::KeyRingCheck(THIS, item_id)"); + Perl_croak(aTHX_ "Usage: Client::KeyRingCheck(THIS, uint32 item_id)"); { - Client * THIS; - bool RETVAL; - uint32 item_id = (uint32)SvUV(ST(1)); + Client *THIS; + bool RETVAL; + uint32 item_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->KeyRingCheck(item_id);; - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_AddPVPPoints); -XS(XS_Client_AddPVPPoints) -{ +XS(XS_Client_AddPVPPoints) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::AddPVPPoints(THIS, Points)"); + Perl_croak(aTHX_ "Usage: Client::AddPVPPoints(THIS, uint32 points)"); { - Client * THIS; - uint32 Points = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 Points = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddPVPPoints(Points); @@ -4523,23 +4272,21 @@ XS(XS_Client_AddPVPPoints) } XS(XS_Client_AddCrystals); -XS(XS_Client_AddCrystals) -{ +XS(XS_Client_AddCrystals) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::AddCrystals(THIS, RadiantCount, EbonCount)"); + Perl_croak(aTHX_ "Usage: Client::AddCrystals(THIS, uint32 radiant_count, uint32 ebon_count)"); { - Client * THIS; - uint32 Radiant = (uint32)SvUV(ST(1)); - uint32 Ebon = (uint32)SvUV(ST(2)); + Client *THIS; + uint32 Radiant = (uint32) SvUV(ST(1)); + uint32 Ebon = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddCrystals(Radiant, Ebon); @@ -4548,126 +4295,119 @@ XS(XS_Client_AddCrystals) } XS(XS_Client_GetPVPPoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetPVPPoints) -{ +XS(XS_Client_GetPVPPoints) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetPVPPoints(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPVPPoints(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetRadiantCrystals); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetRadiantCrystals) -{ +XS(XS_Client_GetRadiantCrystals) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetRadiantCrystals(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRadiantCrystals(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetEbonCrystals); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetEbonCrystals) -{ +XS(XS_Client_GetEbonCrystals) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetEbonCrystals(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEbonCrystals(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_ReadBook); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ReadBook) -{ +XS(XS_Client_ReadBook) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::ReadBook(THIS, Book Text, Type)"); + Perl_croak(aTHX_ "Usage: Client::ReadBook(THIS, char* book_test, uint8 type)"); { - Client * THIS; - char* in_txt = (char *)SvPV_nolen(ST(1)); - uint8 type = (uint8)SvUV(ST(2)); + Client *THIS; + char *in_txt = (char *) SvPV_nolen(ST(1)); + uint8 type = (uint8) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->QuestReadBook(in_txt, type); + THIS->QuestReadBook(in_txt, type); } -XSRETURN_EMPTY; + XSRETURN_EMPTY; } XS(XS_Client_UpdateGroupAAs); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UpdateGroupAAs) -{ +XS(XS_Client_UpdateGroupAAs) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::UpdateGroupAAs(THIS, points, type)"); + Perl_croak(aTHX_ "Usage: Client::UpdateGroupAAs(THIS, int32 points, uint32 type)"); { - Client * THIS; - int32 points = (int32)SvIV(ST(1)); - uint32 type = (uint32)SvUV(ST(2)); + Client *THIS; + int32 points = (int32) SvIV(ST(1)); + uint32 type = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->UpdateGroupAAs(points, type); @@ -4676,74 +4416,70 @@ XS(XS_Client_UpdateGroupAAs) } XS(XS_Client_GetGroupPoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetGroupPoints) -{ +XS(XS_Client_GetGroupPoints) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetGroupPoints(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGroupPoints(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetRaidPoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetRaidPoints) -{ +XS(XS_Client_GetRaidPoints) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetRaidPoints(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRaidPoints(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_LearnRecipe); -XS(XS_Client_LearnRecipe) -{ +XS(XS_Client_LearnRecipe) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::LearnRecipe(THIS, recipe_id)"); + Perl_croak(aTHX_ "Usage: Client::LearnRecipe(THIS, uint32 recipe_id)"); { - Client * THIS; - uint32 recipe_id = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 recipe_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->LearnRecipe(recipe_id);; @@ -4752,100 +4488,95 @@ XS(XS_Client_LearnRecipe) } XS(XS_Client_GetEndurance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetEndurance) -{ +XS(XS_Client_GetEndurance) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetEndurance(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEndurance(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetMaxEndurance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetMaxEndurance) -{ +XS(XS_Client_GetMaxEndurance) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetMaxEndurance(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxEndurance(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetEnduranceRatio); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetEnduranceRatio) -{ +XS(XS_Client_GetEnduranceRatio) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetEnduranceRatio(THIS)"); { - Client * THIS; - uint8 RETVAL; + Client *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEndurancePercent(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_SetEndurance); -XS(XS_Client_SetEndurance) -{ +XS(XS_Client_SetEndurance) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Client::SetEndurance(THIS, Endurance)"); { - Client * THIS; - int32 Endurance = (int32)SvUV(ST(1)); + Client *THIS; + int32 Endurance = (int32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetEndurance(Endurance); @@ -4854,32 +4585,29 @@ XS(XS_Client_SetEndurance) } XS(XS_Client_SendOPTranslocateConfirm); -XS(XS_Client_SendOPTranslocateConfirm) -{ +XS(XS_Client_SendOPTranslocateConfirm) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SendOPTranslocateConfirm(THIS, Caster, SpellID)"); + Perl_croak(aTHX_ "Usage: Client::SendOPTranslocateConfirm(THIS, Mob* caster, int32 spell_id)"); { - Client * THIS; - Mob * caster = nullptr; - int32 spell_id = (int32)SvUV(ST(2)); + Client *THIS; + Mob *caster = nullptr; + int32 spell_id = (int32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); THIS->SendOPTranslocateConfirm(caster, spell_id); @@ -4888,37 +4616,34 @@ XS(XS_Client_SendOPTranslocateConfirm) } XS(XS_Client_NPCSpawn); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_NPCSpawn) -{ +XS(XS_Client_NPCSpawn) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Client::NPCSpawn(THIS, target_npc, option, respawntime=1200)"); + Perl_croak(aTHX_ "Usage: Client::NPCSpawn(THIS, NPC*, string option, uint32 respawn_time=1200)"); { - Client * THIS; - NPC * target_npc = nullptr; - Const_char * option = (Const_char *)SvPV_nolen(ST(2)); - uint32 respawntime = 1200; + Client *THIS; + NPC *target_npc = nullptr; + Const_char *option = (Const_char *) SvPV_nolen(ST(2)); + uint32 respawntime = 1200; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target_npc = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target_npc = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(target_npc == nullptr) + if (target_npc == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 3) - respawntime = (uint32)SvUV(ST(3)); + respawntime = (uint32) SvUV(ST(3)); THIS->NPCSpawn(target_npc, option, respawntime); } @@ -4926,53 +4651,50 @@ XS(XS_Client_NPCSpawn) } XS(XS_Client_GetIP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetIP) -{ +XS(XS_Client_GetIP) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetIP(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetIP(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_AddLevelBasedExp); -XS(XS_Client_AddLevelBasedExp) -{ +XS(XS_Client_AddLevelBasedExp) { dXSARGS; - if (items < 2 || items > 3 ) - Perl_croak(aTHX_ "Usage: Client::AddLevelBasedExp(THIS, exp_percentage, max_level=0)"); + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: Client::AddLevelBasedExp(THIS, uint8 exp_percentage, uint8 max_level = 0)"); { - Client * THIS; - uint8 exp_percentage = (uint8)SvUV(ST(1)); - uint8 max_level = 0; + Client *THIS; + uint8 exp_percentage = (uint8) SvUV(ST(1)); + uint8 max_level = 0; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 2) - max_level = (uint8)SvUV(ST(2)); + max_level = (uint8) SvUV(ST(2)); THIS->AddLevelBasedExp(exp_percentage, max_level); } @@ -4980,22 +4702,20 @@ XS(XS_Client_AddLevelBasedExp) } XS(XS_Client_IncrementAA); -XS(XS_Client_IncrementAA) -{ +XS(XS_Client_IncrementAA) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::IncrementAA(THIS, aaskillid)"); + Perl_croak(aTHX_ "Usage: Client::IncrementAA(THIS, uint32 aa_skill_id)"); { - Client * THIS; - uint32 aaskillid = SvUV(ST(1)); + Client *THIS; + uint32 aaskillid = SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->IncrementAlternateAdvancementRank(aaskillid); @@ -5004,197 +4724,188 @@ XS(XS_Client_IncrementAA) } XS(XS_Client_GrantAlternateAdvancementAbility); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GrantAlternateAdvancementAbility) -{ +XS(XS_Client_GrantAlternateAdvancementAbility) { dXSARGS; - if(items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Client::GrantAlternateAdvancementAbility(THIS, aa_id, points, [ignore_cost])"); + if (items < 3 || items > 4) + Perl_croak(aTHX_ + "Usage: Client::GrantAlternateAdvancementAbility(THIS, int aa_id, int points, [bool ignore_cost = false])"); { - Client * THIS; - bool RETVAL; - int aa_id = (int)SvIV(ST(1)); - int points = (int)SvIV(ST(2)); - bool ignore_cost = false; + Client *THIS; + bool RETVAL; + int aa_id = (int) SvIV(ST(1)); + int points = (int) SvIV(ST(2)); + bool ignore_cost = false; - if(sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Client *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items > 3) { - ignore_cost = (bool)SvTRUE(ST(3)); + if (items > 3) { + ignore_cost = (bool) SvTRUE(ST(3)); } RETVAL = THIS->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_GetAALevel); -XS(XS_Client_GetAALevel) -{ +XS(XS_Client_GetAALevel) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetAALevel(THIS, aaskillid)"); + Perl_croak(aTHX_ "Usage: Client::GetAALevel(THIS, uint32 aa_skill_id)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; - uint32 aaskillid = SvUV(ST(1)); + uint32 aaskillid = SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAA(aaskillid); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_MarkCompassLoc); -XS(XS_Client_MarkCompassLoc) -{ +XS(XS_Client_MarkCompassLoc) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Client::MarkCompassLoc(THIS, x, y, z)"); + Perl_croak(aTHX_ "Usage: Client::MarkCompassLoc(THIS, float x, float y, float z)"); { - Client * THIS; - float x = SvNV(ST(1)); - float y = SvNV(ST(2)); - float z = SvNV(ST(3)); + Client *THIS; + float x = SvNV(ST(1)); + float y = SvNV(ST(2)); + float z = SvNV(ST(3)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->MarkSingleCompassLoc(x,y,z); + THIS->MarkSingleCompassLoc(x, y, z); } XSRETURN_EMPTY; } XS(XS_Client_ClearCompassMark); -XS(XS_Client_ClearCompassMark) -{ +XS(XS_Client_ClearCompassMark) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::ClearCompassMark(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->MarkSingleCompassLoc(0,0,0,0); + THIS->MarkSingleCompassLoc(0, 0, 0, 0); } XSRETURN_EMPTY; } XS(XS_Client_GetFreeSpellBookSlot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetFreeSpellBookSlot) -{ +XS(XS_Client_GetFreeSpellBookSlot) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::GetFreeSpellBookSlot(THIS, start_slot=0)"); + Perl_croak(aTHX_ "Usage: Client::GetFreeSpellBookSlot(THIS, uint32 start_slot = 0)"); { - Client * THIS; - int RETVAL; - uint32 start_slot = 0; + Client *THIS; + int RETVAL; + uint32 start_slot = 0; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 1) start_slot = SvUV(ST(1)); RETVAL = THIS->GetNextAvailableSpellBookSlot(start_slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetSpellBookSlotBySpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetSpellBookSlotBySpellID) -{ +XS(XS_Client_GetSpellBookSlotBySpellID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetSpellBookSlotBySpellID(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Client::GetSpellBookSlotBySpellID(THIS, uint32 spell_id)"); { - Client * THIS; - int RETVAL; - uint32 spell_id = SvUV(ST(1)); + Client *THIS; + int RETVAL; + uint32 spell_id = SvUV(ST(1)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->FindSpellBookSlotBySpellID(spell_id); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_UpdateTaskActivity); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_UpdateTaskActivity) -{ +XS(XS_Client_UpdateTaskActivity) { dXSARGS; if (items < 4) - Perl_croak(aTHX_ "Usage: Client::UpdateTaskActivity(THIS, TaskID, ActivityID, Count, [ignore_quest_update])"); + Perl_croak(aTHX_ + "Usage: Client::UpdateTaskActivity(THIS, int task_id, int activity_id, int count, [bool ignore_quest_update = false])"); { bool ignore_quest_update = false; - Client * THIS; + Client *THIS; - int TaskID = (int)SvIV(ST(1)); - int ActivityID = (int)SvIV(ST(2)); - int Count = (int)SvUV(ST(3)); + int TaskID = (int) SvIV(ST(1)); + int ActivityID = (int) SvIV(ST(2)); + int Count = (int) SvUV(ST(3)); - if (items == 5){ - ignore_quest_update = (bool)SvTRUE(ST(4)); + if (items == 5) { + ignore_quest_update = (bool) SvTRUE(ST(4)); } if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->UpdateTaskActivity(TaskID, ActivityID, Count, ignore_quest_update); @@ -5203,59 +4914,55 @@ XS(XS_Client_UpdateTaskActivity) } XS(XS_Client_GetTaskActivityDoneCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetTaskActivityDoneCount) -{ +XS(XS_Client_GetTaskActivityDoneCount) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::GetTaskActivityDoneCount(THIS, TaskID, ActivityID)"); + Perl_croak(aTHX_ "Usage: Client::GetTaskActivityDoneCount(THIS, int task_id, int activity_id)"); { - Client * THIS; - int RETVAL; - int TaskID = (int)SvIV(ST(1)); - int ActivityID = (int)SvIV(ST(2)); + Client *THIS; + int RETVAL; + int TaskID = (int) SvIV(ST(1)); + int ActivityID = (int) SvIV(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Client *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Client"); if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTaskActivityDoneCountFromTaskID(TaskID, ActivityID); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_AssignTask); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AssignTask) -{ +XS(XS_Client_AssignTask) { dXSARGS; if (items != 3 && items != 4) - Perl_croak(aTHX_ "Usage: Client::AssignTask(THIS, TaskID, NPCID, enforce_level_requirement)"); + Perl_croak(aTHX_ + "Usage: Client::AssignTask(THIS, int task_id, int npc_id, [bool enforce_level_requirement = false])"); { - Client * THIS; - int TaskID = (int)SvIV(ST(1)); - int NPCID = (int)SvIV(ST(2)); - bool enforce_level_requirement = false; - if (items == 4) - { - if ((int)SvIV(ST(3)) == 1) - { + Client *THIS; + int TaskID = (int) SvIV(ST(1)); + int NPCID = (int) SvIV(ST(2)); + bool enforce_level_requirement = false; + if (items == 4) { + if ((int) SvIV(ST(3)) == 1) { enforce_level_requirement = true; } } if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AssignTask(TaskID, NPCID, enforce_level_requirement); @@ -5264,22 +4971,20 @@ XS(XS_Client_AssignTask) } XS(XS_Client_FailTask); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_FailTask) -{ +XS(XS_Client_FailTask) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::FailTask(THIS, TaskID)"); + Perl_croak(aTHX_ "Usage: Client::FailTask(THIS, int task_id)"); { - Client * THIS; - int TaskID = (int)SvIV(ST(1)); + Client *THIS; + int TaskID = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->FailTask(TaskID); @@ -5288,185 +4993,174 @@ XS(XS_Client_FailTask) } XS(XS_Client_IsTaskCompleted); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsTaskCompleted) -{ +XS(XS_Client_IsTaskCompleted) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::IsTaskCompleted(THIS, TaskID)"); + Perl_croak(aTHX_ "Usage: Client::IsTaskCompleted(THIS, int task_id)"); { - Client * THIS; - int RETVAL; - int TaskID = (int)SvIV(ST(1)); + Client *THIS; + int RETVAL; + int TaskID = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsTaskCompleted(TaskID); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_IsTaskActive); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsTaskActive) -{ +XS(XS_Client_IsTaskActive) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::IsTaskActive(THIS, TaskID)"); + Perl_croak(aTHX_ "Usage: Client::IsTaskActive(THIS, int task_id)"); { - Client * THIS; - bool RETVAL; - int TaskID = (int)SvIV(ST(1)); + Client *THIS; + bool RETVAL; + int TaskID = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsTaskActive(TaskID); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_IsTaskActivityActive); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_IsTaskActivityActive) -{ +XS(XS_Client_IsTaskActivityActive) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::IsTaskActivityActive(THIS, TaskID, ActivityID)"); + Perl_croak(aTHX_ "Usage: Client::IsTaskActivityActive(THIS, int task_id, int activity_id)"); { - Client * THIS; - bool RETVAL; - int TaskID = (int)SvIV(ST(1)); - int ActivityID = (int)SvIV(ST(2)); + Client *THIS; + bool RETVAL; + int TaskID = (int) SvIV(ST(1)); + int ActivityID = (int) SvIV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsTaskActivityActive(TaskID, ActivityID); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Client_GetCorpseCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetCorpseCount) -{ +XS(XS_Client_GetCorpseCount) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetCorpseCount(THIS)"); { - Client * THIS; - uint32 RETVAL; + Client *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseCount(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetCorpseID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetCorpseID) -{ +XS(XS_Client_GetCorpseID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetCorpseID(THIS, corpse)"); + Perl_croak(aTHX_ "Usage: Client::GetCorpseID(THIS, uint8 corpse)"); { - Client * THIS; - uint8 corpse = (uint8)SvIV(ST(1)); - uint32 RETVAL; + Client *THIS; + uint8 corpse = (uint8) SvIV(ST(1)); + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseID(corpse); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetCorpseItemAt); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetCorpseItemAt) -{ +XS(XS_Client_GetCorpseItemAt) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::GetCorpseItemAt(THIS, corpse_id, slotid)"); + Perl_croak(aTHX_ "Usage: Client::GetCorpseItemAt(THIS, uint32 corpse_id, uint16 slot_id)"); { - Client * THIS; - uint32 corpse_id = (uint32)SvIV(ST(1)); - uint16 slotid = (uint16)SvIV(ST(2)); - uint32 RETVAL; + Client *THIS; + uint32 corpse_id = (uint32) SvIV(ST(1)); + uint16 slotid = (uint16) SvIV(ST(2)); + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseItemAt(corpse_id, slotid); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_AssignToInstance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AssignToInstance) -{ +XS(XS_Client_AssignToInstance) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::AssignToInstance(THIS, instance_id)"); + Perl_croak(aTHX_ "Usage: Client::AssignToInstance(THIS, uint16 instance_id)"); { - Client * THIS; - uint16 instance_id = (uint16)SvUV(ST(1)); + Client *THIS; + uint16 instance_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AssignToInstance(instance_id); @@ -5475,20 +5169,18 @@ XS(XS_Client_AssignToInstance) } XS(XS_Client_RemoveFromInstance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_RemoveFromInstance) -{ +XS(XS_Client_RemoveFromInstance) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::RemoveFromInstance(THIS, instance_id)"); + Perl_croak(aTHX_ "Usage: Client::RemoveFromInstance(THIS, uint16 instance_id)"); { - Client * THIS; - uint16 instance_id = (uint16)SvUV(ST(1)); + Client *THIS; + uint16 instance_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Client *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Client"); if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); @@ -5499,21 +5191,19 @@ XS(XS_Client_RemoveFromInstance) } XS(XS_Client_Freeze); -XS(XS_Client_Freeze) -{ +XS(XS_Client_Freeze) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client:Freeze(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendAppearancePacket(AT_Anim, ANIM_FREEZE); @@ -5522,21 +5212,19 @@ XS(XS_Client_Freeze) } XS(XS_Client_UnFreeze); -XS(XS_Client_UnFreeze) -{ +XS(XS_Client_UnFreeze) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client:UnFreeze(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendAppearancePacket(AT_Anim, ANIM_STAND); @@ -5546,132 +5234,125 @@ XS(XS_Client_UnFreeze) XS(XS_Client_GetAggroCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAggroCount) -{ +XS(XS_Client_GetAggroCount) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetAggroCount(THIS)"); { - Client * THIS; - int RETVAL; + Client *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAggroCount(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetCarriedMoney); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetCarriedMoney) -{ +XS(XS_Client_GetCarriedMoney) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetCarriedMoney(THIS)"); { - Client * THIS; - int RETVAL; + Client *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCarriedMoney(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetAllMoney); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAllMoney) -{ +XS(XS_Client_GetAllMoney) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetAllMoney(THIS)"); { - Client * THIS; - int RETVAL; + Client *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAllMoney(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_GetItemInInventory); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetItemInInventory) -{ +XS(XS_Client_GetItemInInventory) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetItemInInventory(THIS, slot_id)"); + Perl_croak(aTHX_ "Usage: Client::GetItemInInventory(THIS, int16 slot_id)"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); - EQEmu::ItemInstance *RETVAL = nullptr; + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + EQEmu::ItemInstance *RETVAL = nullptr; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetInv().GetItem(slot_id); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "QuestItem", (void*)RETVAL); + sv_setref_pv(ST(0), "QuestItem", (void *) RETVAL); } XSRETURN(1); } XS(XS_Client_SetCustomItemData); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetCustomItemData) -{ +XS(XS_Client_SetCustomItemData) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Client::SetCustomItemData(THIS, slot_id, identifier, value)"); + Perl_croak(aTHX_ "Usage: Client::SetCustomItemData(THIS, int16 slot_id, string identifier, string value)"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); - Const_char* identifier = SvPV_nolen(ST(2)); - Const_char* value = SvPV_nolen(ST(3)); + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + Const_char *identifier = SvPV_nolen(ST(2)); + Const_char *value = SvPV_nolen(ST(3)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->GetInv().SetCustomItemData(THIS->CharacterID(), slot_id, std::string(identifier), std::string(value)); @@ -5680,50 +5361,48 @@ XS(XS_Client_SetCustomItemData) } XS(XS_Client_GetCustomItemData); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetCustomItemData) -{ +XS(XS_Client_GetCustomItemData) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::GetCustomItemData(THIS, slot_id, identifier)"); + Perl_croak(aTHX_ "Usage: Client::GetCustomItemData(THIS, int16 slot_id, string identifier)"); { - Client * THIS; - int16 slot_id = (int16)SvIV(ST(1)); - Const_char* identifier = SvPV_nolen(ST(2)); - Const_char * RETVAL; + Client *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + Const_char *identifier = SvPV_nolen(ST(2)); + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); std::string ret_val = THIS->GetInv().GetCustomItemData(slot_id, std::string(identifier)); RETVAL = ret_val.c_str(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Client_OpenLFGuildWindow); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_OpenLFGuildWindow) -{ +XS(XS_Client_OpenLFGuildWindow) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::OpenLFGuildWindow(THIS)"); { - Client * THIS; + Client *THIS; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->OpenLFGuildWindow(); @@ -5732,22 +5411,20 @@ XS(XS_Client_OpenLFGuildWindow) } XS(XS_Client_SignalClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SignalClient) -{ +XS(XS_Client_SignalClient) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SignalClient(THIS, data)"); + Perl_croak(aTHX_ "Usage: Client::SignalClient(THIS, uint32 data)"); { - Client * THIS; - uint32 data = (uint32)SvUV(ST(1)); + Client *THIS; + uint32 data = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Signal(data); @@ -5756,23 +5433,21 @@ XS(XS_Client_SignalClient) } XS(XS_Client_AddAlternateCurrencyValue); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_AddAlternateCurrencyValue) -{ +XS(XS_Client_AddAlternateCurrencyValue) { dXSARGS; if (items != 3) Perl_croak(aTHX_ "Usage: Client::AddAlternateCurrencyValue(THIS, uint32 currency_id, int32 amount)"); { - Client * THIS; - uint32 currency_id = (uint32)SvUV(ST(1)); - int32 amount = (int32)SvUV(ST(2)); + Client *THIS; + uint32 currency_id = (uint32) SvUV(ST(1)); + int32 amount = (int32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddAlternateCurrencyValue(currency_id, amount); @@ -5781,25 +5456,23 @@ XS(XS_Client_AddAlternateCurrencyValue) } XS(XS_Client_SendWebLink); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendWebLink) -{ +XS(XS_Client_SendWebLink) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::SendWebLink(THIS, website)"); + Perl_croak(aTHX_ "Usage: Client::SendWebLink(THIS, string website_url)"); { - Client * THIS; - char * website = nullptr; + Client *THIS; + char *website = nullptr; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { website = (char *)SvPV_nolen(ST(1)); } + if (items > 1) { website = (char *) SvPV_nolen(ST(1)); } THIS->SendWebLink(website); } @@ -5807,316 +5480,298 @@ XS(XS_Client_SendWebLink) } XS(XS_Client_GetInstanceID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetInstanceID) -{ +XS(XS_Client_GetInstanceID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Client::GetInstanceID(THIS)"); { - Client * THIS; - int8 RETVAL; + Client *THIS; + int8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetInstanceID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Client_HasSpellScribed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_HasSpellScribed) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::HasSpellScribed(THIS, spell_id)"); - { - Client * THIS; - bool RETVAL; - int spell_id = (int)SvUV(ST(1)); +XS(XS_Client_HasSpellScribed) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::HasSpellScribed(THIS, int spell_id)"); + { + Client *THIS; + bool RETVAL; + int spell_id = (int) SvUV(ST(1)); - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) - Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - RETVAL = THIS->HasSpellScribed(spell_id); - ST(0) = boolSV(RETVAL); - sv_2mortal(ST(0)); - } - XSRETURN(1); + RETVAL = THIS->HasSpellScribed(spell_id); + ST(0) = boolSV(RETVAL); + sv_2mortal(ST(0)); + } + XSRETURN(1); } XS(XS_Client_SetAccountFlag); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetAccountFlag) -{ - dXSARGS; - if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetAccountFlag(THIS, flag, value)"); - { - Client * THIS; - //char* flag = (char *)SvPV_nolen(ST(1)); - //char* value = (char *)SvTRUE(ST(2)); +XS(XS_Client_SetAccountFlag) { + dXSARGS; + if (items != 3) + Perl_croak(aTHX_ "Usage: Client::SetAccountFlag(THIS, string flag, string value)"); + { + Client *THIS; + //char* flag = (char *)SvPV_nolen(ST(1)); + //char* value = (char *)SvTRUE(ST(2)); - std::string flag( (char *)SvPV_nolen(ST(1)) ); - std::string value( (char *)SvTRUE(ST(2)) ); + std::string flag((char *) SvPV_nolen(ST(1))); + std::string value((char *) SvTRUE(ST(2))); - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) - Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - THIS->SetAccountFlag(flag, value); - } - XSRETURN_EMPTY; + THIS->SetAccountFlag(flag, value); + } + XSRETURN_EMPTY; } XS(XS_Client_GetAccountFlag); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetAccountFlag) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::GetAccountFlag(THIS, flag)"); - { - Client * THIS; - //char* flag = (char *)SvPV_nolen(ST(1)); - //char* value = (char *)SvTRUE(ST(2)); +XS(XS_Client_GetAccountFlag) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::GetAccountFlag(THIS, string flag)"); + { + Client *THIS; + //char* flag = (char *)SvPV_nolen(ST(1)); + //char* value = (char *)SvTRUE(ST(2)); - std::string flag( (char *)SvPV_nolen(ST(1)) ); - dXSTARG; + std::string flag((char *) SvPV_nolen(ST(1))); + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) - Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - std::string value = THIS->GetAccountFlag(flag); + std::string value = THIS->GetAccountFlag(flag); - sv_setpv(TARG, value.c_str()); XSprePUSH; PUSHTARG; - } - XSRETURN(1); + sv_setpv(TARG, value.c_str()); + XSprePUSH; + PUSHTARG; + } + XSRETURN(1); } XS(XS_Client_GetHunger); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetHunger) -{ +XS(XS_Client_GetHunger) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: Client::GetHunger(THIS)"); - { - Client * THIS; - int32 RETVAL; - dXSTARG; + Perl_croak(aTHX_ "Usage: Client::GetHunger(THIS)"); + { + Client *THIS; + int32 RETVAL; + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetHunger(); - XSprePUSH; PUSHi((IV)RETVAL); - } - XSRETURN(1); + RETVAL = THIS->GetHunger(); + XSprePUSH; + PUSHi((IV) RETVAL); + } + XSRETURN(1); } XS(XS_Client_GetThirst); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetThirst) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: Client::GetThirst(THIS)"); - { - Client * THIS; - int32 RETVAL; - dXSTARG; +XS(XS_Client_GetThirst) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetThirst(THIS)"); + { + Client *THIS; + int32 RETVAL; + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetThirst(); - XSprePUSH; PUSHi((IV)RETVAL); - } - XSRETURN(1); + RETVAL = THIS->GetThirst(); + XSprePUSH; + PUSHi((IV) RETVAL); + } + XSRETURN(1); } XS(XS_Client_SetHunger); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetHunger) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetHunger(THIS, in_hunger)"); - { - Client * THIS; - int32 in_hunger = (uint32)SvUV(ST(1)); +XS(XS_Client_SetHunger) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::SetHunger(THIS, in_hunger)"); + { + Client *THIS; + int32 in_hunger = (uint32) SvUV(ST(1)); - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetHunger(in_hunger); - } - XSRETURN_EMPTY; + THIS->SetHunger(in_hunger); + } + XSRETURN_EMPTY; } XS(XS_Client_SetThirst); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetThirst) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SetThirst(THIS, in_thirst)"); - { - Client * THIS; - int32 in_thirst = (uint32)SvUV(ST(1)); +XS(XS_Client_SetThirst) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::SetThirst(THIS, int32 in_thirst)"); + { + Client *THIS; + int32 in_thirst = (uint32) SvUV(ST(1)); - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetThirst(in_thirst); - } - XSRETURN_EMPTY; + THIS->SetThirst(in_thirst); + } + XSRETURN_EMPTY; } XS(XS_Client_SendTargetCommand); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendTargetCommand) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SendTargetCommand(THIS, in_entid)"); - { - Client * THIS; - int32 in_entid = (uint32)SvUV(ST(1)); +XS(XS_Client_SendTargetCommand) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::SendTargetCommand(THIS, int32 entity_id)"); + { + Client *THIS; + int32 in_entid = (uint32) SvUV(ST(1)); - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SendTargetCommand(in_entid); - } - XSRETURN_EMPTY; + THIS->SendTargetCommand(in_entid); + } + XSRETURN_EMPTY; } XS(XS_Client_SetConsumption); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SetConsumption) -{ - dXSARGS; - if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SetHunger(THIS, in_hunger, in_thirst)"); - { - Client * THIS; - int32 in_hunger = (uint32)SvUV(ST(1)); - int32 in_thirst = (uint32)SvUV(ST(2)); +XS(XS_Client_SetConsumption) { + dXSARGS; + if (items != 3) + Perl_croak(aTHX_ "Usage: Client::SetHunger(THIS, int32 hunger_amount, int32 thirst_amount)"); + { + Client *THIS; + int32 in_hunger = (uint32) SvUV(ST(1)); + int32 in_thirst = (uint32) SvUV(ST(2)); - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetConsumption(in_hunger, in_thirst); - } - XSRETURN_EMPTY; + THIS->SetConsumption(in_hunger, in_thirst); + } + XSRETURN_EMPTY; } XS(XS_Client_SilentMessage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SilentMessage) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::SilentMessage(THIS, Message)"); - { - Client * THIS; - dXSTARG; +XS(XS_Client_SilentMessage) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::SilentMessage(THIS, string message)"); + { + Client *THIS; + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) - Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - if(THIS->GetTarget() != NULL){ - if(THIS->GetTarget()->IsNPC()){ - if (DistanceSquaredNoZ(THIS->GetPosition(), THIS->GetTarget()->GetPosition()) <= 200) { - if(THIS->GetTarget()->CastToNPC()->IsMoving() && !THIS->GetTarget()->CastToNPC()->IsOnHatelist(THIS->GetTarget())) - THIS->GetTarget()->CastToNPC()->PauseWandering(RuleI(NPC, SayPauseTimeInSec)); - THIS->ChannelMessageReceived(8, 0, 100, SvPV_nolen(ST(1))); - } - } - } - } - XSRETURN_EMPTY; + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + if (THIS->GetTarget() != NULL) { + if (THIS->GetTarget()->IsNPC()) { + if (DistanceSquaredNoZ(THIS->GetPosition(), THIS->GetTarget()->GetPosition()) <= 200) { + if (THIS->GetTarget()->CastToNPC()->IsMoving() && + !THIS->GetTarget()->CastToNPC()->IsOnHatelist(THIS->GetTarget())) + THIS->GetTarget()->CastToNPC()->PauseWandering(RuleI(NPC, SayPauseTimeInSec)); + THIS->ChannelMessageReceived(8, 0, 100, SvPV_nolen(ST(1))); + } + } + } + } + XSRETURN_EMPTY; } XS(XS_Client_PlayMP3); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_PlayMP3) -{ +XS(XS_Client_PlayMP3) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Client::PlayMP3(THIS, fname)"); + Perl_croak(aTHX_ "Usage: Client::PlayMP3(THIS, string file_name)"); { - Client * THIS; - char * fname = nullptr; + Client *THIS; + char *fname = nullptr; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { fname = (char *)SvPV_nolen(ST(1)); } + if (items > 1) { fname = (char *) SvPV_nolen(ST(1)); } THIS->PlayMP3(fname); } @@ -6124,24 +5779,22 @@ XS(XS_Client_PlayMP3) } XS(XS_Client_ExpeditionMessage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_ExpeditionMessage) -{ +XS(XS_Client_ExpeditionMessage) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::ExpeditionMessage(THIS, ExpdID, Message)"); + Perl_croak(aTHX_ "Usage: Client::ExpeditionMessage(THIS, int expedition_id, string message)"); { - Client * THIS; - int ExpdID = (int)SvUV(ST(1)); - const char * Message = (const char *)SvPV_nolen(ST(2)); + Client *THIS; + int ExpdID = (int) SvUV(ST(1)); + const char *Message = (const char *) SvPV_nolen(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->ExpeditionSay(Message, ExpdID); @@ -6152,28 +5805,27 @@ XS(XS_Client_ExpeditionMessage) //Client::SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string msg) XS(XS_Client_SendMarqueeMessage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendMarqueeMessage) -{ +XS(XS_Client_SendMarqueeMessage) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Client::SendMarqueeMessage(THIS, type, priority, fade_in, fade_out, duration, msg)"); + Perl_croak(aTHX_ + "Usage: Client::SendMarqueeMessage(THIS, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, string msg)"); { - Client * THIS; - uint32 type = (uint32)SvUV(ST(1)); - uint32 priority = (uint32)SvUV(ST(2)); - uint32 fade_in = (uint32)SvUV(ST(3)); - uint32 fade_out = (uint32)SvUV(ST(4)); - uint32 duration = (uint32)SvUV(ST(5)); - std::string msg = (std::string)SvPV_nolen(ST(6)); + Client *THIS; + uint32 type = (uint32) SvUV(ST(1)); + uint32 priority = (uint32) SvUV(ST(2)); + uint32 fade_in = (uint32) SvUV(ST(3)); + uint32 fade_out = (uint32) SvUV(ST(4)); + uint32 duration = (uint32) SvUV(ST(5)); + std::string msg = (std::string) SvPV_nolen(ST(6)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->SendMarqueeMessage(type, priority, fade_in, fade_out, duration, msg); @@ -6182,24 +5834,22 @@ XS(XS_Client_SendMarqueeMessage) } XS(XS_Client_SendColoredText); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendColoredText) -{ +XS(XS_Client_SendColoredText) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Client::SendColoredText(color, message)"); + Perl_croak(aTHX_ "Usage: Client::SendColoredText(uint32 color, string message)"); { - Client * THIS; - uint32 color = (uint32)SvUV(ST(1)); - std::string msg = (std::string)SvPV_nolen(ST(2)); + Client *THIS; + uint32 color = (uint32) SvUV(ST(1)); + std::string msg = (std::string) SvPV_nolen(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->SendColoredText(color, msg); @@ -6208,181 +5858,173 @@ XS(XS_Client_SendColoredText) } XS(XS_Client_SendSpellAnim); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_SendSpellAnim) -{ +XS(XS_Client_SendSpellAnim) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: SendSpellAnim(uint16 spell_id, uint32 seq)"); + Perl_croak(aTHX_ "Usage: SendSpellAnim(uint16 target_id, uint32 spell_animation_id)"); { - Client * THIS; - uint16 targetid = (uint16)SvUV(ST(1)); - uint16 spell_id = (uint16)SvUV(ST(2)); + Client *THIS; + uint16 targetid = (uint16) SvUV(ST(1)); + uint16 spell_id = (uint16) SvUV(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - THIS->SendSpellAnim(targetid,spell_id); + THIS->SendSpellAnim(targetid, spell_id); } XSRETURN_EMPTY; } XS(XS_Client_GetTargetRingX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetTargetRingX) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: Client::GetTargetRingX(THIS)"); - { - Client * THIS; - float RETVAL; - dXSTARG; +XS(XS_Client_GetTargetRingX) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetTargetRingX(THIS)"); + { + Client *THIS; + float RETVAL; + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTargetRingX(); - XSprePUSH; PUSHn((double)RETVAL); - } - XSRETURN(1); + XSprePUSH; + PUSHn((double) RETVAL); + } + XSRETURN(1); } XS(XS_Client_GetTargetRingY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetTargetRingY) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: Client::GetTargetRingY(THIS)"); - { - Client * THIS; - float RETVAL; - dXSTARG; +XS(XS_Client_GetTargetRingY) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetTargetRingY(THIS)"); + { + Client *THIS; + float RETVAL; + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTargetRingY(); - XSprePUSH; PUSHn((double)RETVAL); - } - XSRETURN(1); + XSprePUSH; + PUSHn((double) RETVAL); + } + XSRETURN(1); } XS(XS_Client_GetTargetRingZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_GetTargetRingZ) -{ - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: Client::GetTargetRingZ(THIS)"); - { - Client * THIS; - float RETVAL; - dXSTARG; +XS(XS_Client_GetTargetRingZ) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetTargetRingZ(THIS)"); + { + Client *THIS; + float RETVAL; + dXSTARG; - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTargetRingZ(); - XSprePUSH; PUSHn((double)RETVAL); - } - XSRETURN(1); + XSprePUSH; + PUSHn((double) RETVAL); + } + XSRETURN(1); } XS(XS_Client_CalcEXP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_CalcEXP) -{ +XS(XS_Client_CalcEXP) { dXSARGS; if (items < 1 || items > 2) Perl_croak(aTHX_ "Usage: CalcEXP(THIS, uint8 conlevel)"); { - Client * THIS; - uint8 conlevel = 0xFF; + Client *THIS; + uint8 conlevel = 0xFF; uint32 RETVAL; - if(items == 2) - conlevel = (uint16)SvUV(ST(1)); + if (items == 2) + conlevel = (uint16) SvUV(ST(1)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); RETVAL = THIS->CalcEXP(conlevel); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Client_QuestReward); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_QuestReward) -{ +XS(XS_Client_QuestReward) { dXSARGS; if (items < 1 || items > 9) - Perl_croak(aTHX_ "Usage: Client::QuestReward(THIS, mob, copper, silver, gold, platinum, itemid, exp, faction)"); + Perl_croak(aTHX_ + "Usage: Client::QuestReward(THIS, int32 mob, int32 copper, int32 silver, int32 gold, int32 platinum, int32 item_id, int32 exp, [bool faction = false])"); { - Client* THIS; - Mob * mob = nullptr; - int32 copper = 0; - int32 silver = 0; - int32 gold = 0; - int32 platinum = 0; - int32 itemid = 0; - int32 exp = 0; - bool faction = false; + Client *THIS; + Mob *mob = nullptr; + int32 copper = 0; + int32 silver = 0; + int32 gold = 0; + int32 platinum = 0; + int32 itemid = 0; + int32 exp = 0; + bool faction = false; if (sv_derived_from(ST(0), "THIS")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Client *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type client"); if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { + if (items > 1) { if (sv_derived_from(ST(1), "mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); + IV tmp = SvIV((SV *) SvRV(ST(1))); mob = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "mob is not of type Mob"); if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); } - if (items > 2) { copper = (int32)SvIV(ST(2)); } - if (items > 3) { silver = (int32)SvIV(ST(3)); } - if (items > 4) { gold = (int32)SvIV(ST(4)); } - if (items > 5) { platinum = (int32)SvIV(ST(5)); } - if (items > 6) { itemid = (int32)SvIV(ST(6)); } - if (items > 7) { exp = (int32)SvIV(ST(7)); } - if (items > 8) { faction = (bool)SvIV(ST(8)); } + if (items > 2) { copper = (int32) SvIV(ST(2)); } + if (items > 3) { silver = (int32) SvIV(ST(3)); } + if (items > 4) { gold = (int32) SvIV(ST(4)); } + if (items > 5) { platinum = (int32) SvIV(ST(5)); } + if (items > 6) { itemid = (int32) SvIV(ST(6)); } + if (items > 7) { exp = (int32) SvIV(ST(7)); } + if (items > 8) { faction = (bool) SvIV(ST(8)); } THIS->QuestReward(mob, copper, silver, gold, platinum, itemid, exp, faction); } @@ -6390,30 +6032,29 @@ XS(XS_Client_QuestReward) } XS(XS_Client_GetMoney); -XS(XS_Client_GetMoney) -{ +XS(XS_Client_GetMoney) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: GetMoney(THIS, type, subtype)"); + Perl_croak(aTHX_ "Usage: GetMoney(THIS, int8 type, int8 subtype)"); { - Client* THIS; + Client *THIS; uint32 RETVAL; - uint8 type = (uint8)SvUV(ST(1)); - uint8 subtype = (uint8)SvUV(ST(2)); + uint8 type = (uint8) SvUV(ST(1)); + uint8 subtype = (uint8) SvUV(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - - if(THIS == nullptr) + + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMoney(type, subtype); - XSprePUSH; PUSHn((uint32)RETVAL); + XSprePUSH; + PUSHn((uint32) RETVAL); } XSRETURN(1); } @@ -6424,63 +6065,63 @@ XS(XS_Client_GetAccountAge) { if (items != 1) Perl_croak(aTHX_ "Usage: GetAccountAge(THIS)"); { - Client* THIS; + Client *THIS; int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - - if(THIS == nullptr) + + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAccountAge(); - XSprePUSH; PUSHn((int)RETVAL); + XSprePUSH; + PUSHn((int) RETVAL); } XSRETURN(1); } XS(XS_Client_Popup2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_Popup2) -{ +XS(XS_Client_Popup2) { dXSARGS; if (items < 3 || items > 10) - Perl_croak(aTHX_ "Usage: Client::SendFullPopup(THIS, Title, Text, PopupID, NegativeID, Buttons, Duration, ButtonName0, ButtonName1, SoundControls)"); + Perl_croak(aTHX_ + "Usage: Client::SendFullPopup(THIS, string title, string text, uint32 popup_id, uint32 negative_id, uint32 buttons, uint32 duration, string button_name_0, string button_name_1, uint32 sound_controls)"); { - Client * THIS; - char* Title = (char *)SvPV_nolen(ST(1)); - char* Text = (char *)SvPV_nolen(ST(2)); - uint32 PopupID = 0; - uint32 NegativeID = 0; - uint32 Buttons = 0; - uint32 Duration = 0; - char* ButtonName0 = 0; - char* ButtonName1 = 0; - uint32 SoundControls = 0; + Client *THIS; + char *Title = (char *) SvPV_nolen(ST(1)); + char *Text = (char *) SvPV_nolen(ST(2)); + uint32 PopupID = 0; + uint32 NegativeID = 0; + uint32 Buttons = 0; + uint32 Duration = 0; + char *ButtonName0 = 0; + char *ButtonName1 = 0; + uint32 SoundControls = 0; if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - if (items > 3) { PopupID = (uint32)SvUV(ST(3)); } - if (items > 4) { NegativeID = (uint32)SvUV(ST(4)); } - if (items > 5) { Buttons = (uint32)SvUV(ST(5)); } - if (items > 6) { Duration = (uint32)SvUV(ST(6)); } - if (items > 7) { ButtonName0 = (char *)SvPV_nolen(ST(7)); } - if (items > 8) { ButtonName1 = (char *)SvPV_nolen(ST(8)); } - if (items > 9) { SoundControls = (uint32)SvUV(ST(9)); } + + if (items > 3) { PopupID = (uint32) SvUV(ST(3)); } + if (items > 4) { NegativeID = (uint32) SvUV(ST(4)); } + if (items > 5) { Buttons = (uint32) SvUV(ST(5)); } + if (items > 6) { Duration = (uint32) SvUV(ST(6)); } + if (items > 7) { ButtonName0 = (char *) SvPV_nolen(ST(7)); } + if (items > 8) { ButtonName1 = (char *) SvPV_nolen(ST(8)); } + if (items > 9) { SoundControls = (uint32) SvUV(ST(9)); } - THIS->SendFullPopup(Title, Text, PopupID, NegativeID, Buttons, Duration, ButtonName0, ButtonName1, SoundControls); + THIS->SendFullPopup(Title, Text, PopupID, NegativeID, Buttons, Duration, ButtonName0, ButtonName1, + SoundControls); } XSRETURN_EMPTY; } @@ -6490,14 +6131,13 @@ XS(XS_Client_Popup2) extern "C" #endif XS(boot_Client); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Client) -{ +XS(boot_Client) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; @@ -6505,242 +6145,243 @@ XS(boot_Client) - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "SendSound"), XS_Client_SendSound, file, "$"); - newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$"); - newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$"); - newXSproto(strcpy(buf, "Connected"), XS_Client_Connected, file, "$"); - newXSproto(strcpy(buf, "InZone"), XS_Client_InZone, file, "$"); - newXSproto(strcpy(buf, "Kick"), XS_Client_Kick, file, "$"); - newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$"); - newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$"); - newXSproto(strcpy(buf, "WorldKick"), XS_Client_WorldKick, file, "$"); - newXSproto(strcpy(buf, "GetAnon"), XS_Client_GetAnon, file, "$"); - newXSproto(strcpy(buf, "Duck"), XS_Client_Duck, file, "$"); - newXSproto(strcpy(buf, "Stand"), XS_Client_Stand, file, "$"); - newXSproto(strcpy(buf, "SetGM"), XS_Client_SetGM, file, "$$"); - newXSproto(strcpy(buf, "SetPVP"), XS_Client_SetPVP, file, "$$"); - newXSproto(strcpy(buf, "GetPVP"), XS_Client_GetPVP, file, "$"); - newXSproto(strcpy(buf, "GetGM"), XS_Client_GetGM, file, "$"); - newXSproto(strcpy(buf, "SetBaseClass"), XS_Client_SetBaseClass, file, "$$"); - newXSproto(strcpy(buf, "SetBaseRace"), XS_Client_SetBaseRace, file, "$$"); - newXSproto(strcpy(buf, "SetBaseGender"), XS_Client_SetBaseGender, file, "$$"); - newXSproto(strcpy(buf, "GetBaseFace"), XS_Client_GetBaseFace, file, "$"); - newXSproto(strcpy(buf, "GetLanguageSkill"), XS_Client_GetLanguageSkill, file, "$$"); - newXSproto(strcpy(buf, "GetLastName"), XS_Client_GetLastName, file, "$"); - newXSproto(strcpy(buf, "GetLDoNPointsTheme"), XS_Client_GetLDoNPointsTheme, file, "$"); - newXSproto(strcpy(buf, "GetBaseSTR"), XS_Client_GetBaseSTR, file, "$"); - newXSproto(strcpy(buf, "GetBaseSTA"), XS_Client_GetBaseSTA, file, "$"); - newXSproto(strcpy(buf, "GetBaseCHA"), XS_Client_GetBaseCHA, file, "$"); - newXSproto(strcpy(buf, "GetBaseDEX"), XS_Client_GetBaseDEX, file, "$"); - newXSproto(strcpy(buf, "GetBaseINT"), XS_Client_GetBaseINT, file, "$"); - newXSproto(strcpy(buf, "GetBaseAGI"), XS_Client_GetBaseAGI, file, "$"); - newXSproto(strcpy(buf, "GetBaseWIS"), XS_Client_GetBaseWIS, file, "$"); - newXSproto(strcpy(buf, "GetWeight"), XS_Client_GetWeight, file, "$"); - newXSproto(strcpy(buf, "GetEXP"), XS_Client_GetEXP, file, "$"); - newXSproto(strcpy(buf, "GetAAExp"), XS_Client_GetAAExp, file, "$"); - newXSproto(strcpy(buf, "GetAAPercent"), XS_Client_GetAAPercent, file, "$"); - newXSproto(strcpy(buf, "GetTotalSecondsPlayed"), XS_Client_GetTotalSecondsPlayed, file, "$"); - newXSproto(strcpy(buf, "UpdateLDoNPoints"), XS_Client_UpdateLDoNPoints, file, "$$$"); - newXSproto(strcpy(buf, "SetDeity"), XS_Client_SetDeity, file, "$$"); - newXSproto(strcpy(buf, "AddEXP"), XS_Client_AddEXP, file, "$$;$$"); - newXSproto(strcpy(buf, "SetEXP"), XS_Client_SetEXP, file, "$$$;$"); - newXSproto(strcpy(buf, "SetBindPoint"), XS_Client_SetBindPoint, file, "$;$$$$$"); - newXSproto(strcpy(buf, "GetBindX"), XS_Client_GetBindX, file, "$$"); - newXSproto(strcpy(buf, "GetBindY"), XS_Client_GetBindY, file, "$$"); - newXSproto(strcpy(buf, "GetBindZ"), XS_Client_GetBindZ, file, "$$"); - newXSproto(strcpy(buf, "GetBindHeading"), XS_Client_GetBindHeading, file, "$$"); - newXSproto(strcpy(buf, "GetBindZoneID"), XS_Client_GetBindZoneID, file, "$$"); - newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$"); - newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$"); - newXSproto(strcpy(buf, "ChangeLastName"), XS_Client_ChangeLastName, file, "$$"); - newXSproto(strcpy(buf, "GetFactionLevel"), XS_Client_GetFactionLevel, file, "$$$$$$$$"); - newXSproto(strcpy(buf, "SetFactionLevel"), XS_Client_SetFactionLevel, file, "$$$$$$"); - newXSproto(strcpy(buf, "SetFactionLevel2"), XS_Client_SetFactionLevel2, file, "$$$$$$$"); - newXSproto(strcpy(buf, "GetRawItemAC"), XS_Client_GetRawItemAC, file, "$"); - newXSproto(strcpy(buf, "AccountID"), XS_Client_AccountID, file, "$"); - newXSproto(strcpy(buf, "AccountName"), XS_Client_AccountName, file, "$"); - newXSproto(strcpy(buf, "Admin"), XS_Client_Admin, file, "$"); - newXSproto(strcpy(buf, "CharacterID"), XS_Client_CharacterID, file, "$"); - newXSproto(strcpy(buf, "UpdateAdmin"), XS_Client_UpdateAdmin, file, "$;$"); - newXSproto(strcpy(buf, "UpdateWho"), XS_Client_UpdateWho, file, "$;$"); - newXSproto(strcpy(buf, "GuildRank"), XS_Client_GuildRank, file, "$"); - newXSproto(strcpy(buf, "GuildID"), XS_Client_GuildID, file, "$"); - newXSproto(strcpy(buf, "GetFace"), XS_Client_GetFace, file, "$"); - newXSproto(strcpy(buf, "TakeMoneyFromPP"), XS_Client_TakeMoneyFromPP, file, "$$;$"); - newXSproto(strcpy(buf, "AddMoneyToPP"), XS_Client_AddMoneyToPP, file, "$$$$$$"); - newXSproto(strcpy(buf, "TGB"), XS_Client_TGB, file, "$"); - newXSproto(strcpy(buf, "GetSkillPoints"), XS_Client_GetSkillPoints, file, "$"); - newXSproto(strcpy(buf, "SetSkillPoints"), XS_Client_SetSkillPoints, file, "$$"); - newXSproto(strcpy(buf, "IncreaseSkill"), XS_Client_IncreaseSkill, file, "$$;$"); - newXSproto(strcpy(buf, "IncreaseLanguageSkill"), XS_Client_IncreaseLanguageSkill, file, "$$;$"); - newXSproto(strcpy(buf, "GetSkill"), XS_Client_GetSkill, file, "$$"); - newXSproto(strcpy(buf, "GetRawSkill"), XS_Client_GetRawSkill, file, "$$"); - newXSproto(strcpy(buf, "HasSkill"), XS_Client_HasSkill, file, "$$"); - newXSproto(strcpy(buf, "CanHaveSkill"), XS_Client_CanHaveSkill, file, "$$"); - newXSproto(strcpy(buf, "SetSkill"), XS_Client_SetSkill, file, "$$$"); - newXSproto(strcpy(buf, "AddSkill"), XS_Client_AddSkill, file, "$$$"); - newXSproto(strcpy(buf, "CheckSpecializeIncrease"), XS_Client_CheckSpecializeIncrease, file, "$$"); - newXSproto(strcpy(buf, "CheckIncreaseSkill"), XS_Client_CheckIncreaseSkill, file, "$$;$"); - newXSproto(strcpy(buf, "SetLanguageSkill"), XS_Client_SetLanguageSkill, file, "$$$"); - newXSproto(strcpy(buf, "MaxSkill"), XS_Client_MaxSkill, file, "$$;$$"); - newXSproto(strcpy(buf, "GMKill"), XS_Client_GMKill, file, "$"); - newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$"); - newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$"); - newXSproto(strcpy(buf, "IsDueling"), XS_Client_IsDueling, file, "$"); - newXSproto(strcpy(buf, "SetDuelTarget"), XS_Client_SetDuelTarget, file, "$$"); - newXSproto(strcpy(buf, "SetDueling"), XS_Client_SetDueling, file, "$$"); - newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); - newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); - newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$"); - newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$"); - newXSproto(strcpy(buf, "ScribeSpell"), XS_Client_ScribeSpell, file, "$$$;$"); - newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$"); - newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$"); - newXSproto(strcpy(buf, "TrainDiscBySpellID"), XS_Client_TrainDiscBySpellID, file, "$$"); - newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$"); - newXSproto(strcpy(buf, "UntrainDiscAll"), XS_Client_UntrainDiscAll, file, "$;$"); - newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$"); - newXSproto(strcpy(buf, "IsBecomeNPC"), XS_Client_IsBecomeNPC, file, "$"); - newXSproto(strcpy(buf, "GetBecomeNPCLevel"), XS_Client_GetBecomeNPCLevel, file, "$"); - newXSproto(strcpy(buf, "SetBecomeNPC"), XS_Client_SetBecomeNPC, file, "$$"); - newXSproto(strcpy(buf, "SetBecomeNPCLevel"), XS_Client_SetBecomeNPCLevel, file, "$$"); - newXSproto(strcpy(buf, "SetFeigned"), XS_Client_SetFeigned, file, "$$"); - newXSproto(strcpy(buf, "GetFeigned"), XS_Client_GetFeigned, file, "$"); - newXSproto(strcpy(buf, "AutoSplitEnabled"), XS_Client_AutoSplitEnabled, file, "$"); - newXSproto(strcpy(buf, "SetHorseId"), XS_Client_SetHorseId, file, "$$"); - newXSproto(strcpy(buf, "GetHorseId"), XS_Client_GetHorseId, file, "$"); - newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); - newXSproto(strcpy(buf, "SetTint"), XS_Client_SetTint, file, "$$$"); - newXSproto(strcpy(buf, "SetMaterial"), XS_Client_SetMaterial, file, "$$$"); - newXSproto(strcpy(buf, "Undye"), XS_Client_Undye, file, "$"); - newXSproto(strcpy(buf, "GetItemIDAt"), XS_Client_GetItemIDAt, file, "$$"); - newXSproto(strcpy(buf, "GetAugmentIDAt"), XS_Client_GetAugmentIDAt, file, "$$$"); - newXSproto(strcpy(buf, "DeleteItemInInventory"), XS_Client_DeleteItemInInventory, file, "$$;$$"); - newXSproto(strcpy(buf, "SummonItem"), XS_Client_SummonItem, file, "$$;$$$$$$$$"); - newXSproto(strcpy(buf, "SetStats"), XS_Client_SetStats, file, "$$$"); - newXSproto(strcpy(buf, "IncStats"), XS_Client_IncStats, file, "$$$"); - newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$"); - newXSproto(strcpy(buf, "BreakInvis"), XS_Client_BreakInvis, file, "$"); - newXSproto(strcpy(buf, "GetGroup"), XS_Client_GetGroup, file, "$"); - newXSproto(strcpy(buf, "LeaveGroup"), XS_Client_LeaveGroup, file, "$"); - newXSproto(strcpy(buf, "GetRaid"), XS_Client_GetRaid, file, "$"); - newXSproto(strcpy(buf, "IsGrouped"), XS_Client_IsGrouped, file, "$"); - newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$"); - newXSproto(strcpy(buf, "Hungry"), XS_Client_Hungry, file, "$"); - newXSproto(strcpy(buf, "Thirsty"), XS_Client_Thirsty, file, "$"); - newXSproto(strcpy(buf, "GetInstrumentMod"), XS_Client_GetInstrumentMod, file, "$$"); - newXSproto(strcpy(buf, "DecreaseByID"), XS_Client_DecreaseByID, file, "$$$"); - newXSproto(strcpy(buf, "SlotConvert2"), XS_Client_SlotConvert2, file, "$$"); - newXSproto(strcpy(buf, "Escape"), XS_Client_Escape, file, "$"); - newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); - newXSproto(strcpy(buf, "GoFish"), XS_Client_GoFish, file, "$"); - newXSproto(strcpy(buf, "ForageItem"), XS_Client_ForageItem, file, "$"); - newXSproto(strcpy(buf, "CalcPriceMod"), XS_Client_CalcPriceMod, file, "$;$$"); - newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$"); - newXSproto(strcpy(buf, "UseDiscipline"), XS_Client_UseDiscipline, file, "$$$"); - newXSproto(strcpy(buf, "GetCharacterFactionLevel"), XS_Client_GetCharacterFactionLevel, file, "$$"); - newXSproto(strcpy(buf, "SetZoneFlag"), XS_Client_SetZoneFlag, file, "$$"); - newXSproto(strcpy(buf, "ClearZoneFlag"), XS_Client_ClearZoneFlag, file, "$$"); - newXSproto(strcpy(buf, "HasZoneFlag"), XS_Client_HasZoneFlag, file, "$$"); - newXSproto(strcpy(buf, "SendZoneFlagInfo"), XS_Client_SendZoneFlagInfo, file, "$$"); - newXSproto(strcpy(buf, "LoadZoneFlags"), XS_Client_LoadZoneFlags, file, "$"); - newXSproto(strcpy(buf, "SetAATitle"), XS_Client_SetAATitle, file, "$$;$"); - newXSproto(strcpy(buf, "GetClientVersion"), XS_Client_GetClientVersion, file, "$"); - newXSproto(strcpy(buf, "GetClientVersionBit"), XS_Client_GetClientVersionBit, file, "$"); - newXSproto(strcpy(buf, "SetTitleSuffix"), XS_Client_SetTitleSuffix, file, "$$;$"); - newXSproto(strcpy(buf, "SetAAPoints"), XS_Client_SetAAPoints, file, "$$"); - newXSproto(strcpy(buf, "GetAAPoints"), XS_Client_GetAAPoints, file, "$$"); - newXSproto(strcpy(buf, "GetSpentAA"), XS_Client_GetSpentAA, file, "$$"); - newXSproto(strcpy(buf, "AddAAPoints"), XS_Client_AddAAPoints, file, "$$"); - newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); - newXSproto(strcpy(buf, "GetModCharacterFactionLevel"), XS_Client_GetModCharacterFactionLevel, file, "$$"); - newXSproto(strcpy(buf, "GetLDoNWins"), XS_Client_GetLDoNWins, file, "$"); - newXSproto(strcpy(buf, "GetLDoNLosses"), XS_Client_GetLDoNLosses, file, "$"); - newXSproto(strcpy(buf, "GetLDoNWinsTheme"), XS_Client_GetLDoNWinsTheme, file, "$$"); - newXSproto(strcpy(buf, "GetLDoNLossesTheme"), XS_Client_GetLDoNLossesTheme, file, "$$"); - newXSproto(strcpy(buf, "GetItemAt"), XS_Client_GetItemAt, file, "$$"); - newXSproto(strcpy(buf, "GetAugmentAt"), XS_Client_GetAugmentAt, file, "$$$"); - newXSproto(strcpy(buf, "GetStartZone"), XS_Client_GetStartZone, file, "$"); - newXSproto(strcpy(buf, "SetStartZone"), XS_Client_SetStartZone, file, "$$"); - newXSproto(strcpy(buf, "KeyRingAdd"), XS_Client_KeyRingAdd, file, "$$"); - newXSproto(strcpy(buf, "KeyRingCheck"), XS_Client_KeyRingCheck, file, "$$"); - newXSproto(strcpy(buf, "AddPVPPoints"), XS_Client_AddPVPPoints, file, "$$"); - newXSproto(strcpy(buf, "AddCrystals"), XS_Client_AddCrystals, file, "$$"); - newXSproto(strcpy(buf, "GetPVPPoints"), XS_Client_GetPVPPoints, file, "$"); - newXSproto(strcpy(buf, "GetRadiantCrystals"), XS_Client_GetRadiantCrystals, file, "$"); - newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$"); - newXSproto(strcpy(buf, "ReadBook"), XS_Client_ReadBook, file, "$$$"); - newXSproto(strcpy(buf, "UpdateGroupAAs"), XS_Client_UpdateGroupAAs, file, "$$$"); - newXSproto(strcpy(buf, "GetGroupPoints"), XS_Client_GetGroupPoints, file, "$"); - newXSproto(strcpy(buf, "GetRaidPoints"), XS_Client_GetRaidPoints, file, "$"); - newXSproto(strcpy(buf, "LearnRecipe"), XS_Client_LearnRecipe, file, "$$"); - newXSproto(strcpy(buf, "GetEndurance"), XS_Client_GetEndurance, file, "$"); - newXSproto(strcpy(buf, "GetMaxEndurance"), XS_Client_GetMaxEndurance, file, "$"); - newXSproto(strcpy(buf, "GetEnduranceRatio"), XS_Client_GetEnduranceRatio, file, "$"); - newXSproto(strcpy(buf, "SetEndurance"), XS_Client_SetEndurance, file, "$$"); - newXSproto(strcpy(buf, "SendOPTranslocateConfirm"), XS_Client_SendOPTranslocateConfirm, file, "$$$"); - newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); - newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$"); - newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$"); - newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$"); - newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, "$$$;$"); - newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$"); - newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$"); - newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$"); - newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$"); - newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$"); - newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$;$"); - newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$"); - newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$"); - newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$"); - newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$"); - newXSproto(strcpy(buf, "GetTaskActivityDoneCount"), XS_Client_GetTaskActivityDoneCount, file, "$$$"); - newXSproto(strcpy(buf, "GetCorpseCount"), XS_Client_GetCorpseCount, file, "$"); - newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$"); - newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$"); - newXSproto(strcpy(buf, "AssignToInstance"), XS_Client_AssignToInstance, file, "$$"); - newXSproto(strcpy(buf, "Freeze"), XS_Client_Freeze, file, "$"); - newXSproto(strcpy(buf, "UnFreeze"), XS_Client_UnFreeze, file, "$"); - newXSproto(strcpy(buf, "GetAggroCount"), XS_Client_GetAggroCount, file, "$"); - newXSproto(strcpy(buf, "GetCarriedMoney"), XS_Client_GetCarriedMoney, file, "$"); - newXSproto(strcpy(buf, "GetAllMoney"), XS_Client_GetAllMoney, file, "$"); - newXSproto(strcpy(buf, "GetItemInInventory"), XS_Client_GetItemInInventory, file, "$$"); - newXSproto(strcpy(buf, "SetCustomItemData"), XS_Client_SetCustomItemData, file, "$$$$"); - newXSproto(strcpy(buf, "GetCustomItemData"), XS_Client_GetCustomItemData, file, "$$$"); - newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); - newXSproto(strcpy(buf, "SignalClient"), XS_Client_SignalClient, file, "$"); - newXSproto(strcpy(buf, "AddAlternateCurrencyValue"), XS_Client_AddAlternateCurrencyValue, file, "$$$"); - newXSproto(strcpy(buf, "SendWebLink"), XS_Client_SendWebLink, file, "$:$"); - newXSproto(strcpy(buf, "GetInstanceID"), XS_Client_GetInstanceID, file, "$$"); - newXSproto(strcpy(buf, "HasSpellScribed"), XS_Client_HasSkill, file, "$$"); - newXSproto(strcpy(buf, "SetAccountFlag"), XS_Client_SetAccountFlag, file, "$$"); - newXSproto(strcpy(buf, "GetAccountFlag"), XS_Client_GetAccountFlag, file, "$$"); - newXSproto(strcpy(buf, "GetHunger"), XS_Client_GetHunger, file, "$$"); - newXSproto(strcpy(buf, "GetThirst"), XS_Client_GetThirst, file, "$$"); - newXSproto(strcpy(buf, "SetHunger"), XS_Client_SetHunger, file, "$$"); - newXSproto(strcpy(buf, "SetThirst"), XS_Client_SetThirst, file, "$$"); - newXSproto(strcpy(buf, "SetConsumption"), XS_Client_SetConsumption, file, "$$$"); - newXSproto(strcpy(buf, "SilentMessage"), XS_Client_SilentMessage, file, "$$"); - newXSproto(strcpy(buf, "PlayMP3"), XS_Client_PlayMP3, file, "$;$"); - newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$"); - newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$"); - newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$"); - newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$"); - newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$"); - newXSproto(strcpy(buf, "GetTargetRingX"), XS_Client_GetTargetRingX, file, "$$"); - newXSproto(strcpy(buf, "GetTargetRingY"), XS_Client_GetTargetRingY, file, "$$"); - newXSproto(strcpy(buf, "GetTargetRingZ"), XS_Client_GetTargetRingZ, file, "$$"); - newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$"); - newXSproto(strcpy(buf, "CalcEXP"), XS_Client_CalcEXP, file, "$"); - newXSproto(strcpy(buf, "GetMoney"), XS_Client_GetMoney, file, "$$$"); - newXSproto(strcpy(buf, "GetAccountAge"), XS_Client_GetAccountAge, file, "$"); - newXSproto(strcpy(buf, "Popup2"), XS_Client_Popup2, file, "$$$;$$$$$$$"); - XSRETURN_YES; + newXSproto(strcpy(buf, "SendSound"), XS_Client_SendSound, file, "$"); + newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$"); + newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$"); + newXSproto(strcpy(buf, "Connected"), XS_Client_Connected, file, "$"); + newXSproto(strcpy(buf, "InZone"), XS_Client_InZone, file, "$"); + newXSproto(strcpy(buf, "Kick"), XS_Client_Kick, file, "$"); + newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$"); + newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$"); + newXSproto(strcpy(buf, "WorldKick"), XS_Client_WorldKick, file, "$"); + newXSproto(strcpy(buf, "GetAnon"), XS_Client_GetAnon, file, "$"); + newXSproto(strcpy(buf, "Duck"), XS_Client_Duck, file, "$"); + newXSproto(strcpy(buf, "Stand"), XS_Client_Stand, file, "$"); + newXSproto(strcpy(buf, "SetGM"), XS_Client_SetGM, file, "$$"); + newXSproto(strcpy(buf, "SetPVP"), XS_Client_SetPVP, file, "$$"); + newXSproto(strcpy(buf, "GetPVP"), XS_Client_GetPVP, file, "$"); + newXSproto(strcpy(buf, "GetGM"), XS_Client_GetGM, file, "$"); + newXSproto(strcpy(buf, "SetBaseClass"), XS_Client_SetBaseClass, file, "$$"); + newXSproto(strcpy(buf, "SetBaseRace"), XS_Client_SetBaseRace, file, "$$"); + newXSproto(strcpy(buf, "SetBaseGender"), XS_Client_SetBaseGender, file, "$$"); + newXSproto(strcpy(buf, "GetBaseFace"), XS_Client_GetBaseFace, file, "$"); + newXSproto(strcpy(buf, "GetLanguageSkill"), XS_Client_GetLanguageSkill, file, "$$"); + newXSproto(strcpy(buf, "GetLastName"), XS_Client_GetLastName, file, "$"); + newXSproto(strcpy(buf, "GetLDoNPointsTheme"), XS_Client_GetLDoNPointsTheme, file, "$"); + newXSproto(strcpy(buf, "GetBaseSTR"), XS_Client_GetBaseSTR, file, "$"); + newXSproto(strcpy(buf, "GetBaseSTA"), XS_Client_GetBaseSTA, file, "$"); + newXSproto(strcpy(buf, "GetBaseCHA"), XS_Client_GetBaseCHA, file, "$"); + newXSproto(strcpy(buf, "GetBaseDEX"), XS_Client_GetBaseDEX, file, "$"); + newXSproto(strcpy(buf, "GetBaseINT"), XS_Client_GetBaseINT, file, "$"); + newXSproto(strcpy(buf, "GetBaseAGI"), XS_Client_GetBaseAGI, file, "$"); + newXSproto(strcpy(buf, "GetBaseWIS"), XS_Client_GetBaseWIS, file, "$"); + newXSproto(strcpy(buf, "GetWeight"), XS_Client_GetWeight, file, "$"); + newXSproto(strcpy(buf, "GetEXP"), XS_Client_GetEXP, file, "$"); + newXSproto(strcpy(buf, "GetAAExp"), XS_Client_GetAAExp, file, "$"); + newXSproto(strcpy(buf, "GetAAPercent"), XS_Client_GetAAPercent, file, "$"); + newXSproto(strcpy(buf, "GetTotalSecondsPlayed"), XS_Client_GetTotalSecondsPlayed, file, "$"); + newXSproto(strcpy(buf, "UpdateLDoNPoints"), XS_Client_UpdateLDoNPoints, file, "$$$"); + newXSproto(strcpy(buf, "SetDeity"), XS_Client_SetDeity, file, "$$"); + newXSproto(strcpy(buf, "AddEXP"), XS_Client_AddEXP, file, "$$;$$"); + newXSproto(strcpy(buf, "SetEXP"), XS_Client_SetEXP, file, "$$$;$"); + newXSproto(strcpy(buf, "SetBindPoint"), XS_Client_SetBindPoint, file, "$;$$$$$"); + newXSproto(strcpy(buf, "GetBindX"), XS_Client_GetBindX, file, "$$"); + newXSproto(strcpy(buf, "GetBindY"), XS_Client_GetBindY, file, "$$"); + newXSproto(strcpy(buf, "GetBindZ"), XS_Client_GetBindZ, file, "$$"); + newXSproto(strcpy(buf, "GetBindHeading"), XS_Client_GetBindHeading, file, "$$"); + newXSproto(strcpy(buf, "GetBindZoneID"), XS_Client_GetBindZoneID, file, "$$"); + newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$"); + newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$"); + newXSproto(strcpy(buf, "ChangeLastName"), XS_Client_ChangeLastName, file, "$$"); + newXSproto(strcpy(buf, "GetFactionLevel"), XS_Client_GetFactionLevel, file, "$$$$$$$$"); + newXSproto(strcpy(buf, "SetFactionLevel"), XS_Client_SetFactionLevel, file, "$$$$$$"); + newXSproto(strcpy(buf, "SetFactionLevel2"), XS_Client_SetFactionLevel2, file, "$$$$$$$"); + newXSproto(strcpy(buf, "GetRawItemAC"), XS_Client_GetRawItemAC, file, "$"); + newXSproto(strcpy(buf, "AccountID"), XS_Client_AccountID, file, "$"); + newXSproto(strcpy(buf, "AccountName"), XS_Client_AccountName, file, "$"); + newXSproto(strcpy(buf, "Admin"), XS_Client_Admin, file, "$"); + newXSproto(strcpy(buf, "CharacterID"), XS_Client_CharacterID, file, "$"); + newXSproto(strcpy(buf, "UpdateAdmin"), XS_Client_UpdateAdmin, file, "$;$"); + newXSproto(strcpy(buf, "UpdateWho"), XS_Client_UpdateWho, file, "$;$"); + newXSproto(strcpy(buf, "GuildRank"), XS_Client_GuildRank, file, "$"); + newXSproto(strcpy(buf, "GuildID"), XS_Client_GuildID, file, "$"); + newXSproto(strcpy(buf, "GetFace"), XS_Client_GetFace, file, "$"); + newXSproto(strcpy(buf, "TakeMoneyFromPP"), XS_Client_TakeMoneyFromPP, file, "$$;$"); + newXSproto(strcpy(buf, "AddMoneyToPP"), XS_Client_AddMoneyToPP, file, "$$$$$$"); + newXSproto(strcpy(buf, "TGB"), XS_Client_TGB, file, "$"); + newXSproto(strcpy(buf, "GetSkillPoints"), XS_Client_GetSkillPoints, file, "$"); + newXSproto(strcpy(buf, "SetSkillPoints"), XS_Client_SetSkillPoints, file, "$$"); + newXSproto(strcpy(buf, "IncreaseSkill"), XS_Client_IncreaseSkill, file, "$$;$"); + newXSproto(strcpy(buf, "IncreaseLanguageSkill"), XS_Client_IncreaseLanguageSkill, file, "$$;$"); + newXSproto(strcpy(buf, "GetSkill"), XS_Client_GetSkill, file, "$$"); + newXSproto(strcpy(buf, "GetRawSkill"), XS_Client_GetRawSkill, file, "$$"); + newXSproto(strcpy(buf, "HasSkill"), XS_Client_HasSkill, file, "$$"); + newXSproto(strcpy(buf, "CanHaveSkill"), XS_Client_CanHaveSkill, file, "$$"); + newXSproto(strcpy(buf, "SetSkill"), XS_Client_SetSkill, file, "$$$"); + newXSproto(strcpy(buf, "AddSkill"), XS_Client_AddSkill, file, "$$$"); + newXSproto(strcpy(buf, "CheckSpecializeIncrease"), XS_Client_CheckSpecializeIncrease, file, "$$"); + newXSproto(strcpy(buf, "CheckIncreaseSkill"), XS_Client_CheckIncreaseSkill, file, "$$;$"); + newXSproto(strcpy(buf, "SetLanguageSkill"), XS_Client_SetLanguageSkill, file, "$$$"); + newXSproto(strcpy(buf, "MaxSkill"), XS_Client_MaxSkill, file, "$$;$$"); + newXSproto(strcpy(buf, "GMKill"), XS_Client_GMKill, file, "$"); + newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$"); + newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$"); + newXSproto(strcpy(buf, "IsDueling"), XS_Client_IsDueling, file, "$"); + newXSproto(strcpy(buf, "SetDuelTarget"), XS_Client_SetDuelTarget, file, "$$"); + newXSproto(strcpy(buf, "SetDueling"), XS_Client_SetDueling, file, "$$"); + newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); + newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); + newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$"); + newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$"); + newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$"); + newXSproto(strcpy(buf, "ScribeSpell"), XS_Client_ScribeSpell, file, "$$$;$"); + newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$"); + newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$"); + newXSproto(strcpy(buf, "TrainDiscBySpellID"), XS_Client_TrainDiscBySpellID, file, "$$"); + newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); + newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$"); + newXSproto(strcpy(buf, "UntrainDiscAll"), XS_Client_UntrainDiscAll, file, "$;$"); + newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$"); + newXSproto(strcpy(buf, "IsBecomeNPC"), XS_Client_IsBecomeNPC, file, "$"); + newXSproto(strcpy(buf, "GetBecomeNPCLevel"), XS_Client_GetBecomeNPCLevel, file, "$"); + newXSproto(strcpy(buf, "SetBecomeNPC"), XS_Client_SetBecomeNPC, file, "$$"); + newXSproto(strcpy(buf, "SetBecomeNPCLevel"), XS_Client_SetBecomeNPCLevel, file, "$$"); + newXSproto(strcpy(buf, "SetFeigned"), XS_Client_SetFeigned, file, "$$"); + newXSproto(strcpy(buf, "GetFeigned"), XS_Client_GetFeigned, file, "$"); + newXSproto(strcpy(buf, "AutoSplitEnabled"), XS_Client_AutoSplitEnabled, file, "$"); + newXSproto(strcpy(buf, "SetHorseId"), XS_Client_SetHorseId, file, "$$"); + newXSproto(strcpy(buf, "GetHorseId"), XS_Client_GetHorseId, file, "$"); + newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); + newXSproto(strcpy(buf, "SetTint"), XS_Client_SetTint, file, "$$$"); + newXSproto(strcpy(buf, "SetMaterial"), XS_Client_SetMaterial, file, "$$$"); + newXSproto(strcpy(buf, "Undye"), XS_Client_Undye, file, "$"); + newXSproto(strcpy(buf, "GetItemIDAt"), XS_Client_GetItemIDAt, file, "$$"); + newXSproto(strcpy(buf, "GetAugmentIDAt"), XS_Client_GetAugmentIDAt, file, "$$$"); + newXSproto(strcpy(buf, "DeleteItemInInventory"), XS_Client_DeleteItemInInventory, file, "$$;$$"); + newXSproto(strcpy(buf, "SummonItem"), XS_Client_SummonItem, file, "$$;$$$$$$$$"); + newXSproto(strcpy(buf, "SetStats"), XS_Client_SetStats, file, "$$$"); + newXSproto(strcpy(buf, "IncStats"), XS_Client_IncStats, file, "$$$"); + newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$"); + newXSproto(strcpy(buf, "BreakInvis"), XS_Client_BreakInvis, file, "$"); + newXSproto(strcpy(buf, "GetGroup"), XS_Client_GetGroup, file, "$"); + newXSproto(strcpy(buf, "LeaveGroup"), XS_Client_LeaveGroup, file, "$"); + newXSproto(strcpy(buf, "GetRaid"), XS_Client_GetRaid, file, "$"); + newXSproto(strcpy(buf, "IsGrouped"), XS_Client_IsGrouped, file, "$"); + newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$"); + newXSproto(strcpy(buf, "Hungry"), XS_Client_Hungry, file, "$"); + newXSproto(strcpy(buf, "Thirsty"), XS_Client_Thirsty, file, "$"); + newXSproto(strcpy(buf, "GetInstrumentMod"), XS_Client_GetInstrumentMod, file, "$$"); + newXSproto(strcpy(buf, "DecreaseByID"), XS_Client_DecreaseByID, file, "$$$"); + newXSproto(strcpy(buf, "SlotConvert2"), XS_Client_SlotConvert2, file, "$$"); + newXSproto(strcpy(buf, "Escape"), XS_Client_Escape, file, "$"); + newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); + newXSproto(strcpy(buf, "GoFish"), XS_Client_GoFish, file, "$"); + newXSproto(strcpy(buf, "ForageItem"), XS_Client_ForageItem, file, "$"); + newXSproto(strcpy(buf, "CalcPriceMod"), XS_Client_CalcPriceMod, file, "$;$$"); + newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$"); + newXSproto(strcpy(buf, "UseDiscipline"), XS_Client_UseDiscipline, file, "$$$"); + newXSproto(strcpy(buf, "GetCharacterFactionLevel"), XS_Client_GetCharacterFactionLevel, file, "$$"); + newXSproto(strcpy(buf, "SetZoneFlag"), XS_Client_SetZoneFlag, file, "$$"); + newXSproto(strcpy(buf, "ClearZoneFlag"), XS_Client_ClearZoneFlag, file, "$$"); + newXSproto(strcpy(buf, "HasZoneFlag"), XS_Client_HasZoneFlag, file, "$$"); + newXSproto(strcpy(buf, "SendZoneFlagInfo"), XS_Client_SendZoneFlagInfo, file, "$$"); + newXSproto(strcpy(buf, "LoadZoneFlags"), XS_Client_LoadZoneFlags, file, "$"); + newXSproto(strcpy(buf, "SetAATitle"), XS_Client_SetAATitle, file, "$$;$"); + newXSproto(strcpy(buf, "GetClientVersion"), XS_Client_GetClientVersion, file, "$"); + newXSproto(strcpy(buf, "GetClientVersionBit"), XS_Client_GetClientVersionBit, file, "$"); + newXSproto(strcpy(buf, "SetTitleSuffix"), XS_Client_SetTitleSuffix, file, "$$;$"); + newXSproto(strcpy(buf, "SetAAPoints"), XS_Client_SetAAPoints, file, "$$"); + newXSproto(strcpy(buf, "GetAAPoints"), XS_Client_GetAAPoints, file, "$$"); + newXSproto(strcpy(buf, "GetSpentAA"), XS_Client_GetSpentAA, file, "$$"); + newXSproto(strcpy(buf, "AddAAPoints"), XS_Client_AddAAPoints, file, "$$"); + newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); + newXSproto(strcpy(buf, "GetModCharacterFactionLevel"), XS_Client_GetModCharacterFactionLevel, file, "$$"); + newXSproto(strcpy(buf, "GetLDoNWins"), XS_Client_GetLDoNWins, file, "$"); + newXSproto(strcpy(buf, "GetLDoNLosses"), XS_Client_GetLDoNLosses, file, "$"); + newXSproto(strcpy(buf, "GetLDoNWinsTheme"), XS_Client_GetLDoNWinsTheme, file, "$$"); + newXSproto(strcpy(buf, "GetLDoNLossesTheme"), XS_Client_GetLDoNLossesTheme, file, "$$"); + newXSproto(strcpy(buf, "GetItemAt"), XS_Client_GetItemAt, file, "$$"); + newXSproto(strcpy(buf, "GetAugmentAt"), XS_Client_GetAugmentAt, file, "$$$"); + newXSproto(strcpy(buf, "GetStartZone"), XS_Client_GetStartZone, file, "$"); + newXSproto(strcpy(buf, "SetStartZone"), XS_Client_SetStartZone, file, "$$"); + newXSproto(strcpy(buf, "KeyRingAdd"), XS_Client_KeyRingAdd, file, "$$"); + newXSproto(strcpy(buf, "KeyRingCheck"), XS_Client_KeyRingCheck, file, "$$"); + newXSproto(strcpy(buf, "AddPVPPoints"), XS_Client_AddPVPPoints, file, "$$"); + newXSproto(strcpy(buf, "AddCrystals"), XS_Client_AddCrystals, file, "$$"); + newXSproto(strcpy(buf, "GetPVPPoints"), XS_Client_GetPVPPoints, file, "$"); + newXSproto(strcpy(buf, "GetRadiantCrystals"), XS_Client_GetRadiantCrystals, file, "$"); + newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$"); + newXSproto(strcpy(buf, "ReadBook"), XS_Client_ReadBook, file, "$$$"); + newXSproto(strcpy(buf, "UpdateGroupAAs"), XS_Client_UpdateGroupAAs, file, "$$$"); + newXSproto(strcpy(buf, "GetGroupPoints"), XS_Client_GetGroupPoints, file, "$"); + newXSproto(strcpy(buf, "GetRaidPoints"), XS_Client_GetRaidPoints, file, "$"); + newXSproto(strcpy(buf, "LearnRecipe"), XS_Client_LearnRecipe, file, "$$"); + newXSproto(strcpy(buf, "GetEndurance"), XS_Client_GetEndurance, file, "$"); + newXSproto(strcpy(buf, "GetMaxEndurance"), XS_Client_GetMaxEndurance, file, "$"); + newXSproto(strcpy(buf, "GetEnduranceRatio"), XS_Client_GetEnduranceRatio, file, "$"); + newXSproto(strcpy(buf, "SetEndurance"), XS_Client_SetEndurance, file, "$$"); + newXSproto(strcpy(buf, "SendOPTranslocateConfirm"), XS_Client_SendOPTranslocateConfirm, file, "$$$"); + newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); + newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$"); + newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$"); + newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$"); + newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, + "$$$;$"); + newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$"); + newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$"); + newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$"); + newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$"); + newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$"); + newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$"); + newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$;$"); + newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$"); + newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$"); + newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$"); + newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$"); + newXSproto(strcpy(buf, "GetTaskActivityDoneCount"), XS_Client_GetTaskActivityDoneCount, file, "$$$"); + newXSproto(strcpy(buf, "GetCorpseCount"), XS_Client_GetCorpseCount, file, "$"); + newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$"); + newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$"); + newXSproto(strcpy(buf, "AssignToInstance"), XS_Client_AssignToInstance, file, "$$"); + newXSproto(strcpy(buf, "Freeze"), XS_Client_Freeze, file, "$"); + newXSproto(strcpy(buf, "UnFreeze"), XS_Client_UnFreeze, file, "$"); + newXSproto(strcpy(buf, "GetAggroCount"), XS_Client_GetAggroCount, file, "$"); + newXSproto(strcpy(buf, "GetCarriedMoney"), XS_Client_GetCarriedMoney, file, "$"); + newXSproto(strcpy(buf, "GetAllMoney"), XS_Client_GetAllMoney, file, "$"); + newXSproto(strcpy(buf, "GetItemInInventory"), XS_Client_GetItemInInventory, file, "$$"); + newXSproto(strcpy(buf, "SetCustomItemData"), XS_Client_SetCustomItemData, file, "$$$$"); + newXSproto(strcpy(buf, "GetCustomItemData"), XS_Client_GetCustomItemData, file, "$$$"); + newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); + newXSproto(strcpy(buf, "SignalClient"), XS_Client_SignalClient, file, "$"); + newXSproto(strcpy(buf, "AddAlternateCurrencyValue"), XS_Client_AddAlternateCurrencyValue, file, "$$$"); + newXSproto(strcpy(buf, "SendWebLink"), XS_Client_SendWebLink, file, "$:$"); + newXSproto(strcpy(buf, "GetInstanceID"), XS_Client_GetInstanceID, file, "$$"); + newXSproto(strcpy(buf, "HasSpellScribed"), XS_Client_HasSkill, file, "$$"); + newXSproto(strcpy(buf, "SetAccountFlag"), XS_Client_SetAccountFlag, file, "$$"); + newXSproto(strcpy(buf, "GetAccountFlag"), XS_Client_GetAccountFlag, file, "$$"); + newXSproto(strcpy(buf, "GetHunger"), XS_Client_GetHunger, file, "$$"); + newXSproto(strcpy(buf, "GetThirst"), XS_Client_GetThirst, file, "$$"); + newXSproto(strcpy(buf, "SetHunger"), XS_Client_SetHunger, file, "$$"); + newXSproto(strcpy(buf, "SetThirst"), XS_Client_SetThirst, file, "$$"); + newXSproto(strcpy(buf, "SetConsumption"), XS_Client_SetConsumption, file, "$$$"); + newXSproto(strcpy(buf, "SilentMessage"), XS_Client_SilentMessage, file, "$$"); + newXSproto(strcpy(buf, "PlayMP3"), XS_Client_PlayMP3, file, "$;$"); + newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$"); + newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$"); + newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$"); + newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$"); + newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$"); + newXSproto(strcpy(buf, "GetTargetRingX"), XS_Client_GetTargetRingX, file, "$$"); + newXSproto(strcpy(buf, "GetTargetRingY"), XS_Client_GetTargetRingY, file, "$$"); + newXSproto(strcpy(buf, "GetTargetRingZ"), XS_Client_GetTargetRingZ, file, "$$"); + newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$"); + newXSproto(strcpy(buf, "CalcEXP"), XS_Client_CalcEXP, file, "$"); + newXSproto(strcpy(buf, "GetMoney"), XS_Client_GetMoney, file, "$$$"); + newXSproto(strcpy(buf, "GetAccountAge"), XS_Client_GetAccountAge, file, "$"); + newXSproto(strcpy(buf, "Popup2"), XS_Client_Popup2, file, "$$$;$$$$$$$"); + XSRETURN_YES; } #endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_doors.cpp b/zone/perl_doors.cpp index 0024f877e..8c4f4ea98 100644 --- a/zone/perl_doors.cpp +++ b/zone/perl_doors.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -41,282 +43,270 @@ #endif XS(XS_Doors_GetDoorDBID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetDoorDBID) -{ +XS(XS_Doors_GetDoorDBID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetDoorDBID(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDoorDBID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetDoorID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetDoorID) -{ +XS(XS_Doors_GetDoorID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetDoorID(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDoorID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetID) -{ +XS(XS_Doors_GetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetID(THIS)"); { - Doors * THIS; - uint16 RETVAL; + Doors *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEntityID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetX) -{ +XS(XS_Doors_GetX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetX(THIS)"); { - Doors * THIS; - float RETVAL; + Doors *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPosition().x; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetY) -{ +XS(XS_Doors_GetY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetY(THIS)"); { - Doors * THIS; - float RETVAL; + Doors *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPosition().y; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetZ) -{ +XS(XS_Doors_GetZ) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetZ(THIS)"); { - Doors * THIS; - float RETVAL; + Doors *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPosition().z; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetHeading) -{ +XS(XS_Doors_GetHeading) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetHeading(THIS)"); { - Doors * THIS; - float RETVAL; + Doors *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPosition().w; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetOpenType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetOpenType) -{ +XS(XS_Doors_GetOpenType) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetOpenType(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetOpenType(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetLockpick); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetLockpick) -{ +XS(XS_Doors_GetLockpick) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetLockpick(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLockpick(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetKeyItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetKeyItem) -{ +XS(XS_Doors_GetKeyItem) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetKeyItem(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetKeyItem(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetNoKeyring); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetNoKeyring) -{ +XS(XS_Doors_GetNoKeyring) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::GetNoKeyring(THIS, type)"); + Perl_croak(aTHX_ "Usage: Doors::GetNoKeyring(THIS, uint8 type)"); { - Doors * THIS; - uint8 type = (uint8)SvUV(ST(1)); + Doors *THIS; + uint8 type = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->GetNoKeyring(); @@ -325,76 +315,71 @@ XS(XS_Doors_GetNoKeyring) } XS(XS_Doors_GetIncline); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetIncline) -{ +XS(XS_Doors_GetIncline) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetIncline(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetIncline(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Doors_GetSize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetSize) -{ +XS(XS_Doors_GetSize) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetIncline(THIS)"); { - Doors * THIS; - uint32 RETVAL; + Doors *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSize(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } - XS(XS_Doors_SetOpenType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetOpenType) -{ +XS(XS_Doors_SetOpenType) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetOpenType(THIS, type)"); + Perl_croak(aTHX_ "Usage: Doors::SetOpenType(THIS, uint32 open_type)"); { - Doors * THIS; - uint32 type = (uint32)SvUV(ST(1)); + Doors *THIS; + uint32 type = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetOpenType(type); @@ -403,22 +388,20 @@ XS(XS_Doors_SetOpenType) } XS(XS_Doors_SetLockpick); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetLockpick) -{ +XS(XS_Doors_SetLockpick) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetLockpick(THIS, type)"); + Perl_croak(aTHX_ "Usage: Doors::SetLockpick(THIS, uint32 lockpick_type)"); { - Doors * THIS; - uint32 type = (uint32)SvUV(ST(1)); + Doors *THIS; + uint32 type = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetLockpick(type); @@ -427,22 +410,20 @@ XS(XS_Doors_SetLockpick) } XS(XS_Doors_SetKeyItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetKeyItem) -{ +XS(XS_Doors_SetKeyItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetKeyItem(THIS, type)"); + Perl_croak(aTHX_ "Usage: Doors::SetKeyItem(THIS, uint32 key_item_id)"); { - Doors * THIS; - uint32 type = (uint32)SvUV(ST(1)); + Doors *THIS; + uint32 type = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetKeyItem(type); @@ -451,22 +432,20 @@ XS(XS_Doors_SetKeyItem) } XS(XS_Doors_SetNoKeyring); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetNoKeyring) -{ +XS(XS_Doors_SetNoKeyring) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetNoKeyring(THIS, type)"); + Perl_croak(aTHX_ "Usage: Doors::SetNoKeyring(THIS, uint8 no_key_ring)"); { - Doors * THIS; - uint8 type = (uint8)SvUV(ST(1)); + Doors *THIS; + uint8 type = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetNoKeyring(type); @@ -475,22 +454,20 @@ XS(XS_Doors_SetNoKeyring) } XS(XS_Doors_SetIncline); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetIncline) -{ +XS(XS_Doors_SetIncline) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetIncline(THIS, type)"); + Perl_croak(aTHX_ "Usage: Doors::SetIncline(THIS, uint32 incline)"); { - Doors * THIS; - uint32 type = (uint32)SvUV(ST(1)); + Doors *THIS; + uint32 type = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetIncline(type); @@ -499,22 +476,20 @@ XS(XS_Doors_SetIncline) } XS(XS_Doors_SetSize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetSize) -{ +XS(XS_Doors_SetSize) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetSize(THIS, size)"); + Perl_croak(aTHX_ "Usage: Doors::SetSize(THIS, uint32 size)"); { - Doors * THIS; - uint32 type = (uint32)SvUV(ST(1)); + Doors *THIS; + uint32 type = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSize(type); @@ -523,24 +498,22 @@ XS(XS_Doors_SetSize) } XS(XS_Doors_SetLocation); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetLocation) -{ +XS(XS_Doors_SetLocation) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Doors::SetLocation(THIS, x, y, z)"); + Perl_croak(aTHX_ "Usage: Doors::SetLocation(THIS, float x, float y, float z)"); { - Doors * THIS; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); + Doors *THIS; + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetLocation(x, y, z); @@ -549,175 +522,163 @@ XS(XS_Doors_SetLocation) } XS(XS_Doors_SetX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetX) -{ +XS(XS_Doors_SetX) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetX(THIS, XPos)"); + Perl_croak(aTHX_ "Usage: Doors::SetX(THIS, float x)"); { - Doors * THIS; - float x = (float)SvNV(ST(1)); + Doors *THIS; + float x = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - auto position = THIS->GetPosition(); - position.x = x; + auto position = THIS->GetPosition(); + position.x = x; THIS->SetPosition(position); } XSRETURN_EMPTY; } XS(XS_Doors_SetY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetY) -{ +XS(XS_Doors_SetY) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetY(THIS, YPos)"); + Perl_croak(aTHX_ "Usage: Doors::SetY(THIS, float y)"); { - Doors * THIS; - float y = (float)SvNV(ST(1)); + Doors *THIS; + float y = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - auto position = THIS->GetPosition(); - position.y = y; + auto position = THIS->GetPosition(); + position.y = y; THIS->SetPosition(position); } XSRETURN_EMPTY; } XS(XS_Doors_SetZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetZ) -{ +XS(XS_Doors_SetZ) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetZ(THIS, ZPos)"); + Perl_croak(aTHX_ "Usage: Doors::SetZ(THIS, float z)"); { - Doors * THIS; - float z = (float)SvNV(ST(1)); + Doors *THIS; + float z = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); auto position = THIS->GetPosition(); - position.z = z; + position.z = z; THIS->SetPosition(position); } XSRETURN_EMPTY; } XS(XS_Doors_SetHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetHeading) -{ +XS(XS_Doors_SetHeading) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Doors::SetHeading(THIS, heading)"); + Perl_croak(aTHX_ "Usage: Doors::SetHeading(THIS, float heading)"); { - Doors * THIS; - float heading = (float)SvNV(ST(1)); + Doors *THIS; + float heading = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); auto position = THIS->GetPosition(); - position.w = heading; + position.w = heading; THIS->SetPosition(position); } XSRETURN_EMPTY; } XS(XS_Doors_SetModelName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_SetModelName) -{ +XS(XS_Doors_SetModelName) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Doors::SetModelName(THIS, name)"); + Perl_croak(aTHX_ "Usage: Doors::SetModelName(THIS, string name)"); { - Doors * THIS; - char * name = nullptr; + Doors *THIS; + char *name = nullptr; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { name = (char *)SvPV_nolen(ST(1)); } + if (items > 1) { name = (char *) SvPV_nolen(ST(1)); } THIS->SetDoorName(name); } XSRETURN_EMPTY; } XS(XS_Doors_GetModelName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_GetModelName) -{ +XS(XS_Doors_GetModelName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::GetModelName(THIS)"); { - Doors * THIS; - Const_char * RETVAL; + Doors *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDoorName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Doors_CreateDatabaseEntry); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Doors_CreateDatabaseEntry) -{ +XS(XS_Doors_CreateDatabaseEntry) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Doors::InsertDoor(THIS)"); { - Doors * THIS; + Doors *THIS; if (sv_derived_from(ST(0), "Doors")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Doors *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Doors *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Doors"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->CreateDatabaseEntry(); @@ -726,52 +687,50 @@ XS(XS_Doors_CreateDatabaseEntry) } - #ifdef __cplusplus extern "C" #endif XS(boot_Doors); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Doors) -{ +XS(boot_Doors) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; - newXSproto(strcpy(buf, "GetID"),XS_Doors_GetID, file, "$"); - newXSproto(strcpy(buf, "SetModelName"),XS_Doors_SetModelName, file, "$$"); - newXSproto(strcpy(buf, "GetModelName"),XS_Doors_GetModelName, file, "$"); - newXSproto(strcpy(buf, "GetX"),XS_Doors_GetX, file, "$"); - newXSproto(strcpy(buf, "GetY"),XS_Doors_GetY, file, "$"); - newXSproto(strcpy(buf, "GetZ"),XS_Doors_GetZ, file, "$"); - newXSproto(strcpy(buf, "GetHeading"),XS_Doors_GetHeading, file, "$"); - newXSproto(strcpy(buf, "SetX"),XS_Doors_SetX, file, "$$"); - newXSproto(strcpy(buf, "SetY"),XS_Doors_SetY, file, "$$"); - newXSproto(strcpy(buf, "SetZ"),XS_Doors_SetZ, file, "$$"); - newXSproto(strcpy(buf, "SetHeading"),XS_Doors_SetHeading, file, "$$"); - newXSproto(strcpy(buf, "SetLocation"),XS_Doors_SetLocation, file, "$$$$"); - newXSproto(strcpy(buf, "GetDoorDBID"),XS_Doors_GetDoorDBID, file, "$"); - newXSproto(strcpy(buf, "GetDoorID"),XS_Doors_GetDoorID, file, "$"); - newXSproto(strcpy(buf, "SetSize"),XS_Doors_SetSize, file, "$$"); - newXSproto(strcpy(buf, "GetSize"),XS_Doors_GetSize, file, "$"); - newXSproto(strcpy(buf, "SetIncline"),XS_Doors_SetIncline, file, "$$"); - newXSproto(strcpy(buf, "GetIncline"),XS_Doors_GetIncline, file, "$"); - newXSproto(strcpy(buf, "SetOpenType"),XS_Doors_SetOpenType, file, "$$"); - newXSproto(strcpy(buf, "GetOpenType"),XS_Doors_GetOpenType, file, "$"); - newXSproto(strcpy(buf, "SetLockPick"),XS_Doors_SetLockpick, file, "$$"); - newXSproto(strcpy(buf, "GetLockPick"),XS_Doors_GetLockpick, file, "$"); - newXSproto(strcpy(buf, "SetKeyItem"),XS_Doors_SetKeyItem, file, "$$"); - newXSproto(strcpy(buf, "GetKeyItem"),XS_Doors_GetKeyItem, file, "$"); - newXSproto(strcpy(buf, "SetNoKeyring"),XS_Doors_SetNoKeyring, file, "$$"); - newXSproto(strcpy(buf, "GetNoKeyring"),XS_Doors_GetNoKeyring, file, "$"); - newXSproto(strcpy(buf, "CreateDatabaseEntry"),XS_Doors_CreateDatabaseEntry, file, "$"); + XS_VERSION_BOOTCHECK; + newXSproto(strcpy(buf, "GetID"), XS_Doors_GetID, file, "$"); + newXSproto(strcpy(buf, "SetModelName"), XS_Doors_SetModelName, file, "$$"); + newXSproto(strcpy(buf, "GetModelName"), XS_Doors_GetModelName, file, "$"); + newXSproto(strcpy(buf, "GetX"), XS_Doors_GetX, file, "$"); + newXSproto(strcpy(buf, "GetY"), XS_Doors_GetY, file, "$"); + newXSproto(strcpy(buf, "GetZ"), XS_Doors_GetZ, file, "$"); + newXSproto(strcpy(buf, "GetHeading"), XS_Doors_GetHeading, file, "$"); + newXSproto(strcpy(buf, "SetX"), XS_Doors_SetX, file, "$$"); + newXSproto(strcpy(buf, "SetY"), XS_Doors_SetY, file, "$$"); + newXSproto(strcpy(buf, "SetZ"), XS_Doors_SetZ, file, "$$"); + newXSproto(strcpy(buf, "SetHeading"), XS_Doors_SetHeading, file, "$$"); + newXSproto(strcpy(buf, "SetLocation"), XS_Doors_SetLocation, file, "$$$$"); + newXSproto(strcpy(buf, "GetDoorDBID"), XS_Doors_GetDoorDBID, file, "$"); + newXSproto(strcpy(buf, "GetDoorID"), XS_Doors_GetDoorID, file, "$"); + newXSproto(strcpy(buf, "SetSize"), XS_Doors_SetSize, file, "$$"); + newXSproto(strcpy(buf, "GetSize"), XS_Doors_GetSize, file, "$"); + newXSproto(strcpy(buf, "SetIncline"), XS_Doors_SetIncline, file, "$$"); + newXSproto(strcpy(buf, "GetIncline"), XS_Doors_GetIncline, file, "$"); + newXSproto(strcpy(buf, "SetOpenType"), XS_Doors_SetOpenType, file, "$$"); + newXSproto(strcpy(buf, "GetOpenType"), XS_Doors_GetOpenType, file, "$"); + newXSproto(strcpy(buf, "SetLockPick"), XS_Doors_SetLockpick, file, "$$"); + newXSproto(strcpy(buf, "GetLockPick"), XS_Doors_GetLockpick, file, "$"); + newXSproto(strcpy(buf, "SetKeyItem"), XS_Doors_SetKeyItem, file, "$$"); + newXSproto(strcpy(buf, "GetKeyItem"), XS_Doors_GetKeyItem, file, "$"); + newXSproto(strcpy(buf, "SetNoKeyring"), XS_Doors_SetNoKeyring, file, "$$"); + newXSproto(strcpy(buf, "GetNoKeyring"), XS_Doors_GetNoKeyring, file, "$"); + newXSproto(strcpy(buf, "CreateDatabaseEntry"), XS_Doors_CreateDatabaseEntry, file, "$"); XSRETURN_YES; } #endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_entity.cpp b/zone/perl_entity.cpp index eafc5c822..a38852b9c 100644 --- a/zone/perl_entity.cpp +++ b/zone/perl_entity.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include #include "embperl.h" @@ -43,786 +45,726 @@ XS(XS_EntityList_GetMobID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetMobID) -{ +XS(XS_EntityList_GetMobID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetMobID(THIS, id)"); { - EntityList * THIS; - Mob * RETVAL; - uint16 id = (uint16)SvUV(ST(1)); + EntityList *THIS; + Mob *RETVAL; + uint16 id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMobID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetMob) -{ +XS(XS_EntityList_GetMob) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetMob(THIS, name)"); { - EntityList * THIS; - Mob * RETVAL; - char* name = (char *)SvPV_nolen(ST(1)); + EntityList *THIS; + Mob *RETVAL; + char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMob(name); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetMobByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetMobByID) -{ +XS(XS_EntityList_GetMobByID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetMobByID(THIS, id)"); { - EntityList * THIS; - Mob * RETVAL; - uint16 id = (uint16)SvUV(ST(1)); + EntityList *THIS; + Mob *RETVAL; + uint16 id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMob(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetMobByNpcTypeID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetMobByNpcTypeID) -{ +XS(XS_EntityList_GetMobByNpcTypeID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetMobByNpcTypeID(THIS, get_id)"); { - EntityList * THIS; - Mob * RETVAL; - uint32 get_id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Mob *RETVAL; + uint32 get_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMobByNpcTypeID(get_id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_IsMobSpawnedByNpcTypeID); /* prototype pass -Wmissing-prototypes */ -XS(XS_EntityList_IsMobSpawnedByNpcTypeID) -{ +XS(XS_EntityList_IsMobSpawnedByNpcTypeID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::ValidMobByNpcTypeID(THIS, get_id)"); { - EntityList * THIS; - bool RETVAL; - uint32 get_id = (uint32)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint32 get_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsMobSpawnedByNpcTypeID(get_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_GetNPCByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetNPCByID) -{ +XS(XS_EntityList_GetNPCByID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetNPCByID(THIS, id)"); { - EntityList * THIS; - NPC * RETVAL; - uint16 id = (uint16)SvUV(ST(1)); + EntityList *THIS; + NPC *RETVAL; + uint16 id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetNPCByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "NPC", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "NPC", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetNPCByNPCTypeID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetNPCByNPCTypeID) -{ +XS(XS_EntityList_GetNPCByNPCTypeID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetNPCByNPCTypeID(THIS, npc_id)"); { - EntityList * THIS; - NPC * RETVAL; - uint32 npc_id = (uint32)SvUV(ST(1)); + EntityList *THIS; + NPC *RETVAL; + uint32 npc_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetNPCByNPCTypeID(npc_id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "NPC", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "NPC", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetClientByName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetClientByName) -{ +XS(XS_EntityList_GetClientByName) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetClientByName(THIS, name)"); { - EntityList * THIS; - Client * RETVAL; - char * name = (char *)SvPV_nolen(ST(1)); + EntityList *THIS; + Client *RETVAL; + char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClientByName(name); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetClientByAccID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetClientByAccID) -{ +XS(XS_EntityList_GetClientByAccID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetClientByAccID(THIS, accid)"); + Perl_croak(aTHX_ "Usage: EntityList::GetClientByAccID(THIS, uint32 account_id)"); { - EntityList * THIS; - Client * RETVAL; - uint32 accid = (uint32)SvUV(ST(1)); + EntityList *THIS; + Client *RETVAL; + uint32 accid = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClientByAccID(accid); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetClientByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetClientByID) -{ +XS(XS_EntityList_GetClientByID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetClientByID(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::GetClientByID(THIS, uint16 client_id)"); { - EntityList * THIS; - Client * RETVAL; - uint16 id = (uint16)SvUV(ST(1)); + EntityList *THIS; + Client *RETVAL; + uint16 id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClientByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetClientByCharID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetClientByCharID) -{ +XS(XS_EntityList_GetClientByCharID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetClientByCharID(THIS, iCharID)"); + Perl_croak(aTHX_ "Usage: EntityList::GetClientByCharID(THIS, uint32 character_id)"); { - EntityList * THIS; - Client * RETVAL; - uint32 iCharID = (uint32)SvUV(ST(1)); + EntityList *THIS; + Client *RETVAL; + uint32 iCharID = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClientByCharID(iCharID); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetClientByWID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetClientByWID) -{ +XS(XS_EntityList_GetClientByWID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetClientByWID(THIS, iWID)"); + Perl_croak(aTHX_ "Usage: EntityList::GetClientByWID(THIS, uint32 wid)"); { - EntityList * THIS; - Client * RETVAL; - uint32 iWID = (uint32)SvUV(ST(1)); + EntityList *THIS; + Client *RETVAL; + uint32 iWID = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClientByWID(iWID); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetObjectByDBID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetObjectByDBID) -{ +XS(XS_EntityList_GetObjectByDBID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetObjectByDBID(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::GetObjectByDBID(THIS, uint32 database_id)"); { - EntityList * THIS; - Object * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Object *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetObjectByDBID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Object", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Object", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetObjectByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetObjectByID) -{ +XS(XS_EntityList_GetObjectByID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetObjectByID(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::GetObjectByID(THIS, uint32 entity_id)"); { - EntityList * THIS; - Object * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Object *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetObjectByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Object", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Object", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetDoorsByDBID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetDoorsByDBID) -{ +XS(XS_EntityList_GetDoorsByDBID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetDoorsByDBID(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::GetDoorsByDBID(THIS, uint32 database_id)"); { - EntityList * THIS; - Doors * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Doors *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDoorsByDBID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Doors", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Doors", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetDoorsByDoorID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetDoorsByDoorID) -{ +XS(XS_EntityList_GetDoorsByDoorID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetDoorsByDoorID(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::GetDoorsByDoorID(THIS, uint32 door_id)"); { - EntityList * THIS; - Doors * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Doors *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDoorsByDoorID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Doors", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Doors", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetDoorsByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetDoorsByID) -{ +XS(XS_EntityList_GetDoorsByID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetDoorsByID(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::GetDoorsByID(THIS, uint32 entity_id)"); { - EntityList * THIS; - Doors * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Doors *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDoorsByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Doors", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Doors", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_FindDoor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_FindDoor) -{ +XS(XS_EntityList_FindDoor) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::FindDoor(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::FindDoor(THIS, uint32 door_id)"); { - EntityList * THIS; - Doors * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Doors *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->FindDoor(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Doors", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Doors", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetGroupByMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetGroupByMob) -{ +XS(XS_EntityList_GetGroupByMob) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetGroupByMob(THIS, mob)"); + Perl_croak(aTHX_ "Usage: EntityList::GetGroupByMob(THIS, Mob* mob)"); { - EntityList * THIS; - Group * RETVAL; - Mob* mob; + EntityList *THIS; + Group *RETVAL; + Mob *mob; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); RETVAL = THIS->GetGroupByMob(mob); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Group", (void*)RETVAL); + sv_setref_pv(ST(0), "Group", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetGroupByClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetGroupByClient) -{ +XS(XS_EntityList_GetGroupByClient) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::GetGroupByClient(THIS, client)"); + Perl_croak(aTHX_ "Usage: EntityList::GetGroupByClient(THIS, Client* client)"); { - EntityList * THIS; - Group * RETVAL; - Client* client; + EntityList *THIS; + Group *RETVAL; + Client *client; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); RETVAL = THIS->GetGroupByClient(client); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Group", (void*)RETVAL); + sv_setref_pv(ST(0), "Group", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetGroupByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetGroupByID) -{ +XS(XS_EntityList_GetGroupByID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetGroupByID(THIS, id)"); { - EntityList * THIS; - Group * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Group *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGroupByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Group", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Group", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetGroupByLeaderName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetGroupByLeaderName) -{ +XS(XS_EntityList_GetGroupByLeaderName) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetGroupByLeaderName(THIS, leader)"); { - EntityList * THIS; - Group * RETVAL; - char* leader = (char *)SvPV_nolen(ST(1)); + EntityList *THIS; + Group *RETVAL; + char *leader = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGroupByLeaderName(leader); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Group", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Group", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetRaidByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetRaidByID) -{ +XS(XS_EntityList_GetRaidByID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetRaidByID(THIS, id)"); { - EntityList * THIS; - Raid * RETVAL; - uint32 id = (uint32)SvUV(ST(1)); + EntityList *THIS; + Raid *RETVAL; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRaidByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Raid", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Raid", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetRaidByClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetRaidByClient) -{ +XS(XS_EntityList_GetRaidByClient) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetRaidByClient(THIS, client)"); { - EntityList * THIS; - Raid * RETVAL; - Client* client; + EntityList *THIS; + Raid *RETVAL; + Client *client; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); RETVAL = THIS->GetRaidByClient(client); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Raid", (void*)RETVAL); + sv_setref_pv(ST(0), "Raid", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetCorpseByOwner); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetCorpseByOwner) -{ +XS(XS_EntityList_GetCorpseByOwner) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetCorpseByOwner(THIS, client)"); { - EntityList * THIS; - Corpse * RETVAL; - Client* client; + EntityList *THIS; + Corpse *RETVAL; + Client *client; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseByOwner(client); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Corpse", (void*)RETVAL); + sv_setref_pv(ST(0), "Corpse", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetCorpseByID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetCorpseByID) -{ +XS(XS_EntityList_GetCorpseByID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetCorpseByID(THIS, id)"); { - EntityList * THIS; - Corpse * RETVAL; - uint16 id = (uint16)SvUV(ST(1)); + EntityList *THIS; + Corpse *RETVAL; + uint16 id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseByID(id); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Corpse", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Corpse", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetCorpseByName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetCorpseByName) -{ +XS(XS_EntityList_GetCorpseByName) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::GetCorpseByName(THIS, name)"); { - EntityList * THIS; - Corpse * RETVAL; - char* name = (char *)SvPV_nolen(ST(1)); + EntityList *THIS; + Corpse *RETVAL; + char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseByName(name); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Corpse", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Corpse", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_ClearClientPetitionQueue); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_ClearClientPetitionQueue) -{ +XS(XS_EntityList_ClearClientPetitionQueue) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::ClearClientPetitionQueue(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearClientPetitionQueue(); @@ -831,32 +773,29 @@ XS(XS_EntityList_ClearClientPetitionQueue) } XS(XS_EntityList_CanAddHateForMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_CanAddHateForMob) -{ +XS(XS_EntityList_CanAddHateForMob) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::CanAddHateForMob(THIS, p)"); + Perl_croak(aTHX_ "Usage: EntityList::CanAddHateForMob(THIS, Mob* target)"); { - EntityList * THIS; - bool RETVAL; - Mob * p; + EntityList *THIS; + bool RETVAL; + Mob *p; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - p = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + p = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "p is not of type Mob"); - if(p == nullptr) + if (p == nullptr) Perl_croak(aTHX_ "p is nullptr, avoiding crash."); RETVAL = THIS->CanAddHateForMob(p); @@ -867,21 +806,19 @@ XS(XS_EntityList_CanAddHateForMob) } XS(XS_EntityList_Clear); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_Clear) -{ +XS(XS_EntityList_Clear) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::Clear(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Clear(); @@ -890,237 +827,219 @@ XS(XS_EntityList_Clear) } XS(XS_EntityList_RemoveMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveMob) -{ +XS(XS_EntityList_RemoveMob) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveMob(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveMob(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveClient) -{ +XS(XS_EntityList_RemoveClient) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveClient(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveClient(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveNPC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveNPC) -{ +XS(XS_EntityList_RemoveNPC) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveNPC(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveNPC(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveGroup) -{ +XS(XS_EntityList_RemoveGroup) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveGroup(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint32 delete_id = (uint32)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint32 delete_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveGroup(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveCorpse); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveCorpse) -{ +XS(XS_EntityList_RemoveCorpse) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveCorpse(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveCorpse(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveDoor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveDoor) -{ +XS(XS_EntityList_RemoveDoor) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveDoor(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveDoor(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveTrap); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveTrap) -{ +XS(XS_EntityList_RemoveTrap) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveTrap(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveTrap(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveObject); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveObject) -{ +XS(XS_EntityList_RemoveObject) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: EntityList::RemoveObject(THIS, delete_id)"); { - EntityList * THIS; - bool RETVAL; - uint16 delete_id = (uint16)SvUV(ST(1)); + EntityList *THIS; + bool RETVAL; + uint16 delete_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RemoveObject(delete_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_EntityList_RemoveAllMobs); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllMobs) -{ +XS(XS_EntityList_RemoveAllMobs) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllMobs(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllMobs(); @@ -1129,21 +1048,19 @@ XS(XS_EntityList_RemoveAllMobs) } XS(XS_EntityList_RemoveAllClients); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllClients) -{ +XS(XS_EntityList_RemoveAllClients) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllClients(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllClients(); @@ -1152,21 +1069,19 @@ XS(XS_EntityList_RemoveAllClients) } XS(XS_EntityList_RemoveAllNPCs); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllNPCs) -{ +XS(XS_EntityList_RemoveAllNPCs) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllNPCs(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllNPCs(); @@ -1175,21 +1090,19 @@ XS(XS_EntityList_RemoveAllNPCs) } XS(XS_EntityList_RemoveAllGroups); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllGroups) -{ +XS(XS_EntityList_RemoveAllGroups) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllGroups(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllGroups(); @@ -1198,21 +1111,19 @@ XS(XS_EntityList_RemoveAllGroups) } XS(XS_EntityList_RemoveAllCorpses); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllCorpses) -{ +XS(XS_EntityList_RemoveAllCorpses) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllCorpses(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllCorpses(); @@ -1221,21 +1132,19 @@ XS(XS_EntityList_RemoveAllCorpses) } XS(XS_EntityList_RemoveAllDoors); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllDoors) -{ +XS(XS_EntityList_RemoveAllDoors) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllDoors(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllDoors(); @@ -1244,21 +1153,19 @@ XS(XS_EntityList_RemoveAllDoors) } XS(XS_EntityList_RemoveAllTraps); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllTraps) -{ +XS(XS_EntityList_RemoveAllTraps) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllTraps(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllTraps(); @@ -1267,21 +1174,19 @@ XS(XS_EntityList_RemoveAllTraps) } XS(XS_EntityList_RemoveAllObjects); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveAllObjects) -{ +XS(XS_EntityList_RemoveAllObjects) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::RemoveAllObjects(THIS)"); { - EntityList * THIS; + EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveAllObjects(); @@ -1290,24 +1195,22 @@ XS(XS_EntityList_RemoveAllObjects) } XS(XS_EntityList_Message); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_Message) -{ +XS(XS_EntityList_Message) { dXSARGS; if (items < 4) - Perl_croak(aTHX_ "Usage: EntityList::Message(THIS, to_guilddbid, type, message, ...)"); + Perl_croak(aTHX_ "Usage: EntityList::Message(THIS, uint32 guild_id, uint32 emote_color_type, string message)"); { - EntityList * THIS; - uint32 to_guilddbid = (uint32)SvUV(ST(1)); - uint32 type = (uint32)SvUV(ST(2)); - char* message = (char *)SvPV_nolen(ST(3)); + EntityList *THIS; + uint32 to_guilddbid = (uint32) SvUV(ST(1)); + uint32 type = (uint32) SvUV(ST(2)); + char *message = (char *) SvPV_nolen(ST(3)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Message(to_guilddbid, type, message); @@ -1316,25 +1219,24 @@ XS(XS_EntityList_Message) } XS(XS_EntityList_MessageStatus); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_MessageStatus) -{ +XS(XS_EntityList_MessageStatus) { dXSARGS; if (items < 5) - Perl_croak(aTHX_ "Usage: EntityList::MessageStatus(THIS, to_guilddbid, to_minstatus, type, message, ...)"); + Perl_croak(aTHX_ + "Usage: EntityList::MessageStatus(THIS, uint32 guild_id, uint32 emote_color_type, string message)"); { - EntityList * THIS; - uint32 to_guilddbid = (uint32)SvUV(ST(1)); - int to_minstatus = (int)SvIV(ST(2)); - uint32 type = (uint32)SvUV(ST(3)); - char* message = (char *)SvPV_nolen(ST(4)); + EntityList *THIS; + uint32 to_guilddbid = (uint32) SvUV(ST(1)); + int to_minstatus = (int) SvIV(ST(2)); + uint32 type = (uint32) SvUV(ST(3)); + char *message = (char *) SvPV_nolen(ST(4)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->MessageStatus(to_guilddbid, to_minstatus, type, message); @@ -1343,35 +1245,33 @@ XS(XS_EntityList_MessageStatus) } XS(XS_EntityList_MessageClose); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_MessageClose) -{ +XS(XS_EntityList_MessageClose) { dXSARGS; if (items < 6) - Perl_croak(aTHX_ "Usage: EntityList::MessageClose(THIS, sender, skipsender, dist, type, message, ...)"); + Perl_croak(aTHX_ + "Usage: EntityList::MessageClose(THIS, Mob* sender, bool skip_sender, float distance, uint32 emote_color_type, string message)"); { - EntityList * THIS; - Mob* sender; - bool skipsender = (bool)SvTRUE(ST(2)); - float dist = (float)SvNV(ST(3)); - uint32 type = (uint32)SvUV(ST(4)); - char* message = (char *)SvPV_nolen(ST(5)); + EntityList *THIS; + Mob *sender; + bool skipsender = (bool) SvTRUE(ST(2)); + float dist = (float) SvNV(ST(3)); + uint32 type = (uint32) SvUV(ST(4)); + char *message = (char *) SvPV_nolen(ST(5)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - sender = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + sender = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "sender is not of type Mob"); - if(sender == nullptr) + if (sender == nullptr) Perl_croak(aTHX_ "sender is nullptr, avoiding crash."); THIS->MessageClose(sender, skipsender, dist, type, message); @@ -1380,31 +1280,28 @@ XS(XS_EntityList_MessageClose) } XS(XS_EntityList_RemoveFromTargets); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveFromTargets) -{ +XS(XS_EntityList_RemoveFromTargets) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::RemoveFromTargets(THIS, mob)"); + Perl_croak(aTHX_ "Usage: EntityList::RemoveFromTargets(THIS, Mob* target)"); { - EntityList * THIS; - Mob* mob; + EntityList *THIS; + Mob *mob; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); THIS->RemoveFromTargets(mob); @@ -1413,41 +1310,37 @@ XS(XS_EntityList_RemoveFromTargets) } XS(XS_EntityList_ReplaceWithTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_ReplaceWithTarget) -{ +XS(XS_EntityList_ReplaceWithTarget) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: EntityList::ReplaceWithTarget(THIS, pOldMob, pNewTarget)"); + Perl_croak(aTHX_ "Usage: EntityList::ReplaceWithTarget(THIS, Mob* old_mob, Mob* new_target)"); { - EntityList * THIS; - Mob* pOldMob; - Mob* pNewTarget; + EntityList *THIS; + Mob *pOldMob; + Mob *pNewTarget; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - pOldMob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + pOldMob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "pOldMob is not of type Mob"); - if(pOldMob == nullptr) + if (pOldMob == nullptr) Perl_croak(aTHX_ "pOldMob is nullptr, avoiding crash."); if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - pNewTarget = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + pNewTarget = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "pNewTarget is not of type Mob"); - if(pNewTarget == nullptr) + if (pNewTarget == nullptr) Perl_croak(aTHX_ "pNewTarget is nullptr, avoiding crash."); THIS->ReplaceWithTarget(pOldMob, pNewTarget); @@ -1456,31 +1349,28 @@ XS(XS_EntityList_ReplaceWithTarget) } XS(XS_EntityList_OpenDoorsNear); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_OpenDoorsNear) -{ +XS(XS_EntityList_OpenDoorsNear) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::OpenDoorsNear(THIS, opener)"); + Perl_croak(aTHX_ "Usage: EntityList::OpenDoorsNear(THIS, NPC* opener)"); { - EntityList * THIS; - NPC* opener; + EntityList *THIS; + NPC *opener; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - opener = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + opener = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "opener is not of type NPC"); - if(opener == nullptr) + if (opener == nullptr) Perl_croak(aTHX_ "opener is nullptr, avoiding crash."); THIS->OpenDoorsNear(opener); @@ -1489,67 +1379,66 @@ XS(XS_EntityList_OpenDoorsNear) } XS(XS_EntityList_MakeNameUnique); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_MakeNameUnique) -{ +XS(XS_EntityList_MakeNameUnique) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::MakeNameUnique(THIS, name)"); + Perl_croak(aTHX_ "Usage: EntityList::MakeNameUnique(THIS, string name)"); { - EntityList * THIS; - char * RETVAL; + EntityList *THIS; + char *RETVAL; dXSTARG; - char* name = (char *)SvPV_nolen(ST(1)); + char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->MakeNameUnique(name); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_EntityList_RemoveNumbers); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveNumbers) -{ +XS(XS_EntityList_RemoveNumbers) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::RemoveNumbers(CLASS, name)"); + Perl_croak(aTHX_ "Usage: EntityListDeprecated::RemoveNumbers(CLASS, name)"); { - char * RETVAL; + char *RETVAL; dXSTARG; - char* name = (char *)SvPV_nolen(ST(1)); + char *name = (char *) SvPV_nolen(ST(1)); RETVAL = EntityList::RemoveNumbers(name); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_EntityList_SignalMobsByNPCID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_SignalMobsByNPCID) -{ +XS(XS_EntityList_SignalMobsByNPCID) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: EntityList::SignalMobsByNPCID(THIS, npc_type, signal_id)"); + Perl_croak(aTHX_ "Usage: EntityList::SignalMobsByNPCID(THIS, uint32 npc_type_id, int signal_id)"); { - EntityList * THIS; - uint32 npc_type = (uint32)SvUV(ST(1)); - int signal_id = (int)SvIV(ST(2)); + EntityList *THIS; + uint32 npc_type = (uint32) SvUV(ST(1)); + int signal_id = (int) SvIV(ST(2)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SignalMobsByNPCID(npc_type, signal_id); @@ -1558,22 +1447,20 @@ XS(XS_EntityList_SignalMobsByNPCID) } XS(XS_EntityList_RemoveEntity); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveEntity) -{ +XS(XS_EntityList_RemoveEntity) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::RemoveEntity(THIS, id)"); + Perl_croak(aTHX_ "Usage: EntityList::RemoveEntity(THIS, uint16 id)"); { - EntityList * THIS; - uint16 id = (uint16)SvUV(ST(1)); + EntityList *THIS; + uint16 id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveEntity(id); @@ -1582,83 +1469,78 @@ XS(XS_EntityList_RemoveEntity) } XS(XS_EntityList_DeleteNPCCorpses); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_DeleteNPCCorpses) -{ +XS(XS_EntityList_DeleteNPCCorpses) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::DeleteNPCCorpses(THIS)"); { - EntityList * THIS; - int32 RETVAL; + EntityList *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DeleteNPCCorpses(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_EntityList_DeletePlayerCorpses); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_DeletePlayerCorpses) -{ +XS(XS_EntityList_DeletePlayerCorpses) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: EntityList::DeletePlayerCorpses(THIS)"); { - EntityList * THIS; - int32 RETVAL; + EntityList *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DeletePlayerCorpses(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_EntityList_HalveAggro); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_HalveAggro) -{ +XS(XS_EntityList_HalveAggro) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::HalveAggro(THIS, who)"); + Perl_croak(aTHX_ "Usage: EntityList::HalveAggro(THIS, Mob* target)"); { - EntityList * THIS; - Mob* who; + EntityList *THIS; + Mob *who; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - who = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + who = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "who is not of type Mob"); - if(who == nullptr) + if (who == nullptr) Perl_croak(aTHX_ "who is nullptr, avoiding crash."); THIS->HalveAggro(who); @@ -1667,31 +1549,28 @@ XS(XS_EntityList_HalveAggro) } XS(XS_EntityList_DoubleAggro); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_DoubleAggro) -{ +XS(XS_EntityList_DoubleAggro) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::DoubleAggro(THIS, who)"); + Perl_croak(aTHX_ "Usage: EntityList::DoubleAggro(THIS, *Mob target)"); { - EntityList * THIS; - Mob* who; + EntityList *THIS; + Mob *who; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - who = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + who = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "who is not of type Mob"); - if(who == nullptr) + if (who == nullptr) Perl_croak(aTHX_ "who is nullptr, avoiding crash."); THIS->DoubleAggro(who); @@ -1700,31 +1579,28 @@ XS(XS_EntityList_DoubleAggro) } XS(XS_EntityList_ClearFeignAggro); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_ClearFeignAggro) -{ +XS(XS_EntityList_ClearFeignAggro) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::ClearFeignAggro(THIS, targ)"); + Perl_croak(aTHX_ "Usage: EntityList::ClearFeignAggro(THIS, Mob* target)"); { - EntityList * THIS; - Mob* targ; + EntityList *THIS; + Mob *targ; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - targ = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + targ = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "targ is not of type Mob"); - if(targ == nullptr) + if (targ == nullptr) Perl_croak(aTHX_ "targ is nullptr, avoiding crash."); THIS->ClearFeignAggro(targ); @@ -1733,32 +1609,29 @@ XS(XS_EntityList_ClearFeignAggro) } XS(XS_EntityList_Fighting); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_Fighting) -{ +XS(XS_EntityList_Fighting) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::Fighting(THIS, targ)"); + Perl_croak(aTHX_ "Usage: EntityList::Fighting(THIS, Mob* target)"); { - EntityList * THIS; - bool RETVAL; - Mob* targ; + EntityList *THIS; + bool RETVAL; + Mob *targ; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - targ = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + targ = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "targ is not of type Mob"); - if(targ == nullptr) + if (targ == nullptr) Perl_croak(aTHX_ "targ is nullptr, avoiding crash."); RETVAL = THIS->Fighting(targ); @@ -1769,38 +1642,35 @@ XS(XS_EntityList_Fighting) } XS(XS_EntityList_RemoveFromHateLists); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_RemoveFromHateLists) -{ +XS(XS_EntityList_RemoveFromHateLists) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: EntityList::RemoveFromHateLists(THIS, mob, settoone= false)"); + Perl_croak(aTHX_ "Usage: EntityList::RemoveFromHateLists(THIS, Mob* mob, [bool set_to_one = false])"); { - EntityList * THIS; - Mob* mob; - bool settoone; + EntityList *THIS; + Mob *mob; + bool settoone; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); if (items < 3) settoone = false; else { - settoone = (bool)SvTRUE(ST(2)); + settoone = (bool) SvTRUE(ST(2)); } THIS->RemoveFromHateLists(mob, settoone); @@ -1809,34 +1679,32 @@ XS(XS_EntityList_RemoveFromHateLists) } XS(XS_EntityList_MessageGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_MessageGroup) -{ +XS(XS_EntityList_MessageGroup) { dXSARGS; if (items < 5) - Perl_croak(aTHX_ "Usage: EntityList::MessageGroup(THIS, sender, skipclose, type, message, ...)"); + Perl_croak(aTHX_ + "Usage: EntityList::MessageGroup(THIS, Mob* sender, bool skip_close, uint32 emote_color_type, string message)"); { - EntityList * THIS; - Mob* sender; - bool skipclose = (bool)SvTRUE(ST(2)); - uint32 type = (uint32)SvUV(ST(3)); - char* message = (char *)SvPV_nolen(ST(4)); + EntityList *THIS; + Mob *sender; + bool skipclose = (bool) SvTRUE(ST(2)); + uint32 type = (uint32) SvUV(ST(3)); + char *message = (char *) SvPV_nolen(ST(4)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - sender = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + sender = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "sender is not of type Mob"); - if(sender == nullptr) + if (sender == nullptr) Perl_croak(aTHX_ "sender is nullptr, avoiding crash."); THIS->MessageGroup(sender, skipclose, type, message); @@ -1845,46 +1713,43 @@ XS(XS_EntityList_MessageGroup) } XS(XS_EntityList_GetRandomClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetRandomClient) -{ +XS(XS_EntityList_GetRandomClient) { dXSARGS; if ((items < 5) || (items > 6)) - Perl_croak(aTHX_ "Usage: EntityList::GetRandomClient(THIS, x, y, z, distance, excludeclient = nullptr)"); + Perl_croak(aTHX_ + "Usage: EntityList::GetRandomClient(THIS, float x, float y, float z, float distance, [Client* exclude_client = nullptr])"); { EntityList *THIS; - Client *RETVAL, *c = nullptr; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float d = (float)SvNV(ST(4)); + Client *RETVAL, *c = nullptr; + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); + float d = (float) SvNV(ST(4)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items == 6) - { + if (items == 6) { if (sv_derived_from(ST(5), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(5))); - c = INT2PTR(Client *,tmp); + IV tmp = SvIV((SV *) SvRV(ST(5))); + c = INT2PTR(Client *, tmp); } } - RETVAL = entity_list.GetRandomClient(glm::vec3(x, y, z), d * d, c); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + RETVAL = entity_list.GetRandomClient(glm::vec3(x, y, z), d * d, c); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_EntityList_GetMobList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetMobList) -{ +XS(XS_EntityList_GetMobList) { dXSARGS; int num_mobs = 0; if (items != 1) @@ -1893,24 +1758,22 @@ XS(XS_EntityList_GetMobList) EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - std::list mob_list; + std::list mob_list; entity_list.GetMobList(mob_list); auto iter = mob_list.begin(); - while(iter != mob_list.end()) - { + while (iter != mob_list.end()) { Mob *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)entry); + sv_setref_pv(ST(0), "Mob", (void *) entry); XPUSHs(ST(0)); num_mobs++; iter++; @@ -1920,8 +1783,7 @@ XS(XS_EntityList_GetMobList) } XS(XS_EntityList_GetClientList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetClientList) -{ +XS(XS_EntityList_GetClientList) { dXSARGS; int num_clients = 0; if (items != 1) @@ -1930,24 +1792,22 @@ XS(XS_EntityList_GetClientList) EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - std::list client_list; + std::list client_list; entity_list.GetClientList(client_list); auto iter = client_list.begin(); - while(iter != client_list.end()) - { + while (iter != client_list.end()) { Client *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)entry); + sv_setref_pv(ST(0), "Client", (void *) entry); XPUSHs(ST(0)); num_clients++; iter++; @@ -1957,8 +1817,7 @@ XS(XS_EntityList_GetClientList) } XS(XS_EntityList_GetNPCList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetNPCList) -{ +XS(XS_EntityList_GetNPCList) { dXSARGS; int num_npcs = 0; if (items != 1) @@ -1967,24 +1826,22 @@ XS(XS_EntityList_GetNPCList) EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - std::list npc_list; + std::list npc_list; entity_list.GetNPCList(npc_list); auto iter = npc_list.begin(); - while(iter != npc_list.end()) - { + while (iter != npc_list.end()) { NPC *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "NPC", (void*)entry); + sv_setref_pv(ST(0), "NPC", (void *) entry); XPUSHs(ST(0)); num_npcs++; iter++; @@ -1994,8 +1851,7 @@ XS(XS_EntityList_GetNPCList) } XS(XS_EntityList_GetCorpseList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetCorpseList) -{ +XS(XS_EntityList_GetCorpseList) { dXSARGS; int num_corpses = 0; if (items != 1) @@ -2004,24 +1860,22 @@ XS(XS_EntityList_GetCorpseList) EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - std::list corpse_list; + std::list corpse_list; entity_list.GetCorpseList(corpse_list); auto iter = corpse_list.begin(); - while(iter != corpse_list.end()) - { + while (iter != corpse_list.end()) { Corpse *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Corpse", (void*)entry); + sv_setref_pv(ST(0), "Corpse", (void *) entry); XPUSHs(ST(0)); num_corpses++; iter++; @@ -2031,8 +1885,7 @@ XS(XS_EntityList_GetCorpseList) } XS(XS_EntityList_GetObjectList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetObjectList) -{ +XS(XS_EntityList_GetObjectList) { dXSARGS; int num_objects = 0; if (items != 1) @@ -2041,24 +1894,22 @@ XS(XS_EntityList_GetObjectList) EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - std::list object_list; + std::list object_list; entity_list.GetObjectList(object_list); auto iter = object_list.begin(); - while(iter != object_list.end()) - { + while (iter != object_list.end()) { Object *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Object", (void*)entry); + sv_setref_pv(ST(0), "Object", (void *) entry); XPUSHs(ST(0)); num_objects++; iter++; @@ -2068,8 +1919,7 @@ XS(XS_EntityList_GetObjectList) } XS(XS_EntityList_GetDoorsList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_GetDoorsList) -{ +XS(XS_EntityList_GetDoorsList) { dXSARGS; int num_objects = 0; if (items != 1) @@ -2078,24 +1928,22 @@ XS(XS_EntityList_GetDoorsList) EntityList *THIS; if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - std::list door_list; + std::list door_list; entity_list.GetDoorsList(door_list); auto iter = door_list.begin(); - while(iter != door_list.end()) - { + while (iter != door_list.end()) { Doors *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Doors", (void*)entry); + sv_setref_pv(ST(0), "Doors", (void *) entry); XPUSHs(ST(0)); num_objects++; iter++; @@ -2105,23 +1953,21 @@ XS(XS_EntityList_GetDoorsList) } XS(XS_EntityList_SignalAllClients); /* prototype to pass -Wmissing-prototypes */ -XS(XS_EntityList_SignalAllClients) -{ +XS(XS_EntityList_SignalAllClients) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: EntityList::SignalAllClients(THIS, data)"); + Perl_croak(aTHX_ "Usage: EntityList::SignalAllClients(THIS, uint32 data)"); { EntityList *THIS; - uint32 data = (uint32)SvUV(ST(1)); + uint32 data = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EntityList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EntityList"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); entity_list.SignalAllClients(data); @@ -2133,14 +1979,13 @@ XS(XS_EntityList_SignalAllClients) extern "C" #endif XS(boot_EntityList); /* prototype to pass -Wmissing-prototypes */ -XS(boot_EntityList) -{ +XS(boot_EntityList) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; @@ -2148,80 +1993,80 @@ XS(boot_EntityList) - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "GetMobID"), XS_EntityList_GetMobID, file, "$$"); - newXSproto(strcpy(buf, "GetMob"), XS_EntityList_GetMob, file, "$$"); - newXSproto(strcpy(buf, "GetMobByID"), XS_EntityList_GetMobByID, file, "$$"); - newXSproto(strcpy(buf, "GetMobByNpcTypeID"), XS_EntityList_GetMobByNpcTypeID, file, "$$"); - newXSproto(strcpy(buf, "IsMobSpawnedByNpcTypeID"), XS_EntityList_IsMobSpawnedByNpcTypeID, file, "$$"); - newXSproto(strcpy(buf, "GetNPCByID"), XS_EntityList_GetNPCByID, file, "$$"); - newXSproto(strcpy(buf, "GetNPCByNPCTypeID"), XS_EntityList_GetNPCByNPCTypeID, file, "$$"); - newXSproto(strcpy(buf, "GetClientByName"), XS_EntityList_GetClientByName, file, "$$"); - newXSproto(strcpy(buf, "GetClientByAccID"), XS_EntityList_GetClientByAccID, file, "$$"); - newXSproto(strcpy(buf, "GetClientByID"), XS_EntityList_GetClientByID, file, "$$"); - newXSproto(strcpy(buf, "GetClientByCharID"), XS_EntityList_GetClientByCharID, file, "$$"); - newXSproto(strcpy(buf, "GetClientByWID"), XS_EntityList_GetClientByWID, file, "$$"); - newXSproto(strcpy(buf, "GetObjectByID"), XS_EntityList_GetObjectByID, file, "$"); - newXSproto(strcpy(buf, "GetObjectByDBID"), XS_EntityList_GetObjectByDBID, file, "$"); - newXSproto(strcpy(buf, "GetDoorsByID"), XS_EntityList_GetDoorsByID, file, "$$"); - newXSproto(strcpy(buf, "GetDoorsByDBID"), XS_EntityList_GetDoorsByDBID, file, "$$"); - newXSproto(strcpy(buf, "GetDoorsByDoorID"), XS_EntityList_GetDoorsByDoorID, file, "$$"); - newXSproto(strcpy(buf, "FindDoor"), XS_EntityList_FindDoor, file, "$$"); - newXSproto(strcpy(buf, "GetGroupByMob"), XS_EntityList_GetGroupByMob, file, "$$"); - newXSproto(strcpy(buf, "GetGroupByClient"), XS_EntityList_GetGroupByClient, file, "$$"); - newXSproto(strcpy(buf, "GetGroupByID"), XS_EntityList_GetGroupByID, file, "$$"); - newXSproto(strcpy(buf, "GetGroupByLeaderName"), XS_EntityList_GetGroupByLeaderName, file, "$$"); - newXSproto(strcpy(buf, "GetRaidByID"), XS_EntityList_GetRaidByID, file, "$$"); - newXSproto(strcpy(buf, "GetRaidByClient"), XS_EntityList_GetRaidByClient, file, "$$"); - newXSproto(strcpy(buf, "GetCorpseByOwner"), XS_EntityList_GetCorpseByOwner, file, "$$"); - newXSproto(strcpy(buf, "GetCorpseByID"), XS_EntityList_GetCorpseByID, file, "$$"); - newXSproto(strcpy(buf, "GetCorpseByName"), XS_EntityList_GetCorpseByName, file, "$$"); - newXSproto(strcpy(buf, "ClearClientPetitionQueue"), XS_EntityList_ClearClientPetitionQueue, file, "$"); - newXSproto(strcpy(buf, "CanAddHateForMob"), XS_EntityList_CanAddHateForMob, file, "$$"); - newXSproto(strcpy(buf, "Clear"), XS_EntityList_Clear, file, "$"); - newXSproto(strcpy(buf, "RemoveMob"), XS_EntityList_RemoveMob, file, "$$"); - newXSproto(strcpy(buf, "RemoveClient"), XS_EntityList_RemoveClient, file, "$$"); - newXSproto(strcpy(buf, "RemoveNPC"), XS_EntityList_RemoveNPC, file, "$$"); - newXSproto(strcpy(buf, "RemoveGroup"), XS_EntityList_RemoveGroup, file, "$$"); - newXSproto(strcpy(buf, "RemoveCorpse"), XS_EntityList_RemoveCorpse, file, "$$"); - newXSproto(strcpy(buf, "RemoveDoor"), XS_EntityList_RemoveDoor, file, "$$"); - newXSproto(strcpy(buf, "RemoveTrap"), XS_EntityList_RemoveTrap, file, "$$"); - newXSproto(strcpy(buf, "RemoveObject"), XS_EntityList_RemoveObject, file, "$$"); - newXSproto(strcpy(buf, "RemoveAllMobs"), XS_EntityList_RemoveAllMobs, file, "$"); - newXSproto(strcpy(buf, "RemoveAllClients"), XS_EntityList_RemoveAllClients, file, "$"); - newXSproto(strcpy(buf, "RemoveAllNPCs"), XS_EntityList_RemoveAllNPCs, file, "$"); - newXSproto(strcpy(buf, "RemoveAllGroups"), XS_EntityList_RemoveAllGroups, file, "$"); - newXSproto(strcpy(buf, "RemoveAllCorpses"), XS_EntityList_RemoveAllCorpses, file, "$"); - newXSproto(strcpy(buf, "RemoveAllDoors"), XS_EntityList_RemoveAllDoors, file, "$"); - newXSproto(strcpy(buf, "RemoveAllTraps"), XS_EntityList_RemoveAllTraps, file, "$"); - newXSproto(strcpy(buf, "RemoveAllObjects"), XS_EntityList_RemoveAllObjects, file, "$"); - newXSproto(strcpy(buf, "Message"), XS_EntityList_Message, file, "$$$$;@"); - newXSproto(strcpy(buf, "MessageStatus"), XS_EntityList_MessageStatus, file, "$$$$$;@"); - newXSproto(strcpy(buf, "MessageClose"), XS_EntityList_MessageClose, file, "$$$$$$;@"); - newXSproto(strcpy(buf, "RemoveFromTargets"), XS_EntityList_RemoveFromTargets, file, "$$"); - newXSproto(strcpy(buf, "ReplaceWithTarget"), XS_EntityList_ReplaceWithTarget, file, "$$$"); - newXSproto(strcpy(buf, "OpenDoorsNear"), XS_EntityList_OpenDoorsNear, file, "$$"); - newXSproto(strcpy(buf, "MakeNameUnique"), XS_EntityList_MakeNameUnique, file, "$$"); - newXSproto(strcpy(buf, "RemoveNumbers"), XS_EntityList_RemoveNumbers, file, "$$"); - newXSproto(strcpy(buf, "SignalMobsByNPCID"), XS_EntityList_SignalMobsByNPCID, file, "$$$"); - newXSproto(strcpy(buf, "RemoveEntity"), XS_EntityList_RemoveEntity, file, "$$"); - newXSproto(strcpy(buf, "DeleteNPCCorpses"), XS_EntityList_DeleteNPCCorpses, file, "$"); - newXSproto(strcpy(buf, "DeletePlayerCorpses"), XS_EntityList_DeletePlayerCorpses, file, "$"); - newXSproto(strcpy(buf, "HalveAggro"), XS_EntityList_HalveAggro, file, "$$"); - newXSproto(strcpy(buf, "DoubleAggro"), XS_EntityList_DoubleAggro, file, "$$"); - newXSproto(strcpy(buf, "ClearFeignAggro"), XS_EntityList_ClearFeignAggro, file, "$$"); - newXSproto(strcpy(buf, "Fighting"), XS_EntityList_Fighting, file, "$$"); - newXSproto(strcpy(buf, "RemoveFromHateLists"), XS_EntityList_RemoveFromHateLists, file, "$$;$"); - newXSproto(strcpy(buf, "MessageGroup"), XS_EntityList_MessageGroup, file, "$$$$$;@"); - newXSproto(strcpy(buf, "GetRandomClient"), XS_EntityList_GetRandomClient, file, "$$$$$;$"); - newXSproto(strcpy(buf, "GetMobList"), XS_EntityList_GetMobList, file, "$"); - newXSproto(strcpy(buf, "GetClientList"), XS_EntityList_GetClientList, file, "$"); - newXSproto(strcpy(buf, "GetNPCList"), XS_EntityList_GetNPCList, file, "$"); - newXSproto(strcpy(buf, "GetCorpseList"), XS_EntityList_GetCorpseList, file, "$"); - newXSproto(strcpy(buf, "GetObjectList"), XS_EntityList_GetObjectList, file, "$"); - newXSproto(strcpy(buf, "GetDoorsList"), XS_EntityList_GetDoorsList, file, "$"); - newXSproto(strcpy(buf, "SignalAllClients"), XS_EntityList_SignalAllClients, file, "$$"); + newXSproto(strcpy(buf, "GetMobID"), XS_EntityList_GetMobID, file, "$$"); + newXSproto(strcpy(buf, "GetMob"), XS_EntityList_GetMob, file, "$$"); + newXSproto(strcpy(buf, "GetMobByID"), XS_EntityList_GetMobByID, file, "$$"); + newXSproto(strcpy(buf, "GetMobByNpcTypeID"), XS_EntityList_GetMobByNpcTypeID, file, "$$"); + newXSproto(strcpy(buf, "IsMobSpawnedByNpcTypeID"), XS_EntityList_IsMobSpawnedByNpcTypeID, file, "$$"); + newXSproto(strcpy(buf, "GetNPCByID"), XS_EntityList_GetNPCByID, file, "$$"); + newXSproto(strcpy(buf, "GetNPCByNPCTypeID"), XS_EntityList_GetNPCByNPCTypeID, file, "$$"); + newXSproto(strcpy(buf, "GetClientByName"), XS_EntityList_GetClientByName, file, "$$"); + newXSproto(strcpy(buf, "GetClientByAccID"), XS_EntityList_GetClientByAccID, file, "$$"); + newXSproto(strcpy(buf, "GetClientByID"), XS_EntityList_GetClientByID, file, "$$"); + newXSproto(strcpy(buf, "GetClientByCharID"), XS_EntityList_GetClientByCharID, file, "$$"); + newXSproto(strcpy(buf, "GetClientByWID"), XS_EntityList_GetClientByWID, file, "$$"); + newXSproto(strcpy(buf, "GetObjectByID"), XS_EntityList_GetObjectByID, file, "$"); + newXSproto(strcpy(buf, "GetObjectByDBID"), XS_EntityList_GetObjectByDBID, file, "$"); + newXSproto(strcpy(buf, "GetDoorsByID"), XS_EntityList_GetDoorsByID, file, "$$"); + newXSproto(strcpy(buf, "GetDoorsByDBID"), XS_EntityList_GetDoorsByDBID, file, "$$"); + newXSproto(strcpy(buf, "GetDoorsByDoorID"), XS_EntityList_GetDoorsByDoorID, file, "$$"); + newXSproto(strcpy(buf, "FindDoor"), XS_EntityList_FindDoor, file, "$$"); + newXSproto(strcpy(buf, "GetGroupByMob"), XS_EntityList_GetGroupByMob, file, "$$"); + newXSproto(strcpy(buf, "GetGroupByClient"), XS_EntityList_GetGroupByClient, file, "$$"); + newXSproto(strcpy(buf, "GetGroupByID"), XS_EntityList_GetGroupByID, file, "$$"); + newXSproto(strcpy(buf, "GetGroupByLeaderName"), XS_EntityList_GetGroupByLeaderName, file, "$$"); + newXSproto(strcpy(buf, "GetRaidByID"), XS_EntityList_GetRaidByID, file, "$$"); + newXSproto(strcpy(buf, "GetRaidByClient"), XS_EntityList_GetRaidByClient, file, "$$"); + newXSproto(strcpy(buf, "GetCorpseByOwner"), XS_EntityList_GetCorpseByOwner, file, "$$"); + newXSproto(strcpy(buf, "GetCorpseByID"), XS_EntityList_GetCorpseByID, file, "$$"); + newXSproto(strcpy(buf, "GetCorpseByName"), XS_EntityList_GetCorpseByName, file, "$$"); + newXSproto(strcpy(buf, "ClearClientPetitionQueue"), XS_EntityList_ClearClientPetitionQueue, file, "$"); + newXSproto(strcpy(buf, "CanAddHateForMob"), XS_EntityList_CanAddHateForMob, file, "$$"); + newXSproto(strcpy(buf, "Clear"), XS_EntityList_Clear, file, "$"); + newXSproto(strcpy(buf, "RemoveMob"), XS_EntityList_RemoveMob, file, "$$"); + newXSproto(strcpy(buf, "RemoveClient"), XS_EntityList_RemoveClient, file, "$$"); + newXSproto(strcpy(buf, "RemoveNPC"), XS_EntityList_RemoveNPC, file, "$$"); + newXSproto(strcpy(buf, "RemoveGroup"), XS_EntityList_RemoveGroup, file, "$$"); + newXSproto(strcpy(buf, "RemoveCorpse"), XS_EntityList_RemoveCorpse, file, "$$"); + newXSproto(strcpy(buf, "RemoveDoor"), XS_EntityList_RemoveDoor, file, "$$"); + newXSproto(strcpy(buf, "RemoveTrap"), XS_EntityList_RemoveTrap, file, "$$"); + newXSproto(strcpy(buf, "RemoveObject"), XS_EntityList_RemoveObject, file, "$$"); + newXSproto(strcpy(buf, "RemoveAllMobs"), XS_EntityList_RemoveAllMobs, file, "$"); + newXSproto(strcpy(buf, "RemoveAllClients"), XS_EntityList_RemoveAllClients, file, "$"); + newXSproto(strcpy(buf, "RemoveAllNPCs"), XS_EntityList_RemoveAllNPCs, file, "$"); + newXSproto(strcpy(buf, "RemoveAllGroups"), XS_EntityList_RemoveAllGroups, file, "$"); + newXSproto(strcpy(buf, "RemoveAllCorpses"), XS_EntityList_RemoveAllCorpses, file, "$"); + newXSproto(strcpy(buf, "RemoveAllDoors"), XS_EntityList_RemoveAllDoors, file, "$"); + newXSproto(strcpy(buf, "RemoveAllTraps"), XS_EntityList_RemoveAllTraps, file, "$"); + newXSproto(strcpy(buf, "RemoveAllObjects"), XS_EntityList_RemoveAllObjects, file, "$"); + newXSproto(strcpy(buf, "Message"), XS_EntityList_Message, file, "$$$$;@"); + newXSproto(strcpy(buf, "MessageStatus"), XS_EntityList_MessageStatus, file, "$$$$$;@"); + newXSproto(strcpy(buf, "MessageClose"), XS_EntityList_MessageClose, file, "$$$$$$;@"); + newXSproto(strcpy(buf, "RemoveFromTargets"), XS_EntityList_RemoveFromTargets, file, "$$"); + newXSproto(strcpy(buf, "ReplaceWithTarget"), XS_EntityList_ReplaceWithTarget, file, "$$$"); + newXSproto(strcpy(buf, "OpenDoorsNear"), XS_EntityList_OpenDoorsNear, file, "$$"); + newXSproto(strcpy(buf, "MakeNameUnique"), XS_EntityList_MakeNameUnique, file, "$$"); + newXSproto(strcpy(buf, "RemoveNumbers"), XS_EntityList_RemoveNumbers, file, "$$"); + newXSproto(strcpy(buf, "SignalMobsByNPCID"), XS_EntityList_SignalMobsByNPCID, file, "$$$"); + newXSproto(strcpy(buf, "RemoveEntity"), XS_EntityList_RemoveEntity, file, "$$"); + newXSproto(strcpy(buf, "DeleteNPCCorpses"), XS_EntityList_DeleteNPCCorpses, file, "$"); + newXSproto(strcpy(buf, "DeletePlayerCorpses"), XS_EntityList_DeletePlayerCorpses, file, "$"); + newXSproto(strcpy(buf, "HalveAggro"), XS_EntityList_HalveAggro, file, "$$"); + newXSproto(strcpy(buf, "DoubleAggro"), XS_EntityList_DoubleAggro, file, "$$"); + newXSproto(strcpy(buf, "ClearFeignAggro"), XS_EntityList_ClearFeignAggro, file, "$$"); + newXSproto(strcpy(buf, "Fighting"), XS_EntityList_Fighting, file, "$$"); + newXSproto(strcpy(buf, "RemoveFromHateLists"), XS_EntityList_RemoveFromHateLists, file, "$$;$"); + newXSproto(strcpy(buf, "MessageGroup"), XS_EntityList_MessageGroup, file, "$$$$$;@"); + newXSproto(strcpy(buf, "GetRandomClient"), XS_EntityList_GetRandomClient, file, "$$$$$;$"); + newXSproto(strcpy(buf, "GetMobList"), XS_EntityList_GetMobList, file, "$"); + newXSproto(strcpy(buf, "GetClientList"), XS_EntityList_GetClientList, file, "$"); + newXSproto(strcpy(buf, "GetNPCList"), XS_EntityList_GetNPCList, file, "$"); + newXSproto(strcpy(buf, "GetCorpseList"), XS_EntityList_GetCorpseList, file, "$"); + newXSproto(strcpy(buf, "GetObjectList"), XS_EntityList_GetObjectList, file, "$"); + newXSproto(strcpy(buf, "GetDoorsList"), XS_EntityList_GetDoorsList, file, "$"); + newXSproto(strcpy(buf, "SignalAllClients"), XS_EntityList_SignalAllClients, file, "$$"); XSRETURN_YES; } diff --git a/zone/perl_groups.cpp b/zone/perl_groups.cpp index e264b7d7a..33ed9689d 100644 --- a/zone/perl_groups.cpp +++ b/zone/perl_groups.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -42,21 +44,19 @@ XS(XS_Group_DisbandGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_DisbandGroup) -{ +XS(XS_Group_DisbandGroup) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Group::DisbandGroup(THIS)"); { - Group * THIS; + Group *THIS; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->DisbandGroup(); @@ -65,32 +65,29 @@ XS(XS_Group_DisbandGroup) } XS(XS_Group_IsGroupMember); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_IsGroupMember) -{ +XS(XS_Group_IsGroupMember) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Group::IsGroupMember(THIS, client)"); { - Group * THIS; - bool RETVAL; - Mob* client; + Group *THIS; + bool RETVAL; + Mob *client; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - client = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + client = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "client is not of type Mob"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); RETVAL = THIS->IsGroupMember(client); @@ -101,32 +98,29 @@ XS(XS_Group_IsGroupMember) } XS(XS_Group_CastGroupSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_CastGroupSpell) -{ +XS(XS_Group_CastGroupSpell) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Group::CastGroupSpell(THIS, caster, spellid)"); + Perl_croak(aTHX_ "Usage: Group::CastGroupSpell(THIS, Mob* caster, uint16 spell_id)"); { - Group * THIS; - Mob* caster; - uint16 spellid = (uint16)SvUV(ST(2)); + Group *THIS; + Mob *caster; + uint16 spellid = (uint16) SvUV(ST(2)); if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); THIS->CastGroupSpell(caster, spellid); @@ -135,32 +129,29 @@ XS(XS_Group_CastGroupSpell) } XS(XS_Group_SplitExp); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_SplitExp) -{ +XS(XS_Group_SplitExp) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Group::SplitExp(THIS, exp, other)"); + Perl_croak(aTHX_ "Usage: Group::SplitExp(THIS, uint32 exp, Mob* other)"); { - Group * THIS; - uint32 exp = (uint32)SvUV(ST(1)); - Mob* other; + Group *THIS; + uint32 exp = (uint32) SvUV(ST(1)); + Mob *other; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->SplitExp(exp, other); @@ -169,106 +160,98 @@ XS(XS_Group_SplitExp) } XS(XS_Group_GroupMessage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GroupMessage) -{ +XS(XS_Group_GroupMessage) { dXSARGS; - if ((items != 3) && (items != 4)) // the 3 item version is kept for backwards compatability - Perl_croak(aTHX_ "Usage: Group::GroupMessage(THIS, sender, language, message)"); + if ((items != 3) && (items != 4)) // the 3 item version is kept for backwards compatability + Perl_croak(aTHX_ "Usage: Group::GroupMessage(THIS, Mob* sender, uint8 language, string message)"); { - Group * THIS; - Mob* sender; - uint8 language; - char* message; + Group *THIS; + Mob *sender; + uint8 language; + char *message; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - sender = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + sender = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "sender is not of type Mob"); - if(sender == nullptr) + if (sender == nullptr) Perl_croak(aTHX_ "sender is nullptr, avoiding crash."); if (items == 4) { - language = (uint8)SvUV(ST(2)); + language = (uint8) SvUV(ST(2)); if ((language >= MAX_PP_LANGUAGE) || (language < 0)) language = 0; - message = (char *)SvPV_nolen(ST(3)); + message = (char *) SvPV_nolen(ST(3)); THIS->GroupMessage(sender, language, 100, message); - } - else { // if no language is specificed, send it in common - message = (char *)SvPV_nolen(ST(2)); - THIS->GroupMessage(sender,0, 100, message); + } else { // if no language is specificed, send it in common + message = (char *) SvPV_nolen(ST(2)); + THIS->GroupMessage(sender, 0, 100, message); } } XSRETURN_EMPTY; } XS(XS_Group_GetTotalGroupDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GetTotalGroupDamage) -{ +XS(XS_Group_GetTotalGroupDamage) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Group::GetTotalGroupDamage(THIS, other)"); + Perl_croak(aTHX_ "Usage: Group::GetTotalGroupDamage(THIS, Mob* other)"); { - Group * THIS; - uint32 RETVAL; + Group *THIS; + uint32 RETVAL; dXSTARG; - Mob* other; + Mob *other; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); RETVAL = THIS->GetTotalGroupDamage(other); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Group_SplitMoney); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_SplitMoney) -{ +XS(XS_Group_SplitMoney) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: Group::SplitMoney(THIS, copper, silver, gold, platinum)"); + Perl_croak(aTHX_ "Usage: Group::SplitMoney(THIS, uint32 copper, uint32 silver, uint32 gold, uint32 platinum)"); { - Group * THIS; - uint32 copper = (uint32)SvUV(ST(1)); - uint32 silver = (uint32)SvUV(ST(2)); - uint32 gold = (uint32)SvUV(ST(3)); - uint32 platinum = (uint32)SvUV(ST(4)); + Group *THIS; + uint32 copper = (uint32) SvUV(ST(1)); + uint32 silver = (uint32) SvUV(ST(2)); + uint32 gold = (uint32) SvUV(ST(3)); + uint32 platinum = (uint32) SvUV(ST(4)); if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SplitMoney(copper, silver, gold, platinum); @@ -277,31 +260,28 @@ XS(XS_Group_SplitMoney) } XS(XS_Group_SetLeader); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_SetLeader) -{ +XS(XS_Group_SetLeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Group::SetLeader(THIS, newleader)"); + Perl_croak(aTHX_ "Usage: Group::SetLeader(THIS, Mob* new_leader)"); { - Group * THIS; - Mob* newleader; + Group *THIS; + Mob *newleader; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - newleader = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + newleader = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "newleader is not of type Mob"); - if(newleader == nullptr) + if (newleader == nullptr) Perl_croak(aTHX_ "newleader is nullptr, avoiding crash."); THIS->SetLeader(newleader); @@ -310,83 +290,78 @@ XS(XS_Group_SetLeader) } XS(XS_Group_GetLeader); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GetLeader) -{ +XS(XS_Group_GetLeader) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Group::GetLeader(THIS)"); { - Group * THIS; - Mob * RETVAL; + Group *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLeader(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Group_GetLeaderName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GetLeaderName) -{ +XS(XS_Group_GetLeaderName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Group::GetLeaderName(THIS)"); { - Group * THIS; - const char * RETVAL; + Group *THIS; + const char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLeaderName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Group_SendHPPacketsTo); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_SendHPPacketsTo) -{ +XS(XS_Group_SendHPPacketsTo) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Group::SendHPPacketsTo(THIS, newmember)"); + Perl_croak(aTHX_ "Usage: Group::SendHPPacketsTo(THIS, Mob* new_member)"); { - Group * THIS; - Mob* newmember; + Group *THIS; + Mob *newmember; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - newmember = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + newmember = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "newmember is not of type Mob"); - if(newmember == nullptr) + if (newmember == nullptr) Perl_croak(aTHX_ "newmember is nullptr, avoiding crash."); THIS->SendHPManaEndPacketsTo(newmember); @@ -395,31 +370,28 @@ XS(XS_Group_SendHPPacketsTo) } XS(XS_Group_SendHPPacketsFrom); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_SendHPPacketsFrom) -{ +XS(XS_Group_SendHPPacketsFrom) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Group::SendHPPacketsFrom(THIS, newmember)"); + Perl_croak(aTHX_ "Usage: Group::SendHPPacketsFrom(THIS, Mob* new_member)"); { - Group * THIS; - Mob* newmember; + Group *THIS; + Mob *newmember; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - newmember = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + newmember = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "newmember is not of type Mob"); - if(newmember == nullptr) + if (newmember == nullptr) Perl_croak(aTHX_ "newmember is nullptr, avoiding crash."); THIS->SendHPPacketsFrom(newmember); @@ -428,32 +400,29 @@ XS(XS_Group_SendHPPacketsFrom) } XS(XS_Group_IsLeader); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_IsLeader) -{ +XS(XS_Group_IsLeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Group::IsLeader(THIS, leadertest)"); + Perl_croak(aTHX_ "Usage: Group::IsLeader(THIS, Mob* target)"); { - Group * THIS; - bool RETVAL; - Mob* leadertest; + Group *THIS; + bool RETVAL; + Mob *leadertest; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - leadertest = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + leadertest = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "leadertest is not of type Mob"); - if(leadertest == nullptr) + if (leadertest == nullptr) Perl_croak(aTHX_ "leadertest is nullptr, avoiding crash."); RETVAL = THIS->IsLeader(leadertest); @@ -464,88 +433,84 @@ XS(XS_Group_IsLeader) } XS(XS_Group_GroupCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GroupCount) -{ +XS(XS_Group_GroupCount) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Group::GroupCount(THIS)"); { - Group * THIS; - uint8 RETVAL; + Group *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GroupCount(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Group_GetHighestLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GetHighestLevel) -{ +XS(XS_Group_GetHighestLevel) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Group::GetHighestLevel(THIS)"); { - Group * THIS; - uint32 RETVAL; + Group *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHighestLevel(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Group_TeleportGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_TeleportGroup) -{ +XS(XS_Group_TeleportGroup) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Group::TeleportGroup(THIS, sender, zoneID, x, y, z, heading)"); + Perl_croak(aTHX_ + "Usage: Group::TeleportGroup(THIS, Mob* sender, uint32 zone_id, float x, float y, float z, float heading)"); { - Group * THIS; - Mob* sender; - uint32 zoneID = (uint32)SvUV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); - float heading = (float)SvNV(ST(6)); + Group *THIS; + Mob *sender; + uint32 zoneID = (uint32) SvUV(ST(2)); + float x = (float) SvNV(ST(3)); + float y = (float) SvNV(ST(4)); + float z = (float) SvNV(ST(5)); + float heading = (float) SvNV(ST(6)); if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - sender = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + sender = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "sender is not of type Mob"); - if(sender == nullptr) + if (sender == nullptr) Perl_croak(aTHX_ "sender is nullptr, avoiding crash."); THIS->TeleportGroup(sender, zoneID, 0, x, y, z, heading); @@ -554,63 +519,60 @@ XS(XS_Group_TeleportGroup) } XS(XS_Group_GetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Group_GetID) -{ +XS(XS_Group_GetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Group::GetID(THIS)"); { - Group * THIS; - uint32 RETVAL; + Group *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Group_GetMember); -XS(XS_Group_GetMember) -{ +XS(XS_Group_GetMember) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Group::GetMember(THIS, index)"); + Perl_croak(aTHX_ "Usage: Group::GetMember(THIS, int group_index)"); { - Group * THIS; - Mob* member; - Client* RETVAL = nullptr; + Group *THIS; + Mob *member; + Client *RETVAL = nullptr; dXSTARG; if (sv_derived_from(ST(0), "Group")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Group *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Group *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Group"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - int index = (int)SvUV(ST(1)); + int index = (int) SvUV(ST(1)); if (index < 0 || index > 5) RETVAL = nullptr; else { - member = THIS->members[index]; + member = THIS->members[index]; if (member != nullptr) RETVAL = member->CastToClient(); } - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } @@ -619,39 +581,38 @@ XS(XS_Group_GetMember) extern "C" #endif XS(boot_Group); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Group) -{ +XS(boot_Group) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "DisbandGroup"), XS_Group_DisbandGroup, file, "$"); - newXSproto(strcpy(buf, "IsGroupMember"), XS_Group_IsGroupMember, file, "$$"); - newXSproto(strcpy(buf, "CastGroupSpell"), XS_Group_CastGroupSpell, file, "$$$"); - newXSproto(strcpy(buf, "SplitExp"), XS_Group_SplitExp, file, "$$$"); - newXSproto(strcpy(buf, "GroupMessage"), XS_Group_GroupMessage, file, "$$$"); - newXSproto(strcpy(buf, "GetTotalGroupDamage"), XS_Group_GetTotalGroupDamage, file, "$$"); - newXSproto(strcpy(buf, "SplitMoney"), XS_Group_SplitMoney, file, "$$$$$"); - newXSproto(strcpy(buf, "SetLeader"), XS_Group_SetLeader, file, "$$"); - newXSproto(strcpy(buf, "GetLeader"), XS_Group_GetLeader, file, "$"); - newXSproto(strcpy(buf, "GetLeaderName"), XS_Group_GetLeaderName, file, "$"); - newXSproto(strcpy(buf, "SendHPPacketsTo"), XS_Group_SendHPPacketsTo, file, "$$"); - newXSproto(strcpy(buf, "SendHPPacketsFrom"), XS_Group_SendHPPacketsFrom, file, "$$"); - newXSproto(strcpy(buf, "IsLeader"), XS_Group_IsLeader, file, "$$"); - newXSproto(strcpy(buf, "GroupCount"), XS_Group_GroupCount, file, "$"); - newXSproto(strcpy(buf, "GetHighestLevel"), XS_Group_GetHighestLevel, file, "$"); - newXSproto(strcpy(buf, "TeleportGroup"), XS_Group_TeleportGroup, file, "$$$$$$$"); - newXSproto(strcpy(buf, "GetID"), XS_Group_GetID, file, "$"); - newXSproto(strcpy(buf, "GetMember"), XS_Group_GetMember, file, "$$"); + newXSproto(strcpy(buf, "DisbandGroup"), XS_Group_DisbandGroup, file, "$"); + newXSproto(strcpy(buf, "IsGroupMember"), XS_Group_IsGroupMember, file, "$$"); + newXSproto(strcpy(buf, "CastGroupSpell"), XS_Group_CastGroupSpell, file, "$$$"); + newXSproto(strcpy(buf, "SplitExp"), XS_Group_SplitExp, file, "$$$"); + newXSproto(strcpy(buf, "GroupMessage"), XS_Group_GroupMessage, file, "$$$"); + newXSproto(strcpy(buf, "GetTotalGroupDamage"), XS_Group_GetTotalGroupDamage, file, "$$"); + newXSproto(strcpy(buf, "SplitMoney"), XS_Group_SplitMoney, file, "$$$$$"); + newXSproto(strcpy(buf, "SetLeader"), XS_Group_SetLeader, file, "$$"); + newXSproto(strcpy(buf, "GetLeader"), XS_Group_GetLeader, file, "$"); + newXSproto(strcpy(buf, "GetLeaderName"), XS_Group_GetLeaderName, file, "$"); + newXSproto(strcpy(buf, "SendHPPacketsTo"), XS_Group_SendHPPacketsTo, file, "$$"); + newXSproto(strcpy(buf, "SendHPPacketsFrom"), XS_Group_SendHPPacketsFrom, file, "$$"); + newXSproto(strcpy(buf, "IsLeader"), XS_Group_IsLeader, file, "$$"); + newXSproto(strcpy(buf, "GroupCount"), XS_Group_GroupCount, file, "$"); + newXSproto(strcpy(buf, "GetHighestLevel"), XS_Group_GetHighestLevel, file, "$"); + newXSproto(strcpy(buf, "TeleportGroup"), XS_Group_TeleportGroup, file, "$$$$$$$"); + newXSproto(strcpy(buf, "GetID"), XS_Group_GetID, file, "$"); + newXSproto(strcpy(buf, "GetMember"), XS_Group_GetMember, file, "$$"); XSRETURN_YES; } diff --git a/zone/perl_hateentry.cpp b/zone/perl_hateentry.cpp index 7c346a748..85b5d67dd 100644 --- a/zone/perl_hateentry.cpp +++ b/zone/perl_hateentry.cpp @@ -18,7 +18,9 @@ #include "../common/features.h" #include "client.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -29,84 +31,80 @@ #include "../common/linked_list.h" #include "hate_list.h" -#ifdef THIS /* this macro seems to leak out on some systems */ +#ifdef THIS /* this macro seems to leak out on some systems */ #undef THIS #endif XS(XS_HateEntry_GetEnt); /* prototype to pass -Wmissing-prototypes */ -XS(XS_HateEntry_GetEnt) -{ +XS(XS_HateEntry_GetEnt) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetData(THIS)"); { - struct_HateList * THIS; - Mob * RETVAL; + struct_HateList *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "HateEntry")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(struct_HateList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(struct_HateList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->entity_on_hatelist; ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_HateEntry_GetHate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_HateEntry_GetHate) -{ +XS(XS_HateEntry_GetHate) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetHate(THIS)"); { - struct_HateList * THIS; + struct_HateList *THIS; int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "HateEntry")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(struct_HateList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(struct_HateList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->stored_hate_amount; - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_HateEntry_GetDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_HateEntry_GetDamage) -{ +XS(XS_HateEntry_GetDamage) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetDamage(THIS)"); { - struct_HateList * THIS; + struct_HateList *THIS; int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "HateEntry")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(struct_HateList *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(struct_HateList *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->hatelist_damage; - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } @@ -116,24 +114,23 @@ extern "C" #endif XS(boot_HateEntry); -XS(boot_HateEntry) -{ +XS(boot_HateEntry) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "GetEnt"), XS_HateEntry_GetEnt, file, "$"); - newXSproto(strcpy(buf, "GetDamage"), XS_HateEntry_GetDamage, file, "$"); - newXSproto(strcpy(buf, "GetHate"), XS_HateEntry_GetHate, file, "$"); + newXSproto(strcpy(buf, "GetEnt"), XS_HateEntry_GetEnt, file, "$"); + newXSproto(strcpy(buf, "GetDamage"), XS_HateEntry_GetDamage, file, "$"); + newXSproto(strcpy(buf, "GetHate"), XS_HateEntry_GetHate, file, "$"); XSRETURN_YES; } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index cb30cf809..0a6275169 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -46,22 +48,20 @@ typedef const char Const_char; XS(XS_Mob_IsClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsClient) -{ +XS(XS_Mob_IsClient) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsClient(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsClient(); @@ -72,22 +72,20 @@ XS(XS_Mob_IsClient) } XS(XS_Mob_IsNPC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsNPC) -{ +XS(XS_Mob_IsNPC) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsNPC(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsNPC(); @@ -98,22 +96,20 @@ XS(XS_Mob_IsNPC) } XS(XS_Mob_IsMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsMob) -{ +XS(XS_Mob_IsMob) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsMob(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsMob(); @@ -124,22 +120,20 @@ XS(XS_Mob_IsMob) } XS(XS_Mob_IsCorpse); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsCorpse) -{ +XS(XS_Mob_IsCorpse) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsCorpse(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsCorpse(); @@ -150,22 +144,20 @@ XS(XS_Mob_IsCorpse) } XS(XS_Mob_IsPlayerCorpse); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsPlayerCorpse) -{ +XS(XS_Mob_IsPlayerCorpse) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsPlayerCorpse(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsPlayerCorpse(); @@ -176,22 +168,20 @@ XS(XS_Mob_IsPlayerCorpse) } XS(XS_Mob_IsNPCCorpse); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsNPCCorpse) -{ +XS(XS_Mob_IsNPCCorpse) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsNPCCorpse(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsNPCCorpse(); @@ -202,22 +192,20 @@ XS(XS_Mob_IsNPCCorpse) } XS(XS_Mob_IsObject); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsObject) -{ +XS(XS_Mob_IsObject) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsObject(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsObject(); @@ -228,22 +216,20 @@ XS(XS_Mob_IsObject) } XS(XS_Mob_IsDoor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsDoor) -{ +XS(XS_Mob_IsDoor) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsDoor(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsDoor(); @@ -254,22 +240,20 @@ XS(XS_Mob_IsDoor) } XS(XS_Mob_IsTrap); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsTrap) -{ +XS(XS_Mob_IsTrap) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsTrap(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsTrap(); @@ -280,22 +264,20 @@ XS(XS_Mob_IsTrap) } XS(XS_Mob_IsBeacon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsBeacon) -{ +XS(XS_Mob_IsBeacon) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsBeacon(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsBeacon(); @@ -306,184 +288,173 @@ XS(XS_Mob_IsBeacon) } XS(XS_Mob_CastToClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CastToClient) -{ +XS(XS_Mob_CastToClient) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CastToClient(THIS)"); { - Mob * THIS; - Client * RETVAL; + Mob *THIS; + Client *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CastToClient(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_CastToNPC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CastToNPC) -{ +XS(XS_Mob_CastToNPC) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CastToNPC(THIS)"); { - Mob * THIS; - NPC * RETVAL; + Mob *THIS; + NPC *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CastToNPC(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "NPC", (void*)RETVAL); + sv_setref_pv(ST(0), "NPC", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_CastToMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CastToMob) -{ +XS(XS_Mob_CastToMob) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CastToMob(THIS)"); { - Mob * THIS; - Mob * RETVAL; + Mob *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CastToMob(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_CastToCorpse); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CastToCorpse) -{ +XS(XS_Mob_CastToCorpse) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CastToCorpse(THIS)"); { - Mob * THIS; - Corpse * RETVAL; + Mob *THIS; + Corpse *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CastToCorpse(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Corpse", (void*)RETVAL); + sv_setref_pv(ST(0), "Corpse", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetID) -{ +XS(XS_Mob_GetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetID(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetName) -{ +XS(XS_Mob_GetName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetName(THIS)"); { - Mob * THIS; - Const_char * RETVAL; + Mob *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Mob_Depop); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Depop) -{ +XS(XS_Mob_Depop) { dXSARGS; if (items < 1 || items > 2) Perl_croak(aTHX_ "Usage: Mob::Depop(THIS, StartSpawnTimer = true)"); { - Mob * THIS; - bool StartSpawnTimer; + Mob *THIS; + bool StartSpawnTimer; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) StartSpawnTimer = true; else { - StartSpawnTimer = (bool)SvTRUE(ST(1)); + StartSpawnTimer = (bool) SvTRUE(ST(1)); } THIS->Depop(StartSpawnTimer); @@ -492,31 +463,28 @@ XS(XS_Mob_Depop) } XS(XS_Mob_RogueAssassinate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_RogueAssassinate) -{ +XS(XS_Mob_RogueAssassinate) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::RogueAssassinate(THIS, other)"); { - Mob * THIS; - Mob* other; + Mob *THIS; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->RogueAssassinate(other); @@ -525,50 +493,47 @@ XS(XS_Mob_RogueAssassinate) } XS(XS_Mob_BehindMob); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_BehindMob) -{ +XS(XS_Mob_BehindMob) { dXSARGS; if (items < 1 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::BehindMob(THIS, other= 0, playerx= 0.0f, playery= 0.0f)"); + Perl_croak(aTHX_ "Usage: Mob::BehindMob(THIS, Mob* other = 0, [float x = 0.0f], [float y= 0.0f])"); { - Mob * THIS; - bool RETVAL; - Mob* other; - float playerx; - float playery; + Mob *THIS; + bool RETVAL; + Mob *other; + float playerx; + float playery; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) other = 0; else { if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); } if (items < 3) playerx = 0.0f; else { - playerx = (float)SvNV(ST(2)); + playerx = (float) SvNV(ST(2)); } if (items < 4) playery = 0.0f; else { - playery = (float)SvNV(ST(3)); + playery = (float) SvNV(ST(3)); } RETVAL = THIS->BehindMob(other, playerx, playery); @@ -579,29 +544,27 @@ XS(XS_Mob_BehindMob) } XS(XS_Mob_SetLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetLevel) -{ +XS(XS_Mob_SetLevel) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::SetLevel(THIS, in_level, command= false)"); + Perl_croak(aTHX_ "Usage: Mob::SetLevel(THIS, uint8 in_level, [bool command = false])"); { - Mob * THIS; - uint8 in_level = (uint8)SvUV(ST(1)); - bool command; + Mob *THIS; + uint8 in_level = (uint8) SvUV(ST(1)); + bool command; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) command = false; else { - command = (bool)SvTRUE(ST(2)); + command = (bool) SvTRUE(ST(2)); } THIS->SetLevel(in_level, command); @@ -610,49 +573,46 @@ XS(XS_Mob_SetLevel) } XS(XS_Mob_GetSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSkill) -{ +XS(XS_Mob_GetSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetSkill(THIS, skill_num)"); + Perl_croak(aTHX_ "Usage: Mob::GetSkill(THIS, int skill_id)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType)SvUV(ST(1)); + EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSkill(skill_num); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SendWearChange); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendWearChange) -{ +XS(XS_Mob_SendWearChange) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SendWearChange(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::SendWearChange(THIS, uint8 material_slot)"); { - Mob * THIS; - uint8 material_slot = (uint8)SvUV(ST(1)); + Mob *THIS; + uint8 material_slot = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendWearChange(material_slot); @@ -661,130 +621,124 @@ XS(XS_Mob_SendWearChange) } XS(XS_Mob_GetEquipment); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetEquipment) -{ +XS(XS_Mob_GetEquipment) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetEquipment(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetEquipment(THIS, uint8 material_slot)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint8 material_slot = (uint8)SvUV(ST(1)); + uint8 material_slot = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEquipment(material_slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetEquipmentMaterial); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetEquipmentMaterial) -{ +XS(XS_Mob_GetEquipmentMaterial) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetEquipmentMaterial(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetEquipmentMaterial(THIS, uint8 material_slot)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint8 material_slot = (uint8)SvUV(ST(1)); + uint8 material_slot = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEquipmentMaterial(material_slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetEquipmentColor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetEquipmentColor) -{ +XS(XS_Mob_GetEquipmentColor) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetEquipmentColor(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetEquipmentColor(THIS, uint8 material_slot)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint8 material_slot = (uint8)SvUV(ST(1)); + uint8 material_slot = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEquipmentColor(material_slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetArmorTint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetArmorTint) -{ +XS(XS_Mob_GetArmorTint) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetArmorTint(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetArmorTint(THIS, uint8 material_slot)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint8 material_slot = (uint8)SvUV(ST(1)); + uint8 material_slot = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetArmorTint(material_slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsMoving); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsMoving) -{ +XS(XS_Mob_IsMoving) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsMoving(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsMoving(); @@ -795,21 +749,19 @@ XS(XS_Mob_IsMoving) } XS(XS_Mob_GoToBind); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GoToBind) -{ +XS(XS_Mob_GoToBind) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GoToBind(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->GoToBind(); @@ -818,21 +770,19 @@ XS(XS_Mob_GoToBind) } XS(XS_Mob_Gate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Gate) -{ +XS(XS_Mob_Gate) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::Gate(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Gate(); @@ -841,46 +791,44 @@ XS(XS_Mob_Gate) } XS(XS_Mob_Attack); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Attack) -{ +XS(XS_Mob_Attack) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::Attack(THIS, other, Hand= 13, FromRiposte= false)"); + Perl_croak(aTHX_ + "Usage: Mob::Attack(THIS, Mob* other, [int hand = 13 [prim|sec]], [bool from_riposte = false])"); { - Mob * THIS; - bool RETVAL; - Mob* other; - int Hand; - bool FromRiposte; + Mob *THIS; + bool RETVAL; + Mob *other; + int Hand; + bool FromRiposte; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); if (items < 3) Hand = 13; else { - Hand = (int)SvIV(ST(2)); + Hand = (int) SvIV(ST(2)); } if (items < 4) FromRiposte = false; else { - FromRiposte = (bool)SvTRUE(ST(3)); + FromRiposte = (bool) SvTRUE(ST(3)); } RETVAL = THIS->Attack(other, Hand, FromRiposte); @@ -891,55 +839,53 @@ XS(XS_Mob_Attack) } XS(XS_Mob_Damage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Damage) -{ +XS(XS_Mob_Damage) { dXSARGS; if (items < 5 || items > 8) - Perl_croak(aTHX_ "Usage: Mob::Damage(THIS, from, damage, spell_id, attack_skill, avoidable= true, buffslot= -1, iBuffTic= false)"); + Perl_croak(aTHX_ + "Usage: Mob::Damage(THIS, Mob* from, int32 damage, uint16 spell_id, int attack_skill, [bool avoidable = true], [int8 buffslot = -1], [bool buff_tic = false])"); { - Mob * THIS; - Mob* from; - int32 damage = (int32)SvIV(ST(2)); - uint16 spell_id = (uint16)SvUV(ST(3)); - EQEmu::skills::SkillType attack_skill = (EQEmu::skills::SkillType)SvUV(ST(4)); - bool avoidable; - int8 buffslot; - bool iBuffTic; + Mob *THIS; + Mob *from; + int32 damage = (int32) SvIV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(3)); + EQEmu::skills::SkillType attack_skill = (EQEmu::skills::SkillType) SvUV(ST(4)); + bool avoidable; + int8 buffslot; + bool iBuffTic; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - from = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + from = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "from is not of type Mob"); - if(from == nullptr) + if (from == nullptr) Perl_croak(aTHX_ "from is nullptr, avoiding crash."); if (items < 6) avoidable = true; else { - avoidable = (bool)SvTRUE(ST(5)); + avoidable = (bool) SvTRUE(ST(5)); } if (items < 7) buffslot = -1; else { - buffslot = (int8)SvIV(ST(6)); + buffslot = (int8) SvIV(ST(6)); } if (items < 8) iBuffTic = false; else { - iBuffTic = (bool)SvTRUE(ST(7)); + iBuffTic = (bool) SvTRUE(ST(7)); } THIS->Damage(from, damage, spell_id, attack_skill, avoidable, buffslot, iBuffTic); @@ -948,31 +894,28 @@ XS(XS_Mob_Damage) } XS(XS_Mob_RangedAttack); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_RangedAttack) -{ +XS(XS_Mob_RangedAttack) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::RangedAttack(THIS, other)"); + Perl_croak(aTHX_ "Usage: Mob::RangedAttack(THIS, Mob* other)"); { - Mob * THIS; - Mob* other; + Mob *THIS; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->RangedAttack(other); @@ -981,31 +924,28 @@ XS(XS_Mob_RangedAttack) } XS(XS_Mob_ThrowingAttack); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ThrowingAttack) -{ +XS(XS_Mob_ThrowingAttack) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::ThrowingAttack(THIS, other)"); + Perl_croak(aTHX_ "Usage: Mob::ThrowingAttack(THIS, Mob* other)"); { - Mob * THIS; - Mob* other; + Mob *THIS; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->ThrowingAttack(other); @@ -1014,21 +954,19 @@ XS(XS_Mob_ThrowingAttack) } XS(XS_Mob_Heal); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Heal) -{ +XS(XS_Mob_Heal) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::Heal(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Heal(); @@ -1038,34 +976,30 @@ XS(XS_Mob_Heal) XS(XS_Mob_HealDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_HealDamage) -{ +XS(XS_Mob_HealDamage) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::HealDamage(THIS, amount, caster = 0)"); + Perl_croak(aTHX_ "Usage: Mob::HealDamage(THIS, int32 amount, [Mob* caster = 0])"); { - Mob * THIS; - int32 heal_amt = (int32)SvIV(ST(1)); - Mob * caster = nullptr; + Mob *THIS; + int32 heal_amt = (int32) SvIV(ST(1)); + Mob *caster = nullptr; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items == 3) - { + if (items == 3) { if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); } @@ -1075,21 +1009,19 @@ XS(XS_Mob_HealDamage) } XS(XS_Mob_SetMaxHP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetMaxHP) -{ +XS(XS_Mob_SetMaxHP) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::SetMaxHP(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetMaxHP(); @@ -1098,49 +1030,46 @@ XS(XS_Mob_SetMaxHP) } XS(XS_Mob_GetLevelCon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetLevelCon) -{ +XS(XS_Mob_GetLevelCon) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetLevelCon(THIS, iOtherLevel)"); + Perl_croak(aTHX_ "Usage: Mob::GetLevelCon(THIS, uint8 other_level)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - uint8 iOtherLevel = (uint8)SvUV(ST(1)); + uint8 iOtherLevel = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLevelCon(iOtherLevel); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetHP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetHP) -{ +XS(XS_Mob_SetHP) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetHP(THIS, hp)"); + Perl_croak(aTHX_ "Usage: Mob::SetHP(THIS, int32 hp)"); { - Mob * THIS; - int32 hp = (int32)SvIV(ST(1)); + Mob *THIS; + int32 hp = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetHP(hp); @@ -1149,29 +1078,27 @@ XS(XS_Mob_SetHP) } XS(XS_Mob_DoAnim); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DoAnim) -{ +XS(XS_Mob_DoAnim) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::DoAnim(THIS, animnum, type=0)"); + Perl_croak(aTHX_ "Usage: Mob::DoAnim(THIS, int animation_number, [int type = 0])"); { - Mob * THIS; - int animnum = (int)SvIV(ST(1)); - int type; + Mob *THIS; + int animnum = (int) SvIV(ST(1)); + int type; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) type = 0; else { - type = (int)SvIV(ST(2)); + type = (int) SvIV(ST(2)); } THIS->DoAnim(animnum, type); @@ -1180,29 +1107,27 @@ XS(XS_Mob_DoAnim) } XS(XS_Mob_ChangeSize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ChangeSize) -{ +XS(XS_Mob_ChangeSize) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::ChangeSize(THIS, in_size, bNoRestriction= false)"); + Perl_croak(aTHX_ "Usage: Mob::ChangeSize(THIS, float in_size, [bool no_restriction = false])"); { - Mob * THIS; - float in_size = (float)SvNV(ST(1)); - bool bNoRestriction; + Mob *THIS; + float in_size = (float) SvNV(ST(1)); + bool bNoRestriction; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) bNoRestriction = false; else { - bNoRestriction = (bool)SvTRUE(ST(2)); + bNoRestriction = (bool) SvTRUE(ST(2)); } THIS->ChangeSize(in_size, bNoRestriction); @@ -1211,31 +1136,29 @@ XS(XS_Mob_ChangeSize) } XS(XS_Mob_GMMove); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GMMove) -{ +XS(XS_Mob_GMMove) { dXSARGS; if (items < 4 || items > 5) - Perl_croak(aTHX_ "Usage: Mob::GMMove(THIS, x, y, z, heading= 0.01)"); + Perl_croak(aTHX_ "Usage: Mob::GMMove(THIS, float x, float y, float z, [float heading = 0.01])"); { - Mob * THIS; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float heading; + Mob *THIS; + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); + float heading; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 5) heading = 0.01; else { - heading = (float)SvNV(ST(4)); + heading = (float) SvNV(ST(4)); } THIS->GMMove(x, y, z, heading); @@ -1244,28 +1167,26 @@ XS(XS_Mob_GMMove) } XS(XS_Mob_SendPosUpdate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendPosUpdate) -{ +XS(XS_Mob_SendPosUpdate) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Mob::SendPosUpdate(THIS, iSendToSelf= 0)"); + Perl_croak(aTHX_ "Usage: Mob::SendPosUpdate(THIS, [uint8 send_to_self = 0])"); { - Mob * THIS; - uint8 iSendToSelf; + Mob *THIS; + uint8 iSendToSelf; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) iSendToSelf = 0; else { - iSendToSelf = (uint8)SvUV(ST(1)); + iSendToSelf = (uint8) SvUV(ST(1)); } THIS->SendPositionUpdate(iSendToSelf); @@ -1274,21 +1195,19 @@ XS(XS_Mob_SendPosUpdate) } XS(XS_Mob_SendPosition); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendPosition) -{ +XS(XS_Mob_SendPosition) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::SendPosition(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendPosition(); @@ -1297,22 +1216,20 @@ XS(XS_Mob_SendPosition) } XS(XS_Mob_HasProcs); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_HasProcs) -{ +XS(XS_Mob_HasProcs) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HasProcs(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->HasProcs(); @@ -1323,35 +1240,32 @@ XS(XS_Mob_HasProcs) } XS(XS_Mob_IsInvisible); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsInvisible) -{ +XS(XS_Mob_IsInvisible) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Mob::IsInvisible(THIS, other= 0)"); + Perl_croak(aTHX_ "Usage: Mob::IsInvisible(THIS, [Mob* other = 0])"); { - Mob * THIS; - bool RETVAL; - Mob * other; + Mob *THIS; + bool RETVAL; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) other = 0; else { if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); } @@ -1363,22 +1277,20 @@ XS(XS_Mob_IsInvisible) } XS(XS_Mob_SetInvisible); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetInvisible) -{ +XS(XS_Mob_SetInvisible) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetInvisible(THIS, state)"); + Perl_croak(aTHX_ "Usage: Mob::SetInvisible(THIS, uint8 state)"); { - Mob * THIS; - uint8 state = (uint8)SvUV(ST(1)); + Mob *THIS; + uint8 state = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetInvisible(state); @@ -1387,125 +1299,118 @@ XS(XS_Mob_SetInvisible) } XS(XS_Mob_FindBuff); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_FindBuff) -{ +XS(XS_Mob_FindBuff) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::FindBuff(THIS, spellid)"); + Perl_croak(aTHX_ "Usage: Mob::FindBuff(THIS, uint16 spell_id)"); { - Mob * THIS; - bool RETVAL; - uint16 spellid = (uint16)SvUV(ST(1)); + Mob *THIS; + bool RETVAL; + uint16 spellid = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->FindBuff(spellid); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_FindType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_FindType) -{ +XS(XS_Mob_FindType) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::FindType(THIS, type, bOffensive= false, threshold= 100)"); + Perl_croak(aTHX_ "Usage: Mob::FindType(THIS, uint8 type, [bool offensive = false], [uint16 threshold = 100])"); { - Mob * THIS; - bool RETVAL; - uint8 type = (uint8)SvUV(ST(1)); - bool bOffensive; - uint16 threshold; + Mob *THIS; + bool RETVAL; + uint8 type = (uint8) SvUV(ST(1)); + bool bOffensive; + uint16 threshold; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) bOffensive = false; else { - bOffensive = (bool)SvTRUE(ST(2)); + bOffensive = (bool) SvTRUE(ST(2)); } if (items < 4) threshold = 100; else { - threshold = (uint16)SvUV(ST(3)); + threshold = (uint16) SvUV(ST(3)); } RETVAL = THIS->FindType(type, bOffensive, threshold); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_GetBuffSlotFromType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetBuffSlotFromType) -{ +XS(XS_Mob_GetBuffSlotFromType) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetBuffSlotFromType(THIS, type)"); + Perl_croak(aTHX_ "Usage: Mob::GetBuffSlotFromType(THIS, uint16 type)"); { - Mob * THIS; - int8 RETVAL; + Mob *THIS; + int8 RETVAL; dXSTARG; - uint16 type = (uint16)SvUV(ST(1)); + uint16 type = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBuffSlotFromType(type); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_MakePet); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_MakePet) -{ +XS(XS_Mob_MakePet) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::MakePet(THIS, spell_id, pettype, name=nullptr)"); + Perl_croak(aTHX_ "Usage: Mob::MakePet(THIS, uint16 spell_id, string pet_type, [string name = nullptr])"); { - Mob * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); - char* pettype = (char *)SvPV_nolen(ST(2)); - char * name; + Mob *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); + char *pettype = (char *) SvPV_nolen(ST(2)); + char *name; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) name = nullptr; else { - name = (char *)SvPV_nolen(ST(3)); + name = (char *) SvPV_nolen(ST(3)); } THIS->MakePet(spell_id, pettype, name); @@ -1514,51 +1419,49 @@ XS(XS_Mob_MakePet) } XS(XS_Mob_MakeTempPet); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_MakeTempPet) -{ +XS(XS_Mob_MakeTempPet) { dXSARGS; if (items < 2 || items > 6) - Perl_croak(aTHX_ "Usage: Mob::MakeTempPet(THIS, spell_id, name=nullptr, duration=0, target=nullptr, sticktarg=0)"); + Perl_croak(aTHX_ + "Usage: Mob::MakeTempPet(THIS, uint16 spell_id, [string name = nullptr], [uint32 duration = 0], [Mob* target = nullptr], [bool sticktarg = 0])"); { - Mob * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); - char * name; - uint32 duration; - Mob * target; - bool sticktarg; + Mob *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); + char *name; + uint32 duration; + Mob *target; + bool sticktarg; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) name = nullptr; else - name = (char *)SvPV_nolen(ST(2)); + name = (char *) SvPV_nolen(ST(2)); if (items < 4) duration = 0; else - duration = (uint32)SvUV(ST(3)); + duration = (uint32) SvUV(ST(3)); if (items < 5) target = nullptr; else if (sv_derived_from(ST(4), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(4))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(4))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "owner is not of type Mob"); if (items < 6) sticktarg = false; else { - sticktarg = (bool)SvTRUE(ST(5)); + sticktarg = (bool) SvTRUE(ST(5)); } THIS->TemporaryPets(spell_id, target, name, duration, true, sticktarg); @@ -1567,59 +1470,57 @@ XS(XS_Mob_MakeTempPet) } XS(XS_Mob_TypesTempPet); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_TypesTempPet) -{ +XS(XS_Mob_TypesTempPet) { dXSARGS; if (items < 2 || items > 7) - Perl_croak(aTHX_ "Usage: Mob::TypesTempPet(THIS, typesid, name=nullptr, duration=0, follow=0, target=nullptr, sticktarg=0,)"); + Perl_croak(aTHX_ + "Usage: Mob::TypesTempPet(THIS, uint32 type_id, [string name = nullptr], [uint32 duration = 0], [bool follow = 0], [Mob* target = nullptr], [bool stick_targ = 0])"); { - Mob * THIS; - uint32 typesid = (uint32)SvUV(ST(1)); - char * name; - uint32 duration; - bool follow; - Mob * target; - bool sticktarg; + Mob *THIS; + uint32 typesid = (uint32) SvUV(ST(1)); + char *name; + uint32 duration; + bool follow; + Mob *target; + bool sticktarg; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) name = nullptr; else - name = (char *)SvPV_nolen(ST(2)); + name = (char *) SvPV_nolen(ST(2)); if (items < 4) duration = 0; else - duration = (uint32)SvUV(ST(3)); + duration = (uint32) SvUV(ST(3)); if (items < 5) follow = true; else { - follow = (bool)SvTRUE(ST(4)); + follow = (bool) SvTRUE(ST(4)); } if (items < 6) target = nullptr; else if (sv_derived_from(ST(5), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(5))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(5))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); if (items < 7) sticktarg = false; else { - sticktarg = (bool)SvTRUE(ST(6)); + sticktarg = (bool) SvTRUE(ST(6)); } THIS->TypesTemporaryPets(typesid, target, name, duration, follow, sticktarg); @@ -1628,577 +1529,553 @@ XS(XS_Mob_TypesTempPet) } XS(XS_Mob_GetBaseRace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetBaseRace) -{ +XS(XS_Mob_GetBaseRace) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetBaseRace(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseRace(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetBaseGender); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetBaseGender) -{ +XS(XS_Mob_GetBaseGender) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetBaseGender(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBaseGender(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDeity); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDeity) -{ +XS(XS_Mob_GetDeity) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetDeity(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDeity(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetRace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetRace) -{ +XS(XS_Mob_GetRace) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetRace(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRace(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetGender); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetGender) -{ +XS(XS_Mob_GetGender) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetGender(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGender(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetTexture); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetTexture) -{ +XS(XS_Mob_GetTexture) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetTexture(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTexture(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHelmTexture); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHelmTexture) -{ +XS(XS_Mob_GetHelmTexture) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHelmTexture(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHelmTexture(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHairColor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHairColor) -{ +XS(XS_Mob_GetHairColor) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHairColor(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHairColor(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetBeardColor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetBeardColor) -{ +XS(XS_Mob_GetBeardColor) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetBeardColor(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBeardColor(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetEyeColor1); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetEyeColor1) -{ +XS(XS_Mob_GetEyeColor1) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetEyeColor1(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEyeColor1(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetEyeColor2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetEyeColor2) -{ +XS(XS_Mob_GetEyeColor2) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetEyeColor2(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEyeColor2(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHairStyle); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHairStyle) -{ +XS(XS_Mob_GetHairStyle) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHairStyle(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHairStyle(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetLuclinFace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetLuclinFace) -{ +XS(XS_Mob_GetLuclinFace) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetLuclinFace(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLuclinFace(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetBeard); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetBeard) -{ +XS(XS_Mob_GetBeard) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetBeard(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBeard(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDrakkinHeritage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDrakkinHeritage) -{ +XS(XS_Mob_GetDrakkinHeritage) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetDrakkinHeritage(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDrakkinHeritage(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDrakkinTattoo); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDrakkinTattoo) -{ +XS(XS_Mob_GetDrakkinTattoo) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetDrakkinTattoo(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDrakkinTattoo(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDrakkinDetails); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDrakkinDetails) -{ +XS(XS_Mob_GetDrakkinDetails) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetDrakkinDetails(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDrakkinDetails(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetClass); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetClass) -{ +XS(XS_Mob_GetClass) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetClass(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClass(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetLevel) -{ +XS(XS_Mob_GetLevel) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetLevel(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLevel(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetCleanName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetCleanName) -{ +XS(XS_Mob_GetCleanName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetCleanName(THIS)"); { - Mob * THIS; - Const_char * RETVAL; + Mob *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCleanName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Mob_GetTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetTarget) -{ +XS(XS_Mob_GetTarget) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetTarget(THIS)"); { - Mob * THIS; - Mob * RETVAL; + Mob *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTarget(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetTarget) -{ +XS(XS_Mob_SetTarget) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::SetTarget(THIS, mob)"); { - Mob * THIS; - Mob* mob; + Mob *THIS; + Mob *mob; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); THIS->SetTarget(mob); @@ -2207,48 +2084,45 @@ XS(XS_Mob_SetTarget) } XS(XS_Mob_GetHPRatio); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHPRatio) -{ +XS(XS_Mob_GetHPRatio) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHPRatio(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHPRatio(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsWarriorClass); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsWarriorClass) -{ +XS(XS_Mob_IsWarriorClass) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsWarriorClass(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsWarriorClass(); @@ -2259,288 +2133,276 @@ XS(XS_Mob_IsWarriorClass) } XS(XS_Mob_GetHP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHP) -{ +XS(XS_Mob_GetHP) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHP(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHP(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxHP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxHP) -{ +XS(XS_Mob_GetMaxHP) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxHP(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxHP(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetItemHPBonuses); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetItemHPBonuses) -{ +XS(XS_Mob_GetItemHPBonuses) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetItemHPBonuses(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetItemHPBonuses(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSpellHPBonuses); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSpellHPBonuses) -{ +XS(XS_Mob_GetSpellHPBonuses) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetSpellHPBonuses(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpellHPBonuses(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSpellIDFromSlot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSpellIDFromSlot) -{ +XS(XS_Mob_GetSpellIDFromSlot) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::GetSpellIDFromSlot(THIS, slot)"); { - Mob * THIS; - int RETVAL; + Mob *THIS; + int RETVAL; dXSTARG; - uint8 slot = (uint16)SvUV(ST(1)); + uint8 slot = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (slot > THIS->GetMaxBuffSlots()) RETVAL = -1; - else + else RETVAL = THIS->GetSpellIDFromSlot(slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWalkspeed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWalkspeed) -{ +XS(XS_Mob_GetWalkspeed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWalkspeed(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetWalkspeed(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetRunspeed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetRunspeed) -{ +XS(XS_Mob_GetRunspeed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetRunspeed(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRunspeed(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetCasterLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetCasterLevel) -{ +XS(XS_Mob_GetCasterLevel) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::GetCasterLevel(THIS, spell_id)"); { - Mob * THIS; - int RETVAL; + Mob *THIS; + int RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); + uint16 spell_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCasterLevel(spell_id); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxMana); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxMana) -{ +XS(XS_Mob_GetMaxMana) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxMana(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxMana(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMana); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMana) -{ +XS(XS_Mob_GetMana) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMana(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMana(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetMana); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetMana) -{ +XS(XS_Mob_SetMana) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::SetMana(THIS, amount)"); { - Mob * THIS; - int32 amount = (int32)SvIV(ST(1)); + Mob *THIS; + int32 amount = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetMana(amount); @@ -2549,905 +2411,869 @@ XS(XS_Mob_SetMana) } XS(XS_Mob_GetManaRatio); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetManaRatio) -{ +XS(XS_Mob_GetManaRatio) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetManaRatio(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetManaRatio(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetAC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAC) -{ +XS(XS_Mob_GetAC) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetAC(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAC(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetATK); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetATK) -{ +XS(XS_Mob_GetATK) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetATK(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetATK(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSTR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSTR) -{ +XS(XS_Mob_GetSTR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetSTR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSTR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSTA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSTA) -{ +XS(XS_Mob_GetSTA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetSTA(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSTA(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDEX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDEX) -{ +XS(XS_Mob_GetDEX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetDEX(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDEX(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetAGI); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAGI) -{ +XS(XS_Mob_GetAGI) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetAGI(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAGI(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetINT); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetINT) -{ +XS(XS_Mob_GetINT) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetINT(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetINT(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWIS); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWIS) -{ +XS(XS_Mob_GetWIS) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWIS(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetWIS(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetCHA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetCHA) -{ +XS(XS_Mob_GetCHA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetCHA(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCHA(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMR) -{ +XS(XS_Mob_GetMR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetFR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetFR) -{ +XS(XS_Mob_GetFR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetFR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetFR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDR) -{ +XS(XS_Mob_GetDR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetDR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetPR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetPR) -{ +XS(XS_Mob_GetPR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetPR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetCR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetCR) -{ +XS(XS_Mob_GetCR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetCR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetCorruption); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetCorruption) -{ +XS(XS_Mob_GetCorruption) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetCorruption(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorrup(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetPhR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetPhR) -{ +XS(XS_Mob_GetPhR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetPhR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPhR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxSTR); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxSTR) -{ +XS(XS_Mob_GetMaxSTR) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxSTR(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxSTR(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxSTA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxSTA) -{ +XS(XS_Mob_GetMaxSTA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxSTA(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxSTA(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxDEX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxDEX) -{ +XS(XS_Mob_GetMaxDEX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxDEX(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxDEX(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxAGI); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxAGI) -{ +XS(XS_Mob_GetMaxAGI) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxAGI(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxAGI(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxINT); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxINT) -{ +XS(XS_Mob_GetMaxINT) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxINT(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxINT(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxWIS); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxWIS) -{ +XS(XS_Mob_GetMaxWIS) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxWIS(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxWIS(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetMaxCHA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetMaxCHA) -{ +XS(XS_Mob_GetMaxCHA) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMaxCHA(THIS)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxCHA(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetActSpellRange); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetActSpellRange) -{ +XS(XS_Mob_GetActSpellRange) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetActSpellRange(THIS, spell_id, range)"); + Perl_croak(aTHX_ "Usage: Mob::GetActSpellRange(THIS, uint16 spell_id, float range)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); - float range = (float)SvNV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(1)); + float range = (float) SvNV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetActSpellRange(spell_id, range); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetActSpellDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetActSpellDamage) -{ +XS(XS_Mob_GetActSpellDamage) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetActSpellDamage(THIS, spell_id, value)"); + Perl_croak(aTHX_ "Usage: Mob::GetActSpellDamage(THIS, uint16 spell_id, int32 value)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); - int32 value = (int32)SvIV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(1)); + int32 value = (int32) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetActSpellDamage(spell_id, value); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetActSpellHealing); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetActSpellHealing) -{ +XS(XS_Mob_GetActSpellHealing) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetActSpellHealing(THIS, spell_id, value)"); + Perl_croak(aTHX_ "Usage: Mob::GetActSpellHealing(THIS, uint16 spell_id, int32 value)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); - int32 value = (int32)SvIV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(1)); + int32 value = (int32) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetActSpellHealing(spell_id, value); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetActSpellCost); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetActSpellCost) -{ +XS(XS_Mob_GetActSpellCost) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetActSpellCost(THIS, spell_id, cost)"); + Perl_croak(aTHX_ "Usage: Mob::GetActSpellCost(THIS, uint16 spell_id, int32 cost)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); - int32 cost = (int32)SvIV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(1)); + int32 cost = (int32) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetActSpellCost(spell_id, cost); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetActSpellDuration); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetActSpellDuration) -{ +XS(XS_Mob_GetActSpellDuration) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetActSpellDuration(THIS, spell_id, duration)"); + Perl_croak(aTHX_ "Usage: Mob::GetActSpellDuration(THIS, uint16 spell_id, int32 duration)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); - int32 duration = (int32)SvIV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(1)); + int32 duration = (int32) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetActSpellDuration(spell_id, duration); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetActSpellCasttime); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetActSpellCasttime) -{ +XS(XS_Mob_GetActSpellCasttime) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetActSpellCasttime(THIS, spell_id, casttime)"); + Perl_croak(aTHX_ "Usage: Mob::GetActSpellCasttime(THIS, uint16 spell_id, uint32 cast_time)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); - int32 casttime = (int32)SvIV(ST(2)); + uint16 spell_id = (uint16) SvUV(ST(1)); + int32 casttime = (int32) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetActSpellCasttime(spell_id, casttime); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_ResistSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ResistSpell) -{ +XS(XS_Mob_ResistSpell) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Mob::ResistSpell(THIS, ressit_type, spell_id, caster)"); + Perl_croak(aTHX_ "Usage: Mob::ResistSpell(THIS, uint8 resist_type, uint16 spell_id, [Mob* caster = nullptr])"); { - Mob * THIS; - double RETVAL; + Mob *THIS; + double RETVAL; dXSTARG; - uint8 ressit_type = (uint8)SvUV(ST(1)); - uint16 spell_id = (uint16)SvUV(ST(2)); - Mob * caster; + uint8 ressit_type = (uint8) SvUV(ST(1)); + uint16 spell_id = (uint16) SvUV(ST(2)); + Mob *caster; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(3), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(3))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(3))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); RETVAL = THIS->ResistSpell(ressit_type, spell_id, caster); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSpecializeSkillValue); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSpecializeSkillValue) -{ +XS(XS_Mob_GetSpecializeSkillValue) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetSpecializeSkillValue(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Mob::GetSpecializeSkillValue(THIS, uint16 spell_id)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; - uint16 spell_id = (uint16)SvUV(ST(1)); + uint16 spell_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpecializeSkillValue(spell_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetNPCTypeID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetNPCTypeID) -{ +XS(XS_Mob_GetNPCTypeID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetNPCTypeID(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetNPCTypeID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsTargeted); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsTargeted) -{ +XS(XS_Mob_IsTargeted) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsTargeted(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsTargeted(); @@ -3458,283 +3284,271 @@ XS(XS_Mob_IsTargeted) } XS(XS_Mob_GetX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetX) -{ +XS(XS_Mob_GetX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetX(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetX(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetY) -{ +XS(XS_Mob_GetY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetY(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetY(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetZ) -{ +XS(XS_Mob_GetZ) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetZ(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetZ(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHeading) -{ +XS(XS_Mob_GetHeading) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHeading(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHeading(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWaypointX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWaypointX) -{ +XS(XS_Mob_GetWaypointX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWaypointX(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCurrentWayPoint().x; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWaypointY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWaypointY) -{ +XS(XS_Mob_GetWaypointY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWaypointY(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCurrentWayPoint().y; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWaypointZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWaypointZ) -{ +XS(XS_Mob_GetWaypointZ) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWaypointZ(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCurrentWayPoint().z; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWaypointH); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWaypointH) -{ +XS(XS_Mob_GetWaypointH) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWaypointH(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCurrentWayPoint().w; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWaypointPause); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWaypointPause) -{ +XS(XS_Mob_GetWaypointPause) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWaypointPause(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCWPP(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetWaypointID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetWaypointID) -{ +XS(XS_Mob_GetWaypointID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetWaypointID(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCWP(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetCurrentWP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetCurrentWP) -{ +XS(XS_Mob_SetCurrentWP) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::SetCurrentWP(THIS, waypoint)"); { - Mob * THIS; - uint16 waypoint = (uint16)SvUV(ST(1)); + Mob *THIS; + uint16 waypoint = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetCurrentWP(waypoint); @@ -3743,48 +3557,45 @@ XS(XS_Mob_SetCurrentWP) } XS(XS_Mob_GetSize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSize) -{ +XS(XS_Mob_GetSize) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetSize(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSize(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetFollowID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetFollowID) -{ +XS(XS_Mob_SetFollowID) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::SetFollowID(THIS, id)"); { - Mob * THIS; - uint32 id = (uint32)SvUV(ST(1)); + Mob *THIS; + uint32 id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetFollowID(id); @@ -3793,49 +3604,46 @@ XS(XS_Mob_SetFollowID) } XS(XS_Mob_GetFollowID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetFollowID) -{ +XS(XS_Mob_GetFollowID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetFollowID(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetFollowID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_Message); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Message) -{ +XS(XS_Mob_Message) { dXSARGS; if (items < 3) - Perl_croak(aTHX_ "Usage: Mob::Message(THIS, type, message, ...)"); + Perl_croak(aTHX_ "Usage: Mob::Message(THIS, uint32 emote_color_type, string message)"); { - Mob * THIS; - uint32 type = (uint32)SvUV(ST(1)); - char* message = (char *)SvPV_nolen(ST(2)); + Mob *THIS; + uint32 type = (uint32) SvUV(ST(1)); + char *message = (char *) SvPV_nolen(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Message(type, message); @@ -3844,30 +3652,29 @@ XS(XS_Mob_Message) } XS(XS_Mob_Message_StringID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Message_StringID) -{ +XS(XS_Mob_Message_StringID) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::Message_StringID(THIS, type, string_id, distance= 0)"); + Perl_croak(aTHX_ + "Usage: Mob::Message_StringID(THIS, uint32 emote_color_type, uint32 string_id, [uint32 distance = 0])"); { - Mob * THIS; - uint32 type = (uint32)SvUV(ST(1)); - uint32 string_id = (uint32)SvUV(ST(2)); - uint32 distance; + Mob *THIS; + uint32 type = (uint32) SvUV(ST(1)); + uint32 string_id = (uint32) SvUV(ST(2)); + uint32 distance; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) distance = 0; else { - distance = (uint32)SvUV(ST(3)); + distance = (uint32) SvUV(ST(3)); } THIS->Message_StringID(type, string_id, distance); @@ -3876,22 +3683,20 @@ XS(XS_Mob_Message_StringID) } XS(XS_Mob_Say); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Say) -{ +XS(XS_Mob_Say) { dXSARGS; if (items < 2) - Perl_croak(aTHX_ "Usage: Mob::Say(THIS, format, ...)"); + Perl_croak(aTHX_ "Usage: Mob::Say(THIS, string message)"); { - Mob * THIS; - char * format = (char *)SvPV_nolen(ST(1)); + Mob *THIS; + char *format = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Say(format); @@ -3900,22 +3705,20 @@ XS(XS_Mob_Say) } XS(XS_Mob_Shout); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Shout) -{ +XS(XS_Mob_Shout) { dXSARGS; if (items < 2) - Perl_croak(aTHX_ "Usage: Mob::Shout(THIS, format, ...)"); + Perl_croak(aTHX_ "Usage: Mob::Shout(THIS, string message)"); { - Mob * THIS; - char * format = (char *)SvPV_nolen(ST(1)); + Mob *THIS; + char *format = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Shout(format); @@ -3924,22 +3727,20 @@ XS(XS_Mob_Shout) } XS(XS_Mob_Emote); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Emote) -{ +XS(XS_Mob_Emote) { dXSARGS; if (items < 2) - Perl_croak(aTHX_ "Usage: Mob::Emote(THIS, format, ...)"); + Perl_croak(aTHX_ "Usage: Mob::Emote(THIS, string message)"); { - Mob * THIS; - char * format = (char *)SvPV_nolen(ST(1)); + Mob *THIS; + char *format = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Emote(format); @@ -3948,28 +3749,26 @@ XS(XS_Mob_Emote) } XS(XS_Mob_InterruptSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_InterruptSpell) -{ +XS(XS_Mob_InterruptSpell) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Mob::InterruptSpell(THIS, spellid= 0xFFFF)"); + Perl_croak(aTHX_ "Usage: Mob::InterruptSpell(THIS, [uint16 spell_id = 0xFFFF])"); { - Mob * THIS; - uint16 spellid; + Mob *THIS; + uint16 spellid; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) spellid = 0xFFFF; else { - spellid = (uint16)SvUV(ST(1)); + spellid = (uint16) SvUV(ST(1)); } THIS->InterruptSpell(spellid); @@ -3978,27 +3777,26 @@ XS(XS_Mob_InterruptSpell) } XS(XS_Mob_CastSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CastSpell) -{ +XS(XS_Mob_CastSpell) { dXSARGS; if (items < 3 || items > 7) - Perl_croak(aTHX_ "Usage: Mob::CastSpell(THIS, spell_id, target_id, slot= 22, casttime= -1, mana_cost= -1, resist_adjust = 0)"); + Perl_croak(aTHX_ + "Usage: Mob::CastSpell(THIS, uint16 spell_id, uint16 target_id, [int slot = 22], [int32 cast_time = -1], [int32 mana_cost = -1], [int16 resist_adjust = 0])"); { - Mob * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); - uint16 target_id = (uint16)SvUV(ST(2)); + Mob *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); + uint16 target_id = (uint16) SvUV(ST(2)); EQEmu::CastingSlot slot; - int32 casttime; - int32 mana_cost; - int16 resist_adjust; + int32 casttime; + int32 mana_cost; + int16 resist_adjust; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) @@ -4010,80 +3808,73 @@ XS(XS_Mob_CastSpell) if (items < 5) casttime = -1; else { - casttime = (int32)SvIV(ST(4)); + casttime = (int32) SvIV(ST(4)); } if (items < 6) mana_cost = -1; else { - mana_cost = (int32)SvIV(ST(5)); + mana_cost = (int32) SvIV(ST(5)); } - if(items < 7) - { - resist_adjust = 0; - } - else - { - resist_adjust = (int16)SvIV(ST(6)); - } + if (items < 7) { + resist_adjust = 0; + } else { + resist_adjust = (int16) SvIV(ST(6)); + } - if (resist_adjust == 0)//If you do not pass resist adjust as nullptr it will ignore the spells default resist adjust + if (resist_adjust == + 0)//If you do not pass resist adjust as nullptr it will ignore the spells default resist adjust THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0); else - THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, &resist_adjust); + THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, + &resist_adjust); } XSRETURN_EMPTY; } XS(XS_Mob_SpellFinished); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SpellFinished) -{ +XS(XS_Mob_SpellFinished) { dXSARGS; if (items < 2 || items > 5) - Perl_croak(aTHX_ "Usage: Mob::SpellFinished(spell_id, spell_target = this, mana_cost = 0, resist_diff = 0)"); + Perl_croak(aTHX_ + "Usage: Mob::SpellFinished(uint16 spell_id, [Mob* spell_target = this], [uint16 mana_cost = 0], [uint16 resist_diff = 0])"); { - Mob * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); - Mob * spell_target; - uint16 mana_cost = 0; - int16 resist_diff; + Mob *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); + Mob *spell_target; + uint16 mana_cost = 0; + int16 resist_diff; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); spell_target = THIS; - if (items > 2) - { + if (items > 2) { if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - spell_target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + spell_target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "spell_target is not of type Mob"); - if(spell_target == nullptr) + if (spell_target == nullptr) Perl_croak(aTHX_ "spell_target is nullptr, avoiding crash."); } if (items > 3) - mana_cost = (uint16)SvUV(ST(3)); + mana_cost = (uint16) SvUV(ST(3)); - if (items > 4) - { - resist_diff = (int16)SvUV(ST(4)); - } - else - { - resist_diff = spells[spell_id].ResistDiff; - } + if (items > 4) { + resist_diff = (int16) SvUV(ST(4)); + } else { + resist_diff = spells[spell_id].ResistDiff; + } THIS->SpellFinished(spell_id, spell_target, EQEmu::CastingSlot::Item, mana_cost, -1, resist_diff); } @@ -4091,59 +3882,54 @@ XS(XS_Mob_SpellFinished) } XS(XS_Mob_IsImmuneToSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsImmuneToSpell) -{ +XS(XS_Mob_IsImmuneToSpell) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::IsImmuneToSpell(THIS, spell_id, caster)"); + Perl_croak(aTHX_ "Usage: Mob::IsImmuneToSpell(THIS, uint16 spell_id, [Mob* caster = nullptr])"); { - Mob * THIS; - bool RETVAL; - uint16 spell_id = (uint16)SvUV(ST(1)); - Mob * caster; + Mob *THIS; + bool RETVAL; + uint16 spell_id = (uint16) SvUV(ST(1)); + Mob *caster; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); RETVAL = THIS->IsImmuneToSpell(spell_id, caster); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_BuffFadeBySpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_BuffFadeBySpellID) -{ +XS(XS_Mob_BuffFadeBySpellID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::BuffFadeBySpellID(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: Mob::BuffFadeBySpellID(THIS, uint16 spell_id)"); { - Mob * THIS; - uint16 spell_id = (uint16)SvUV(ST(1)); + Mob *THIS; + uint16 spell_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->BuffFadeBySpellID(spell_id); @@ -4152,29 +3938,27 @@ XS(XS_Mob_BuffFadeBySpellID) } XS(XS_Mob_BuffFadeByEffect); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_BuffFadeByEffect) -{ +XS(XS_Mob_BuffFadeByEffect) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::BuffFadeByEffect(THIS, effectid, skipslot= -1)"); + Perl_croak(aTHX_ "Usage: Mob::BuffFadeByEffect(THIS, int effect_id, int skip_slot = -1)"); { - Mob * THIS; - int effectid = (int)SvIV(ST(1)); - int skipslot; + Mob *THIS; + int effectid = (int) SvIV(ST(1)); + int skipslot; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) skipslot = -1; else { - skipslot = (int)SvIV(ST(2)); + skipslot = (int) SvIV(ST(2)); } THIS->BuffFadeByEffect(effectid, skipslot); @@ -4183,21 +3967,19 @@ XS(XS_Mob_BuffFadeByEffect) } XS(XS_Mob_BuffFadeAll); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_BuffFadeAll) -{ +XS(XS_Mob_BuffFadeAll) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::BuffFadeAll(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->BuffFadeAll(); @@ -4206,29 +3988,27 @@ XS(XS_Mob_BuffFadeAll) } XS(XS_Mob_BuffFadeBySlot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_BuffFadeBySlot) -{ +XS(XS_Mob_BuffFadeBySlot) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::BuffFadeBySlot(THIS, slot, iRecalcBonuses= true)"); + Perl_croak(aTHX_ "Usage: Mob::BuffFadeBySlot(THIS, int slot, bool recalc_bonuses = true)"); { - Mob * THIS; - int slot = (int)SvIV(ST(1)); - bool iRecalcBonuses; + Mob *THIS; + int slot = (int) SvIV(ST(1)); + bool iRecalcBonuses; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) iRecalcBonuses = true; else { - iRecalcBonuses = (bool)SvTRUE(ST(2)); + iRecalcBonuses = (bool) SvTRUE(ST(2)); } THIS->BuffFadeBySlot(slot, iRecalcBonuses); @@ -4237,57 +4017,55 @@ XS(XS_Mob_BuffFadeBySlot) } XS(XS_Mob_CanBuffStack); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanBuffStack) -{ +XS(XS_Mob_CanBuffStack) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::CanBuffStack(THIS, spellid, caster_level, iFailIfOverwrite= false)"); + Perl_croak(aTHX_ + "Usage: Mob::CanBuffStack(THIS, uint16 spell_id, uint8 caster_level, [bool fail_if_overwritten = false])"); { - Mob * THIS; - int RETVAL; + Mob *THIS; + int RETVAL; dXSTARG; - uint16 spellid = (uint16)SvUV(ST(1)); - uint8 caster_level = (uint8)SvUV(ST(2)); - bool iFailIfOverwrite; + uint16 spellid = (uint16) SvUV(ST(1)); + uint8 caster_level = (uint8) SvUV(ST(2)); + bool iFailIfOverwrite; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) iFailIfOverwrite = false; else { - iFailIfOverwrite = (bool)SvTRUE(ST(3)); + iFailIfOverwrite = (bool) SvTRUE(ST(3)); } RETVAL = THIS->CanBuffStack(spellid, caster_level, iFailIfOverwrite); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsCasting); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsCasting) -{ +XS(XS_Mob_IsCasting) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsCasting(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsCasting(); @@ -4298,55 +4076,52 @@ XS(XS_Mob_IsCasting) } XS(XS_Mob_CastingSpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CastingSpellID) -{ +XS(XS_Mob_CastingSpellID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CastingSpellID(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CastingSpellID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetAppearance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetAppearance) -{ +XS(XS_Mob_SetAppearance) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::SetAppearance(THIS, app, iIgnoreSelf= true)"); + Perl_croak(aTHX_ "Usage: Mob::SetAppearance(THIS, int appearance [0|1|2|3|4], [ignore_self = true])"); { - Mob * THIS; - EmuAppearance app = (EmuAppearance)SvUV(ST(1)); - bool iIgnoreSelf; + Mob *THIS; + EmuAppearance app = (EmuAppearance) SvUV(ST(1)); + bool iIgnoreSelf; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) iIgnoreSelf = true; else { - iIgnoreSelf = (bool)SvTRUE(ST(2)); + iIgnoreSelf = (bool) SvTRUE(ST(2)); } THIS->SetAppearance(app, iIgnoreSelf); @@ -4355,74 +4130,70 @@ XS(XS_Mob_SetAppearance) } XS(XS_Mob_GetAppearance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAppearance) -{ +XS(XS_Mob_GetAppearance) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetAppearance(THIS)"); { - Mob * THIS; - EmuAppearance RETVAL; + Mob *THIS; + EmuAppearance RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAppearance(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetRunAnimSpeed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetRunAnimSpeed) -{ +XS(XS_Mob_GetRunAnimSpeed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetRunAnimSpeed(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetRunAnimSpeed(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetRunAnimSpeed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetRunAnimSpeed) -{ +XS(XS_Mob_SetRunAnimSpeed) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetRunAnimSpeed(THIS, in)"); + Perl_croak(aTHX_ "Usage: Mob::SetRunAnimSpeed(THIS, int8 speed)"); { - Mob * THIS; - int8 in = (int8)SvIV(ST(1)); + Mob *THIS; + int8 in = (int8) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetRunAnimSpeed(in); @@ -4431,22 +4202,20 @@ XS(XS_Mob_SetRunAnimSpeed) } XS(XS_Mob_SetPetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetPetID) -{ +XS(XS_Mob_SetPetID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetPetID(THIS, NewPetID)"); + Perl_croak(aTHX_ "Usage: Mob::SetPetID(THIS, uint16 new_pet_id)"); { - Mob * THIS; - uint16 NewPetID = (uint16)SvUV(ST(1)); + Mob *THIS; + uint16 NewPetID = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetPetID(NewPetID); @@ -4455,48 +4224,45 @@ XS(XS_Mob_SetPetID) } XS(XS_Mob_GetPetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetPetID) -{ +XS(XS_Mob_GetPetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetPetID(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPetID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetOwnerID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetOwnerID) -{ +XS(XS_Mob_SetOwnerID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetOwnerID(THIS, NewOwnerID)"); + Perl_croak(aTHX_ "Usage: Mob::SetOwnerID(THIS, uint16 new_owner_id)"); { - Mob * THIS; - uint16 NewOwnerID = (uint16)SvUV(ST(1)); + Mob *THIS; + uint16 NewOwnerID = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetOwnerID(NewOwnerID); @@ -4505,100 +4271,95 @@ XS(XS_Mob_SetOwnerID) } XS(XS_Mob_GetOwnerID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetOwnerID) -{ +XS(XS_Mob_GetOwnerID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetOwnerID(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetOwnerID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetPetType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetPetType) -{ +XS(XS_Mob_GetPetType) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetPetType(THIS)"); { - Mob * THIS; - uint16 RETVAL; + Mob *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPetType(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetBodyType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetBodyType) -{ +XS(XS_Mob_GetBodyType) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetBodyType(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetBodyType(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_Stun); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Stun) -{ +XS(XS_Mob_Stun) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::Stun(THIS, duration)"); + Perl_croak(aTHX_ "Usage: Mob::Stun(THIS, int duration)"); { - Mob * THIS; - int duration = (int)SvIV(ST(1)); + Mob *THIS; + int duration = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Stun(duration); @@ -4607,21 +4368,19 @@ XS(XS_Mob_Stun) } XS(XS_Mob_Spin); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Spin) -{ +XS(XS_Mob_Spin) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::Spin(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Spin(); @@ -4630,21 +4389,19 @@ XS(XS_Mob_Spin) } XS(XS_Mob_Kill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Kill) -{ +XS(XS_Mob_Kill) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::Kill(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Kill(); @@ -4653,22 +4410,20 @@ XS(XS_Mob_Kill) } XS(XS_Mob_SetInvul); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetInvul) -{ +XS(XS_Mob_SetInvul) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetInvul(THIS, invul)"); + Perl_croak(aTHX_ "Usage: Mob::SetInvul(THIS, bool set_invulnerable)"); { - Mob * THIS; - bool invul = (bool)SvTRUE(ST(1)); + Mob *THIS; + bool invul = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetInvul(invul); @@ -4677,22 +4432,20 @@ XS(XS_Mob_SetInvul) } XS(XS_Mob_GetInvul); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetInvul) -{ +XS(XS_Mob_GetInvul) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetInvul(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetInvul(); @@ -4703,22 +4456,20 @@ XS(XS_Mob_GetInvul) } XS(XS_Mob_SetExtraHaste); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetExtraHaste) -{ +XS(XS_Mob_SetExtraHaste) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetExtraHaste(THIS, Haste)"); + Perl_croak(aTHX_ "Usage: Mob::SetExtraHaste(THIS, int haste)"); { - Mob * THIS; - int Haste = (int)SvIV(ST(1)); + Mob *THIS; + int Haste = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetExtraHaste(Haste); @@ -4727,74 +4478,70 @@ XS(XS_Mob_SetExtraHaste) } XS(XS_Mob_GetHaste); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHaste) -{ +XS(XS_Mob_GetHaste) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHaste(THIS)"); { - Mob * THIS; - int RETVAL; + Mob *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHaste(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHandToHandDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHandToHandDamage) -{ +XS(XS_Mob_GetHandToHandDamage) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHandToHandDamage(THIS)"); { - Mob * THIS; - int RETVAL; + Mob *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHandToHandDamage(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_CanThisClassDoubleAttack); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanThisClassDoubleAttack) -{ +XS(XS_Mob_CanThisClassDoubleAttack) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CanThisClassDoubleAttack(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanThisClassDoubleAttack(); @@ -4805,22 +4552,20 @@ XS(XS_Mob_CanThisClassDoubleAttack) } XS(XS_Mob_CanThisClassDualWield); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanThisClassDualWield) -{ +XS(XS_Mob_CanThisClassDualWield) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CanThisClassDualWield(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanThisClassDualWield(); @@ -4831,22 +4576,20 @@ XS(XS_Mob_CanThisClassDualWield) } XS(XS_Mob_CanThisClassRiposte); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanThisClassRiposte) -{ +XS(XS_Mob_CanThisClassRiposte) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CanThisClassRiposte(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanThisClassRiposte(); @@ -4857,22 +4600,20 @@ XS(XS_Mob_CanThisClassRiposte) } XS(XS_Mob_CanThisClassDodge); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanThisClassDodge) -{ +XS(XS_Mob_CanThisClassDodge) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CanThisClassDodge(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanThisClassDodge(); @@ -4883,22 +4624,20 @@ XS(XS_Mob_CanThisClassDodge) } XS(XS_Mob_CanThisClassParry); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanThisClassParry) -{ +XS(XS_Mob_CanThisClassParry) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::CanThisClassParry(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanThisClassParry(); @@ -4909,73 +4648,69 @@ XS(XS_Mob_CanThisClassParry) } XS(XS_Mob_GetHandToHandDelay); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHandToHandDelay) -{ +XS(XS_Mob_GetHandToHandDelay) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHandToHandDelay(THIS)"); { - Mob * THIS; - int RETVAL; + Mob *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHandToHandDelay(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetClassLevelFactor); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetClassLevelFactor) -{ +XS(XS_Mob_GetClassLevelFactor) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetClassLevelFactor(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClassLevelFactor(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_Mesmerize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Mesmerize) -{ +XS(XS_Mob_Mesmerize) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::Mesmerize(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Mesmerize(); @@ -4984,22 +4719,20 @@ XS(XS_Mob_Mesmerize) } XS(XS_Mob_IsMezzed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsMezzed) -{ +XS(XS_Mob_IsMezzed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsMezzed(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsMezzed(); @@ -5010,22 +4743,20 @@ XS(XS_Mob_IsMezzed) } XS(XS_Mob_IsStunned); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsStunned) -{ +XS(XS_Mob_IsStunned) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsStunned(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsStunned(); @@ -5037,21 +4768,19 @@ XS(XS_Mob_IsStunned) XS(XS_Mob_StartEnrage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_StartEnrage) -{ +XS(XS_Mob_StartEnrage) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::StartEnrage(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->StartEnrage(); @@ -5060,22 +4789,20 @@ XS(XS_Mob_StartEnrage) } XS(XS_Mob_IsEnraged); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsEnraged) -{ +XS(XS_Mob_IsEnraged) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsEnraged(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsEnraged(); @@ -5086,58 +4813,54 @@ XS(XS_Mob_IsEnraged) } XS(XS_Mob_GetReverseFactionCon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetReverseFactionCon) -{ +XS(XS_Mob_GetReverseFactionCon) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::GetReverseFactionCon(THIS, iOther)"); { - Mob * THIS; - FACTION_VALUE RETVAL; + Mob *THIS; + FACTION_VALUE RETVAL; dXSTARG; - Mob* iOther; + Mob *iOther; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - iOther = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + iOther = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "iOther is not of type Mob"); - if(iOther == nullptr) + if (iOther == nullptr) Perl_croak(aTHX_ "iOther is nullptr, avoiding crash."); RETVAL = THIS->GetReverseFactionCon(iOther); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsAIControlled); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsAIControlled) -{ +XS(XS_Mob_IsAIControlled) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsAIControlled(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsAIControlled(); @@ -5148,74 +4871,70 @@ XS(XS_Mob_IsAIControlled) } XS(XS_Mob_GetAggroRange); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAggroRange) -{ +XS(XS_Mob_GetAggroRange) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetAggroRange(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAggroRange(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetAssistRange); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAssistRange) -{ +XS(XS_Mob_GetAssistRange) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetAssistRange(THIS)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAssistRange(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetPetOrder); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetPetOrder) -{ +XS(XS_Mob_SetPetOrder) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::SetPetOrder(THIS, i)"); { - Mob * THIS; - Mob::eStandingPetOrder i = (Mob::eStandingPetOrder)SvIV(ST(1)); + Mob *THIS; + Mob::eStandingPetOrder i = (Mob::eStandingPetOrder) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetPetOrder(i); @@ -5224,48 +4943,45 @@ XS(XS_Mob_SetPetOrder) } XS(XS_Mob_GetPetOrder); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetPetOrder) -{ +XS(XS_Mob_GetPetOrder) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetPetOrder(THIS)"); { - Mob * THIS; - Mob::eStandingPetOrder RETVAL; + Mob *THIS; + Mob::eStandingPetOrder RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPetOrder(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsRoamer); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsRoamer) -{ +XS(XS_Mob_IsRoamer) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsRoamer(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsRoamer(); @@ -5276,22 +4992,20 @@ XS(XS_Mob_IsRoamer) } XS(XS_Mob_IsRooted); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsRooted) -{ +XS(XS_Mob_IsRooted) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsRooted(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsRooted(); @@ -5302,66 +5016,64 @@ XS(XS_Mob_IsRooted) } XS(XS_Mob_AddToHateList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_AddToHateList) -{ +XS(XS_Mob_AddToHateList) { dXSARGS; if (items < 2 || items > 7) - Perl_croak(aTHX_ "Usage: Mob::AddToHateList(THIS, other, hate= 0, damage= 0, iYellForHelp= true, bFrenzy= false, iBuffTic= false)"); + Perl_croak(aTHX_ + "Usage: Mob::AddToHateList(THIS, Mob* other, [int32 hate = 0], [int32 damage = 0], [bool yell_for_help = true], [bool frenzy = false], [bool buff_tic = false])"); { - Mob * THIS; - Mob* other; - int32 hate; - int32 damage; - bool iYellForHelp; - bool bFrenzy; - bool iBuffTic; + Mob *THIS; + Mob *other; + int32 hate; + int32 damage; + bool iYellForHelp; + bool bFrenzy; + bool iBuffTic; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); if (items < 3) hate = 0; else { - hate = (int32)SvIV(ST(2)); + hate = (int32) SvIV(ST(2)); } if (items < 4) damage = 0; else { - damage = (int32)SvIV(ST(3)); + damage = (int32) SvIV(ST(3)); } if (items < 5) iYellForHelp = true; else { - iYellForHelp = (bool)SvTRUE(ST(4)); + iYellForHelp = (bool) SvTRUE(ST(4)); } if (items < 6) bFrenzy = false; else { - bFrenzy = (bool)SvTRUE(ST(5)); + bFrenzy = (bool) SvTRUE(ST(5)); } if (items < 7) iBuffTic = false; else { - iBuffTic = (bool)SvTRUE(ST(6)); + iBuffTic = (bool) SvTRUE(ST(6)); } THIS->AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic); @@ -5370,45 +5082,42 @@ XS(XS_Mob_AddToHateList) } XS(XS_Mob_SetHate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetHate) -{ +XS(XS_Mob_SetHate) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::SetHate(THIS, other, hate= 0, damage= 0)"); + Perl_croak(aTHX_ "Usage: Mob::SetHate(THIS, Mob* other, [int32 hate = 0], [int32 damage = 0])"); { - Mob * THIS; - Mob* other; - int32 hate; - int32 damage; + Mob *THIS; + Mob *other; + int32 hate; + int32 damage; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); if (items < 3) hate = 0; else { - hate = (int32)SvIV(ST(2)); + hate = (int32) SvIV(ST(2)); } if (items < 4) damage = 0; else { - damage = (int32)SvIV(ST(3)); + damage = (int32) SvIV(ST(3)); } THIS->SetHateAmountOnEnt(other, hate, damage); @@ -5417,31 +5126,28 @@ XS(XS_Mob_SetHate) } XS(XS_Mob_HalveAggro); -XS(XS_Mob_HalveAggro) -{ +XS(XS_Mob_HalveAggro) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::HalveAggro(THIS, other)"); + Perl_croak(aTHX_ "Usage: Mob::HalveAggro(THIS, Mob* other)"); { - Mob * THIS; - Mob * other; + Mob *THIS; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->HalveAggro(other); @@ -5450,31 +5156,28 @@ XS(XS_Mob_HalveAggro) } XS(XS_Mob_DoubleAggro); -XS(XS_Mob_DoubleAggro) -{ +XS(XS_Mob_DoubleAggro) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::DoubleAggro(THIS, other)"); + Perl_croak(aTHX_ "Usage: Mob::DoubleAggro(THIS, Mob* other)"); { - Mob * THIS; - Mob * other; + Mob *THIS; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->DoubleAggro(other); @@ -5483,189 +5186,176 @@ XS(XS_Mob_DoubleAggro) } XS(XS_Mob_GetHateAmount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHateAmount) -{ +XS(XS_Mob_GetHateAmount) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::GetHateAmount(THIS, tmob, is_dam= false)"); + Perl_croak(aTHX_ "Usage: Mob::GetHateAmount(THIS, Mob* mob, [bool is_damage = false])"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - Mob* tmob; - bool is_dam; + Mob *tmob; + bool is_dam; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - tmob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + tmob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "tmob is not of type Mob"); - if(tmob == nullptr) + if (tmob == nullptr) Perl_croak(aTHX_ "tmob is nullptr, avoiding crash."); if (items < 3) is_dam = false; else { - is_dam = (bool)SvTRUE(ST(2)); + is_dam = (bool) SvTRUE(ST(2)); } RETVAL = THIS->GetHateAmount(tmob, is_dam); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetDamageAmount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetDamageAmount) -{ +XS(XS_Mob_GetDamageAmount) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetDamageAmount(THIS, tmob)"); + Perl_croak(aTHX_ "Usage: Mob::GetDamageAmount(THIS, Mob* target_mob)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - Mob* tmob; + Mob *tmob; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - tmob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + tmob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "tmob is not of type Mob"); - if(tmob == nullptr) + if (tmob == nullptr) Perl_croak(aTHX_ "tmob is nullptr, avoiding crash."); RETVAL = THIS->GetDamageAmount(tmob); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHateTop); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHateTop) -{ +XS(XS_Mob_GetHateTop) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHateTop(THIS)"); { - Mob * THIS; - Mob * RETVAL; + Mob *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHateTop(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHateDamageTop); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHateDamageTop) -{ +XS(XS_Mob_GetHateDamageTop) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetHateDamageTop(THIS, other)"); + Perl_croak(aTHX_ "Usage: Mob::GetHateDamageTop(THIS, Mob* other)"); { - Mob * THIS; - Mob * RETVAL; - Mob* other; + Mob *THIS; + Mob *RETVAL; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); RETVAL = THIS->GetHateDamageTop(other); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetHateRandom); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHateRandom) -{ +XS(XS_Mob_GetHateRandom) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetHateRandom(THIS)"); { - Mob * THIS; - Mob * RETVAL; + Mob *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHateRandom(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_IsEngaged); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsEngaged) -{ +XS(XS_Mob_IsEngaged) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsEngaged(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsEngaged(); @@ -5676,22 +5366,20 @@ XS(XS_Mob_IsEngaged) } XS(XS_Mob_HateSummon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_HateSummon) -{ +XS(XS_Mob_HateSummon) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HateSummon(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->HateSummon(); @@ -5702,34 +5390,31 @@ XS(XS_Mob_HateSummon) } XS(XS_Mob_FaceTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_FaceTarget) -{ +XS(XS_Mob_FaceTarget) { dXSARGS; if (items < 1 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::FaceTarget(THIS, MobToFace= 0)"); + Perl_croak(aTHX_ "Usage: Mob::FaceTarget(THIS, [Mob* target = 0])"); { - Mob * THIS; - Mob* MobToFace; + Mob *THIS; + Mob *MobToFace; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) MobToFace = 0; else { if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - MobToFace = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + MobToFace = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "MobToFace is not of type Mob"); - if(MobToFace == nullptr) + if (MobToFace == nullptr) Perl_croak(aTHX_ "MobToFace is nullptr, avoiding crash."); } @@ -5739,22 +5424,20 @@ XS(XS_Mob_FaceTarget) } XS(XS_Mob_SetHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetHeading) -{ +XS(XS_Mob_SetHeading) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetHeading(THIS, iHeading)"); + Perl_croak(aTHX_ "Usage: Mob::SetHeading(THIS, float heading)"); { - Mob * THIS; - float iHeading = (float)SvNV(ST(1)); + Mob *THIS; + float iHeading = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetHeading(iHeading); @@ -5763,21 +5446,19 @@ XS(XS_Mob_SetHeading) } XS(XS_Mob_WipeHateList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_WipeHateList) -{ +XS(XS_Mob_WipeHateList) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::WipeHateList(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->WipeHateList(); @@ -5786,32 +5467,29 @@ XS(XS_Mob_WipeHateList) } XS(XS_Mob_CheckAggro); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CheckAggro) -{ +XS(XS_Mob_CheckAggro) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::CheckAggro(THIS, other)"); + Perl_croak(aTHX_ "Usage: Mob::CheckAggro(THIS, Mob* other)"); { - Mob * THIS; - bool RETVAL; - Mob* other; + Mob *THIS; + bool RETVAL; + Mob *other; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); RETVAL = THIS->CheckAggro(other); @@ -5822,155 +5500,113 @@ XS(XS_Mob_CheckAggro) } XS(XS_Mob_CalculateHeadingToTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CalculateHeadingToTarget) -{ +XS(XS_Mob_CalculateHeadingToTarget) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::CalculateHeadingToTarget(THIS, in_x, in_y)"); + Perl_croak(aTHX_ "Usage: Mob::CalculateHeadingToTarget(THIS, float x, float y)"); { - Mob * THIS; - int8 RETVAL; + Mob *THIS; + int8 RETVAL; dXSTARG; - float in_x = (float)SvNV(ST(1)); - float in_y = (float)SvNV(ST(2)); + float in_x = (float) SvNV(ST(1)); + float in_y = (float) SvNV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CalculateHeadingToTarget(in_x, in_y); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_CalculateNewPosition); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CalculateNewPosition) -{ +XS(XS_Mob_CalculateNewPosition) { dXSARGS; if (items < 5 || items > 6) - Perl_croak(aTHX_ "Usage: Mob::CalculateNewPosition(THIS, x, y, z, speed, checkZ= false)"); + Perl_croak(aTHX_ + "Usage: Mob::CalculateNewPosition(THIS, float x, float y, float z, float speed, [bool check_z = false])"); { - Mob * THIS; - bool RETVAL; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float speed = (float)SvNV(ST(4)); - bool checkZ; + Mob *THIS; + bool RETVAL; + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); + float speed = (float) SvNV(ST(4)); + bool checkZ; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 6) checkZ = false; else { - checkZ = (bool)SvTRUE(ST(5)); + checkZ = (bool) SvTRUE(ST(5)); } RETVAL = THIS->CalculateNewPosition(x, y, z, speed, checkZ); - ST(0) = boolSV(RETVAL); - sv_2mortal(ST(0)); - } - XSRETURN(1); -} - -XS(XS_Mob_CalculateNewPosition2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CalculateNewPosition2) -{ - dXSARGS; - if (items < 5 || items > 6) - Perl_croak(aTHX_ "Usage: Mob::CalculateNewPosition2(THIS, x, y, z, speed, checkZ= false)"); - { - Mob * THIS; - bool RETVAL; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float speed = (float)SvNV(ST(4)); - bool checkZ; - - if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - if (items < 6) - checkZ = false; - else { - checkZ = (bool)SvTRUE(ST(5)); - } - - RETVAL = THIS->CalculateNewPosition2(x, y, z, speed, checkZ); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_CalculateDistance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CalculateDistance) -{ +XS(XS_Mob_CalculateDistance) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Mob::CalculateDistance(THIS, x, y, z)"); + Perl_croak(aTHX_ "Usage: Mob::CalculateDistance(THIS, float x, float y, float z)"); { - Mob * THIS; - float RETVAL; + Mob *THIS; + float RETVAL; dXSTARG; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CalculateDistance(x, y, z); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_SendTo); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendTo) -{ +XS(XS_Mob_SendTo) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Mob::SendTo(THIS, new_x, new_y, new_z)"); + Perl_croak(aTHX_ "Usage: Mob::SendTo(THIS, float new_x, float new_y, float new_z)"); { - Mob * THIS; - float new_x = (float)SvNV(ST(1)); - float new_y = (float)SvNV(ST(2)); - float new_z = (float)SvNV(ST(3)); + Mob *THIS; + float new_x = (float) SvNV(ST(1)); + float new_y = (float) SvNV(ST(2)); + float new_z = (float) SvNV(ST(3)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendTo(new_x, new_y, new_z); @@ -5979,24 +5615,22 @@ XS(XS_Mob_SendTo) } XS(XS_Mob_SendToFixZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendToFixZ) -{ +XS(XS_Mob_SendToFixZ) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Mob::SendToFixZ(THIS, new_x, new_y, new_z)"); + Perl_croak(aTHX_ "Usage: Mob::SendToFixZ(THIS, float new_x, float new_y, float new_z)"); { - Mob * THIS; - float new_x = (float)SvNV(ST(1)); - float new_y = (float)SvNV(ST(2)); - float new_z = (float)SvNV(ST(3)); + Mob *THIS; + float new_x = (float) SvNV(ST(1)); + float new_y = (float) SvNV(ST(2)); + float new_z = (float) SvNV(ST(3)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendToFixZ(new_x, new_y, new_z); @@ -6005,25 +5639,24 @@ XS(XS_Mob_SendToFixZ) } XS(XS_Mob_NPCSpecialAttacks); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_NPCSpecialAttacks) -{ +XS(XS_Mob_NPCSpecialAttacks) { dXSARGS; if (items < 3 || items > 5) - Perl_croak(aTHX_ "Usage: Mob::NPCSpecialAttacks(THIS, parse, permtag, [reset], [remove])"); + Perl_croak(aTHX_ + "Usage: Mob::NPCSpecialAttacks(THIS, string abilities_string, int perm_tag, [bool reset = true], [bool remove = true])"); { - Mob * THIS; - char* parse = (char *)SvPV_nolen(ST(1)); - int permtag = (int)SvIV(ST(2)); - bool reset = items == 4 ? (bool)SvTRUE(ST(3)) : true; - bool remove = items == 5 ? (bool)SvTRUE(ST(4)) : false; + Mob *THIS; + char *parse = (char *) SvPV_nolen(ST(1)); + int permtag = (int) SvIV(ST(2)); + bool reset = items == 4 ? (bool) SvTRUE(ST(3)) : true; + bool remove = items == 5 ? (bool) SvTRUE(ST(4)) : false; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->NPCSpecialAttacks(parse, permtag, reset, remove); @@ -6032,214 +5665,203 @@ XS(XS_Mob_NPCSpecialAttacks) } XS(XS_Mob_DontHealMeBefore); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DontHealMeBefore) -{ +XS(XS_Mob_DontHealMeBefore) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::DontHealMeBefore(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DontHealMeBefore(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_DontBuffMeBefore); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DontBuffMeBefore) -{ +XS(XS_Mob_DontBuffMeBefore) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::DontBuffMeBefore(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DontBuffMeBefore(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_DontDotMeBefore); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DontDotMeBefore) -{ +XS(XS_Mob_DontDotMeBefore) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::DontDotMeBefore(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DontDotMeBefore(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_DontRootMeBefore); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DontRootMeBefore) -{ +XS(XS_Mob_DontRootMeBefore) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::DontRootMeBefore(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DontRootMeBefore(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_DontSnareMeBefore); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DontSnareMeBefore) -{ +XS(XS_Mob_DontSnareMeBefore) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::DontSnareMeBefore(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DontSnareMeBefore(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetResist); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetResist) -{ +XS(XS_Mob_GetResist) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::GetResist(THIS, type)"); { - Mob * THIS; - int16 RETVAL; + Mob *THIS; + int16 RETVAL; dXSTARG; - uint8 type = (uint8)SvUV(ST(1)); + uint8 type = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetResist(type); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetShieldTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetShieldTarget) -{ +XS(XS_Mob_GetShieldTarget) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetShieldTarget(THIS)"); { - Mob * THIS; - Mob * RETVAL; + Mob *THIS; + Mob *RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetShieldTarget(); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Mob", (void*)RETVAL); + sv_setref_pv(ST(0), "Mob", (void *) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetShieldTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetShieldTarget) -{ +XS(XS_Mob_SetShieldTarget) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Mob::SetShieldTarget(THIS, mob)"); { - Mob * THIS; - Mob* mob; + Mob *THIS; + Mob *mob; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); THIS->SetShieldTarget(mob); @@ -6248,22 +5870,20 @@ XS(XS_Mob_SetShieldTarget) } XS(XS_Mob_Charmed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_Charmed) -{ +XS(XS_Mob_Charmed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::Charmed(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Charmed(); @@ -6274,218 +5894,207 @@ XS(XS_Mob_Charmed) } XS(XS_Mob_GetLevelHP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetLevelHP) -{ +XS(XS_Mob_GetLevelHP) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetLevelHP(THIS, tlevel)"); + Perl_croak(aTHX_ "Usage: Mob::GetLevelHP(THIS, uint8 level)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - uint8 tlevel = (uint8)SvUV(ST(1)); + uint8 tlevel = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLevelHP(tlevel); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetZoneID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetZoneID) -{ +XS(XS_Mob_GetZoneID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetZoneID(THIS)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetZoneID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_CheckAggroAmount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CheckAggroAmount) -{ +XS(XS_Mob_CheckAggroAmount) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::CheckAggroAmount(THIS, spellid)"); + Perl_croak(aTHX_ "Usage: Mob::CheckAggroAmount(THIS, uint16 spell_id)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - uint16 spellid = (uint16)SvUV(ST(1)); + uint16 spellid = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CheckAggroAmount(spellid, nullptr); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_CheckHealAggroAmount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CheckHealAggroAmount) -{ +XS(XS_Mob_CheckHealAggroAmount) { dXSARGS; if (items != 2 && items != 3) - Perl_croak(aTHX_ "Usage: Mob::CheckHealAggroAmount(THIS, spellid, possible_heal_amt)"); + Perl_croak(aTHX_ "Usage: Mob::CheckHealAggroAmount(THIS, uint16 spell_id, uint32 possible_heal_amt)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - uint16 spellid = (uint16)SvUV(ST(1)); - uint32 possible = 0; + uint16 spellid = (uint16) SvUV(ST(1)); + uint32 possible = 0; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items == 3) - { - possible = (uint32)SvUV(ST(2)); + if (items == 3) { + possible = (uint32) SvUV(ST(2)); } RETVAL = THIS->CheckHealAggroAmount(spellid, nullptr, possible); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetAA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAA) -{ +XS(XS_Mob_GetAA) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetAA(THIS, rank_id)"); + Perl_croak(aTHX_ "Usage: Mob::GetAA(THIS, uint32 rank_id)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - uint32 rank_id = (uint32)SvUV(ST(1)); + uint32 rank_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAA(rank_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetAAByAAID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAAByAAID) -{ +XS(XS_Mob_GetAAByAAID) { dXSARGS; - if(items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetAAByAAID(THIS, aa_id)"); + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::GetAAByAAID(THIS, uint32 aa_id)"); { - Mob * THIS; - uint32 RETVAL; + Mob *THIS; + uint32 RETVAL; dXSTARG; - uint32 aa_id = (uint32)SvUV(ST(1)); + uint32 aa_id = (uint32) SvUV(ST(1)); - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAAByAAID(aa_id); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetAA); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetAA) -{ +XS(XS_Mob_SetAA) { dXSARGS; - if(items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::SetAA(THIS, aa_id, points, [charges])"); + if (items < 3 || items > 4) + Perl_croak(aTHX_ "Usage: Mob::SetAA(THIS, int aa_id, int points, [int charges = 0])"); { - Mob * THIS; - bool RETVAL; - int aa_id = (int)SvIV(ST(1)); - int points = (int)SvIV(ST(2)); - int charges = (items == 4) ? (int)SvIV(ST(3)) : 0; + Mob *THIS; + bool RETVAL; + int aa_id = (int) SvIV(ST(1)); + int points = (int) SvIV(ST(2)); + int charges = (items == 4) ? (int) SvIV(ST(3)) : 0; - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->SetAA(aa_id, points, charges); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_DivineAura); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DivineAura) -{ +XS(XS_Mob_DivineAura) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::DivineAura(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->DivineAura(); @@ -6496,31 +6105,28 @@ XS(XS_Mob_DivineAura) } XS(XS_Mob_AddFeignMemory); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_AddFeignMemory) -{ +XS(XS_Mob_AddFeignMemory) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::AddFeignMemory(THIS, attacker)"); + Perl_croak(aTHX_ "Usage: Mob::AddFeignMemory(THIS, Client* attacker)"); { - Mob * THIS; - Client* attacker; + Mob *THIS; + Client *attacker; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - attacker = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + attacker = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "attacker is not of type Client"); - if(attacker == nullptr) + if (attacker == nullptr) Perl_croak(aTHX_ "attacker is nullptr, avoiding crash."); THIS->AddFeignMemory(attacker); @@ -6529,31 +6135,28 @@ XS(XS_Mob_AddFeignMemory) } XS(XS_Mob_RemoveFromFeignMemory); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_RemoveFromFeignMemory) -{ +XS(XS_Mob_RemoveFromFeignMemory) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::RemoveFromFeignMemory(THIS, attacker)"); + Perl_croak(aTHX_ "Usage: Mob::RemoveFromFeignMemory(THIS, Client* attacker)"); { - Mob * THIS; - Client* attacker; + Mob *THIS; + Client *attacker; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - attacker = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + attacker = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "attacker is not of type Client"); - if(attacker == nullptr) + if (attacker == nullptr) Perl_croak(aTHX_ "attacker is nullptr, avoiding crash."); THIS->RemoveFromFeignMemory(attacker); @@ -6562,21 +6165,19 @@ XS(XS_Mob_RemoveFromFeignMemory) } XS(XS_Mob_ClearFeignMemory); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ClearFeignMemory) -{ +XS(XS_Mob_ClearFeignMemory) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::ClearFeignMemory(THIS)"); { - Mob * THIS; + Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearFeignMemory(); @@ -6585,22 +6186,20 @@ XS(XS_Mob_ClearFeignMemory) } XS(XS_Mob_SetOOCRegen); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetOOCRegen) -{ +XS(XS_Mob_SetOOCRegen) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetOOCRegen(THIS, newoocregen)"); + Perl_croak(aTHX_ "Usage: Mob::SetOOCRegen(THIS, int32 new_ooc_regen)"); { - Mob * THIS; - int32 newoocregen = (int32)SvIV(ST(1)); + Mob *THIS; + int32 newoocregen = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetOOCRegen(newoocregen); @@ -6609,77 +6208,73 @@ XS(XS_Mob_SetOOCRegen) } XS(XS_Mob_GetEntityVariable); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetEntityVariable) -{ +XS(XS_Mob_GetEntityVariable) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetEntityVariable(THIS, id)"); + Perl_croak(aTHX_ "Usage: Mob::GetEntityVariable(THIS, string id)"); { - Mob * THIS; - Const_char * id = SvPV_nolen(ST(1)); - Const_char * RETVAL; + Mob *THIS; + Const_char *id = SvPV_nolen(ST(1)); + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEntityVariable(id); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Mob_EntityVariableExists); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_EntityVariableExists) -{ +XS(XS_Mob_EntityVariableExists) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::EntityVariableExists(THIS, id)"); + Perl_croak(aTHX_ "Usage: Mob::EntityVariableExists(THIS, string id)"); { - Mob * THIS; - Const_char * id = SvPV_nolen(ST(1)); - bool RETVAL; + Mob *THIS; + Const_char *id = SvPV_nolen(ST(1)); + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->EntityVariableExists(id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_SetEntityVariable); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetEntityVariable) -{ +XS(XS_Mob_SetEntityVariable) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::SetEntityVariable(THIS, id, var)"); + Perl_croak(aTHX_ "Usage: Mob::SetEntityVariable(THIS, string id, string var)"); { - Mob * THIS; - Const_char * id = SvPV_nolen(ST(1)); - const char * var = (const char *)SvPV_nolen(ST(2)); + Mob *THIS; + Const_char *id = SvPV_nolen(ST(1)); + const char *var = (const char *) SvPV_nolen(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetEntityVariable(id, var); @@ -6688,8 +6283,7 @@ XS(XS_Mob_SetEntityVariable) } XS(XS_Mob_GetHateList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetHateList) -{ +XS(XS_Mob_GetHateList) { dXSARGS; int num_entries = 0; if (items != 1) @@ -6698,23 +6292,21 @@ XS(XS_Mob_GetHateList) Mob *THIS; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); auto hate_list = THIS->GetHateList(); - auto iter = hate_list.begin(); + auto iter = hate_list.begin(); - while(iter != hate_list.end()) - { + while (iter != hate_list.end()) { struct_HateList *entry = (*iter); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "HateEntry", (void*)entry); + sv_setref_pv(ST(0), "HateEntry", (void *) entry); XPUSHs(ST(0)); num_entries++; iter++; @@ -6723,67 +6315,30 @@ XS(XS_Mob_GetHateList) XSRETURN(num_entries); } -/* - dXSARGS; - int num_mobs = 0; - if (items != 1) - Perl_croak(aTHX_ "Usage: EntityList::GetCorpseList(THIS)"); - { - EntityList *THIS; - - if (sv_derived_from(ST(0), "EntityList")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EntityList *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type EntityList"); - - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - std::list corpse_list = entity_list.GetCorpseList(); - std::list::iterator iter = corpse_list.begin(); - - while(iter != corpse_list.end()) - { - Corpse *entry = (*iter); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Corpse", (void*)entry); - XPUSHs(ST(0)); - num_mobs++; - iter++; - } - } - XSRETURN(num_mobs); -*/ - XS(XS_Mob_SignalClient); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SignalClient) -{ +XS(XS_Mob_SignalClient) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::SignalClient(THIS, client, data)"); + Perl_croak(aTHX_ "Usage: Mob::SignalClient(THIS, Client* client, uint32 data)"); { - Mob * THIS; - Client* client = nullptr; - uint32 data = (uint32)SvUV(ST(2)); + Mob *THIS; + Client *client = nullptr; + uint32 data = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); client->Signal(data); @@ -6792,81 +6347,74 @@ XS(XS_Mob_SignalClient) } XS(XS_Mob_CombatRange); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CombatRange) -{ +XS(XS_Mob_CombatRange) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::CombatRange(THIS, target)"); + Perl_croak(aTHX_ "Usage: Mob::CombatRange(THIS, Mob* target)"); { - Mob * THIS; - Mob * target = nullptr; - bool RETVAL; + Mob *THIS; + Mob *target = nullptr; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) + if (target == nullptr) Perl_croak(aTHX_ "target is nullptr, avoiding crash."); RETVAL = THIS->CombatRange(target); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_DoSpecialAttackDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DoSpecialAttackDamage) -{ +XS(XS_Mob_DoSpecialAttackDamage) { dXSARGS; if (items < 4 || items > 6) - Perl_croak(aTHX_ "Usage: Mob::DoSpecialAttackDamage(THIS, target, skill, max_damage, min_damage = 1, hate_override = -1)"); + Perl_croak(aTHX_ + "Usage: Mob::DoSpecialAttackDamage(THIS, Mob* target, int skill, int32 max_damage, [int32 min_damage = 1], [int32 hate_override = -11])"); { - Mob * THIS; - Mob* target; - EQEmu::skills::SkillType attack_skill = (EQEmu::skills::SkillType)SvUV(ST(2)); - int32 max_damage = (int32)SvIV(ST(3)); - int32 min_damage = 1; - int32 hate_override = -11; + Mob *THIS; + Mob *target; + EQEmu::skills::SkillType attack_skill = (EQEmu::skills::SkillType) SvUV(ST(2)); + int32 max_damage = (int32) SvIV(ST(3)); + int32 min_damage = 1; + int32 hate_override = -11; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) + if (target == nullptr) Perl_croak(aTHX_ "target is nullptr, avoiding crash."); - if (items > 4) - { - min_damage = (int32)SvIV(ST(4)); + if (items > 4) { + min_damage = (int32) SvIV(ST(4)); } - if (items == 6) - { - hate_override = (int32)SvIV(ST(5)); + if (items == 6) { + hate_override = (int32) SvIV(ST(5)); } THIS->DoSpecialAttackDamage(target, attack_skill, max_damage, min_damage, hate_override); @@ -6875,32 +6423,29 @@ XS(XS_Mob_DoSpecialAttackDamage) } XS(XS_Mob_CheckLoS); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CheckLoS) -{ +XS(XS_Mob_CheckLoS) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::CheckLoS(THIS, mob)"); + Perl_croak(aTHX_ "Usage: Mob::CheckLoS(THIS, Mob*)"); { - Mob * THIS; - Mob* mob; - bool RETVAL; + Mob *THIS; + Mob *mob; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); RETVAL = THIS->CheckLosFN(mob); @@ -6911,33 +6456,30 @@ XS(XS_Mob_CheckLoS) } XS(XS_Mob_CheckLoSToLoc); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CheckLoSToLoc) -{ +XS(XS_Mob_CheckLoSToLoc) { dXSARGS; if (items != 4 && items != 5) - Perl_croak(aTHX_ "Usage: Mob::CheckLoSToLoc(THIS, loc_x, loc_y, loc_z, mob_size)"); + Perl_croak(aTHX_ "Usage: Mob::CheckLoSToLoc(THIS, float x, float y, float z, float mob_size)"); { - Mob * THIS; - float loc_x = (float)SvNV(ST(1)); - float loc_y = (float)SvNV(ST(2)); - float loc_z = (float)SvNV(ST(3)); - float mob_size; - bool RETVAL; + Mob *THIS; + float loc_x = (float) SvNV(ST(1)); + float loc_y = (float) SvNV(ST(2)); + float loc_z = (float) SvNV(ST(3)); + float mob_size; + bool RETVAL; if (items == 5) { - mob_size = (float)SvNV(ST(4)); - } - else { + mob_size = (float) SvNV(ST(4)); + } else { mob_size = 6; } if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CheckLosFN(loc_x, loc_y, loc_z, mob_size); @@ -6948,94 +6490,90 @@ XS(XS_Mob_CheckLoSToLoc) } XS(XS_Mob_FindGroundZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_FindGroundZ) -{ +XS(XS_Mob_FindGroundZ) { dXSARGS; if (items != 3 && items != 4) - Perl_croak(aTHX_ "Usage: Mob::FindGroundZ(THIS, new_x, new_y, z_offset)"); + Perl_croak(aTHX_ "Usage: Mob::FindGroundZ(THIS, float x, float y, float z_offset)"); { - Mob * THIS; - float new_x = (float)SvNV(ST(1)); - float new_y = (float)SvNV(ST(2)); - float z_offset; - float RETVAL; + Mob *THIS; + float new_x = (float) SvNV(ST(1)); + float new_y = (float) SvNV(ST(2)); + float z_offset; + float RETVAL; dXSTARG; if (items == 4) { - z_offset = (float)SvNV(ST(3)); - } - else { + z_offset = (float) SvNV(ST(3)); + } else { z_offset = 10; } if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGroundZ(new_x, new_y, z_offset); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Mob_ProjectileAnim); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ProjectileAnim) -{ +XS(XS_Mob_ProjectileAnim) { dXSARGS; if (items < 3 || items > 9) - Perl_croak(aTHX_ "Usage: Mob::ProjectileAnim(THIS, mob, item_id, IsArrow?, speed, angle, tilt, arc)"); + Perl_croak(aTHX_ + "Usage: Mob::ProjectileAnim(THIS, Mob* mob, int item_id, [bool is_arrow = false], [float speed = 0], [float angle = 0], [float tilt = 0], [float arc = 0])"); { - Mob * THIS; - Mob* mob; - int item_id = SvUV(ST(2)); - bool IsArrow = false; - float speed = 0; - float angle = 0; - float tilt = 0; - float arc = 0; - char * IDFile = nullptr; + Mob *THIS; + Mob *mob; + int item_id = SvUV(ST(2)); + bool IsArrow = false; + float speed = 0; + float angle = 0; + float tilt = 0; + float arc = 0; + char *IDFile = nullptr; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - mob = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + mob = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "mob is not of type Mob"); - if(mob == nullptr) + if (mob == nullptr) Perl_croak(aTHX_ "mob is nullptr, avoiding crash."); - if(items > 3){ - IsArrow = (bool)SvTRUE(ST(3)); + if (items > 3) { + IsArrow = (bool) SvTRUE(ST(3)); } - if(items > 4){ - speed = (float)SvNV(ST(4)); + if (items > 4) { + speed = (float) SvNV(ST(4)); } - if(items > 5){ - angle = (float)SvNV(ST(5)); + if (items > 5) { + angle = (float) SvNV(ST(5)); } - if(items > 6){ - tilt = (float)SvNV(ST(6)); + if (items > 6) { + tilt = (float) SvNV(ST(6)); } - if(items > 7){ - arc = (float)SvNV(ST(7)); + if (items > 7) { + arc = (float) SvNV(ST(7)); } - if (items > 8) { IDFile = (char *)SvPV_nolen(ST(8)); } + if (items > 8) { IDFile = (char *) SvPV_nolen(ST(8)); } THIS->ProjectileAnimation(mob, item_id, IsArrow, speed, angle, tilt, arc, IDFile); @@ -7044,68 +6582,64 @@ XS(XS_Mob_ProjectileAnim) } XS(XS_Mob_HasNPCSpecialAtk); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_HasNPCSpecialAtk) -{ +XS(XS_Mob_HasNPCSpecialAtk) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::HasNPCSpecialAtk(THIS, parse)"); + Perl_croak(aTHX_ "Usage: Mob::HasNPCSpecialAtk(THIS, string ability_string)"); { - Mob * THIS; - char* parse = (char *)SvPV_nolen(ST(1)); - bool RETVAL; + Mob *THIS; + char *parse = (char *) SvPV_nolen(ST(1)); + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->HasNPCSpecialAtk(parse); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Mob_SendAppearanceEffect); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendAppearanceEffect) -{ +XS(XS_Mob_SendAppearanceEffect) { dXSARGS; if (items < 2 || items > 7) - Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffect(THIS, parm1, parm2, parm3, parm4, parm5, singleclient)"); + Perl_croak(aTHX_ + "Usage: Mob::SendAppearanceEffect(THIS, int32 param_1, [int32 param_2 = 0], [int32 param_3 = 0], [int32 param_4 = 0], [int32 param_5 = 0], [Client* single_client_to_send_to = null])"); { - Mob * THIS; - int32 parm1 = (int32)SvIV(ST(1)); - int32 parm2 = 0; - int32 parm3 = 0; - int32 parm4 = 0; - int32 parm5 = 0; - Client* client = nullptr; + Mob *THIS; + int32 parm1 = (int32) SvIV(ST(1)); + int32 parm2 = 0; + int32 parm3 = 0; + int32 parm4 = 0; + int32 parm5 = 0; + Client *client = nullptr; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 2) { parm2 = (int32)SvIV(ST(2)); } - if (items > 3) { parm3 = (int32)SvIV(ST(3)); } - if (items > 4) { parm4 = (int32)SvIV(ST(4)); } - if (items > 5) { parm5 = (int32)SvIV(ST(5)); } - if (items > 6) { + if (items > 2) { parm2 = (int32) SvIV(ST(2)); } + if (items > 3) { parm3 = (int32) SvIV(ST(3)); } + if (items > 4) { parm4 = (int32) SvIV(ST(4)); } + if (items > 5) { parm5 = (int32) SvIV(ST(5)); } + if (items > 6) { if (sv_derived_from(ST(6), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(6))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(6))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); } @@ -7115,22 +6649,20 @@ XS(XS_Mob_SendAppearanceEffect) } XS(XS_Mob_SetFlyMode); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetFlyMode) -{ +XS(XS_Mob_SetFlyMode) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetFlyMode(THIS, 0|1|2|3)"); + Perl_croak(aTHX_ "Usage: Mob::SetFlyMode(THIS, uint8 flymode[0|1|2|3])"); { - Mob * THIS; - uint8 flymode = (uint8)SvIV(ST(1)); + Mob *THIS; + uint8 flymode = (uint8) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetFlyMode(flymode); @@ -7139,22 +6671,20 @@ XS(XS_Mob_SetFlyMode) } XS(XS_Mob_SetTexture); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetTexture) -{ +XS(XS_Mob_SetTexture) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetTexture(THIS, texture)"); + Perl_croak(aTHX_ "Usage: Mob::SetTexture(THIS, int32 texture)"); { - Mob * THIS; - int32 texture = (int32)SvIV(ST(1)); + Mob *THIS; + int32 texture = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendIllusionPacket(THIS->GetRace(), 0xFF, texture); @@ -7163,22 +6693,20 @@ XS(XS_Mob_SetTexture) } XS(XS_Mob_SetRace); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetRace) -{ +XS(XS_Mob_SetRace) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetRace(THIS, race)"); + Perl_croak(aTHX_ "Usage: Mob::SetRace(THIS, int32 race)"); { - Mob * THIS; - int32 race = (int32)SvIV(ST(1)); + Mob *THIS; + int32 race = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendIllusionPacket(race); @@ -7187,163 +6715,156 @@ XS(XS_Mob_SetRace) } XS(XS_Mob_SetGender); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetGender) -{ +XS(XS_Mob_SetGender) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetGender(THIS, gender)"); + Perl_croak(aTHX_ "Usage: Mob::SetGender(THIS, int32 gender)"); { - Mob * THIS; - int32 gender = (int32)SvIV(ST(1)); + Mob *THIS; + int32 gender = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SendIllusionPacket(THIS->GetRace(),gender); + THIS->SendIllusionPacket(THIS->GetRace(), gender); } XSRETURN_EMPTY; } XS(XS_Mob_SendIllusion); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendIllusion) -{ +XS(XS_Mob_SendIllusion) { dXSARGS; if (items < 2 || items > 14) - Perl_croak(aTHX_ "Usage: Mob::SendIllusion(THIS,race,gender,texture,helmtexture,face,hairstyle,haircolor,beard,beardcolor,drakkin_heritage,drakkin_tattoo,drakkin_details,size)"); + Perl_croak(aTHX_ + "Usage: Mob::SendIllusion(THIS, uint16 race, [uint8 gender = 0xFF], [uint8 texture = 0xFF], [unit8 helmtexture = 0xFF], [unit8 face = 0xFF], [unit8 hairstyle = 0xFF], [uint8 hair_color = 0xFF], [uint8 beard = 0xFF], [uint8 beard_color = 0xFF], [uint32 drakkin_heritage = 0xFFFFFFFF], [uint32 drakkin_tattoo = 0xFFFFFFFF], [uint32 drakkin_details = 0xFFFFFFFF], [float size = -1])"); { - Mob * THIS; - uint16 race = (uint16)SvIV(ST(1)); - uint8 gender = 0xFF; - uint8 texture = 0xFF; - uint8 helmtexture = 0xFF; - uint8 face = 0xFF; - uint8 hairstyle = 0xFF; - uint8 haircolor = 0xFF; - uint8 beard = 0xFF; - uint8 beardcolor = 0xFF; - uint32 drakkin_heritage = 0xFFFFFFFF; - uint32 drakkin_tattoo = 0xFFFFFFFF; - uint32 drakkin_details = 0xFFFFFFFF; - float size = -1.0f; + Mob *THIS; + uint16 race = (uint16) SvIV(ST(1)); + uint8 gender = 0xFF; + uint8 texture = 0xFF; + uint8 helmtexture = 0xFF; + uint8 face = 0xFF; + uint8 hairstyle = 0xFF; + uint8 haircolor = 0xFF; + uint8 beard = 0xFF; + uint8 beardcolor = 0xFF; + uint32 drakkin_heritage = 0xFFFFFFFF; + uint32 drakkin_tattoo = 0xFFFFFFFF; + uint32 drakkin_details = 0xFFFFFFFF; + float size = -1.0f; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items > 2) {gender = (uint8)SvIV(ST(2));} - if(items > 3) {texture = (uint8)SvIV(ST(3));} - if(items > 4) {helmtexture = (uint8)SvIV(ST(4));} - if(items > 5) {face = (uint8)SvIV(ST(5));} - if(items > 6) {hairstyle = (uint8)SvIV(ST(6));} - if(items > 7) {haircolor = (uint8)SvIV(ST(7));} - if(items > 8) {beard = (uint8)SvIV(ST(8));} - if(items > 9) {beardcolor = (uint8)SvIV(ST(9));} - if(items > 10) {drakkin_heritage = (uint32)SvIV(ST(10));} - if(items > 11) {drakkin_tattoo = (uint32)SvIV(ST(11));} - if(items > 12) {drakkin_details = (uint32)SvIV(ST(12));} - if(items > 13) {size = (float)SvNV(ST(13));} + if (items > 2) { gender = (uint8) SvIV(ST(2)); } + if (items > 3) { texture = (uint8) SvIV(ST(3)); } + if (items > 4) { helmtexture = (uint8) SvIV(ST(4)); } + if (items > 5) { face = (uint8) SvIV(ST(5)); } + if (items > 6) { hairstyle = (uint8) SvIV(ST(6)); } + if (items > 7) { haircolor = (uint8) SvIV(ST(7)); } + if (items > 8) { beard = (uint8) SvIV(ST(8)); } + if (items > 9) { beardcolor = (uint8) SvIV(ST(9)); } + if (items > 10) { drakkin_heritage = (uint32) SvIV(ST(10)); } + if (items > 11) { drakkin_tattoo = (uint32) SvIV(ST(11)); } + if (items > 12) { drakkin_details = (uint32) SvIV(ST(12)); } + if (items > 13) { size = (float) SvNV(ST(13)); } - THIS->SendIllusionPacket(race,gender,texture,helmtexture,haircolor,beardcolor,0xFF,0xFF, - hairstyle,face,beard,0xFF,drakkin_heritage,drakkin_tattoo,drakkin_details,size); + THIS->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, + hairstyle, face, beard, 0xFF, drakkin_heritage, drakkin_tattoo, drakkin_details, size); } XSRETURN_EMPTY; } XS(XS_Mob_CameraEffect); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CameraEffect) -{ +XS(XS_Mob_CameraEffect) { dXSARGS; if (items < 2 || items > 5) - Perl_croak(aTHX_ "Usage: Mob::CameraEffect(THIS, duration, intensity, singleclient, global)"); + Perl_croak(aTHX_ + "Usage: Mob::CameraEffect(THIS, uint32 duration, [uint32 intensity = 0], [Client* single_client = nullptr], [bool is_world_wide = false])"); { - Mob * THIS; - uint32 duration = (uint32)SvUV(ST(1)); - uint32 intensity = 0; - Client* client = nullptr; - bool global = false; - bool nullcli = false; + Mob *THIS; + uint32 duration = (uint32) SvUV(ST(1)); + uint32 intensity = 0; + Client *client = nullptr; + bool global = false; + bool nullcli = false; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 2) { intensity = (uint32)SvUV(ST(2)); } - if (items > 3) { + if (items > 2) { intensity = (uint32) SvUV(ST(2)); } + if (items > 3) { if (sv_derived_from(ST(3), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(3))); - client = INT2PTR(Client *,tmp); - } - else - nullcli = true; - if(client == nullptr) - nullcli = true; - //Perl_croak(aTHX_ "client is nullptr, avoiding crash."); + IV tmp = SvIV((SV *) SvRV(ST(3))); + client = INT2PTR(Client *, tmp); + } else + nullcli = true; + if (client == nullptr) + nullcli = true; + //Perl_croak(aTHX_ "client is nullptr, avoiding crash."); } - if (items > 4) { global = (bool)SvTRUE(ST(4)); } + if (items > 4) { global = (bool) SvTRUE(ST(4)); } - if(nullcli) - THIS->CameraEffect(duration, intensity, 0, global); + if (nullcli) + THIS->CameraEffect(duration, intensity, 0, global); else - THIS->CameraEffect(duration, intensity, client, global); + THIS->CameraEffect(duration, intensity, client, global); } XSRETURN_EMPTY; } XS(XS_Mob_SpellEffect); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SpellEffect) -{ +XS(XS_Mob_SpellEffect) { dXSARGS; if (items < 2 || items > 8) - Perl_croak(aTHX_ "Usage: Mob::SpellEffect(THIS, effect, [duration, finish_delay, zone_wide, unk20, perm_effect, client])"); + Perl_croak(aTHX_ + "Usage: Mob::SpellEffect(THIS, uint32 effect, [uint32 duration = 5000], [uint32 finish_delay = 0], [bool zone_wide = false], [uint32 unk20 = 3000], [bool perm_effect = false], [Client* single_client])"); { - Mob * THIS; - uint32 effect = (uint32)SvUV(ST(1)); - uint32 duration = 5000; - uint32 finish_delay = 0; - bool zone_wide = true; - uint32 unk20 = 3000; - bool perm_effect = false; - Client* client = nullptr; + Mob *THIS; + uint32 effect = (uint32) SvUV(ST(1)); + uint32 duration = 5000; + uint32 finish_delay = 0; + bool zone_wide = true; + uint32 unk20 = 3000; + bool perm_effect = false; + Client *client = nullptr; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 2) { duration = (uint32)SvUV(ST(2)); } - if (items > 3) { finish_delay = (uint32)SvUV(ST(3)); } - if (items > 4) { zone_wide = (bool)SvTRUE(ST(4)); } - if (items > 5) { unk20 = (uint32)SvUV(ST(5)); } - if (items > 6) { perm_effect = (bool)SvTRUE(ST(6)); } - if (items > 7) { + if (items > 2) { duration = (uint32) SvUV(ST(2)); } + if (items > 3) { finish_delay = (uint32) SvUV(ST(3)); } + if (items > 4) { zone_wide = (bool) SvTRUE(ST(4)); } + if (items > 5) { unk20 = (uint32) SvUV(ST(5)); } + if (items > 6) { perm_effect = (bool) SvTRUE(ST(6)); } + if (items > 7) { if (sv_derived_from(ST(7), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(7))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(7))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); } @@ -7355,25 +6876,23 @@ XS(XS_Mob_SpellEffect) XS(XS_Mob_TempName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_TempName) -{ +XS(XS_Mob_TempName) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Mob::TempName(THIS, name)"); + Perl_croak(aTHX_ "Usage: Mob::TempName(THIS, string name)"); { - Mob * THIS; - char * name = nullptr; + Mob *THIS; + char *name = nullptr; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { name = (char *)SvPV_nolen(ST(1)); } + if (items > 1) { name = (char *) SvPV_nolen(ST(1)); } THIS->TempName(name); } @@ -7381,51 +6900,48 @@ XS(XS_Mob_TempName) } XS(XS_Mob_GetItemStat); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetItemStat) -{ +XS(XS_Mob_GetItemStat) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetItemStat(THIS, itemid, stat)"); + Perl_croak(aTHX_ "Usage: Mob::GetItemStat(THIS, uint32 item_id, string stat)"); { - Mob * THIS; - int32 RETVAL; - uint32 itemid = (uint32)SvUV(ST(1)); - Const_char * stat = (Const_char *)SvPV_nolen(ST(2)); + Mob *THIS; + int32 RETVAL; + uint32 itemid = (uint32) SvUV(ST(1)); + Const_char *stat = (Const_char *) SvPV_nolen(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetItemStat(itemid, stat); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetGlobal); -XS(XS_Mob_GetGlobal) -{ +XS(XS_Mob_GetGlobal) { dXSARGS; if (items < 2) - Perl_croak(aTHX_ "Usage: GetGlobal(THIS, varname)"); + Perl_croak(aTHX_ "Usage: GetGlobal(THIS, string var_name)"); { - Mob* THIS; - Const_char* varname = (Const_char*)SvPV_nolen(ST(1)); + Mob *THIS; + Const_char *varname = (Const_char *) SvPV_nolen(ST(1)); std::string ret_val = "Undefined"; - Const_char* RETVAL; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); @@ -7434,42 +6950,42 @@ XS(XS_Mob_GetGlobal) ret_val = THIS->GetGlobal(varname); RETVAL = ret_val.c_str(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Mob_SetGlobal); -XS(XS_Mob_SetGlobal) -{ +XS(XS_Mob_SetGlobal) { dXSARGS; if (items < 5 || items > 6) - Perl_croak(aTHX_ "Usage: SetGlobal(THIS, varname, newvalue, options, duration, other=nullptr)"); + Perl_croak(aTHX_ + "Usage: SetGlobal(THIS, string var_name, string new_value, int options, string duration, [Mob* other = nullptr])"); { - Mob * THIS; - char * varname = (char *)SvPV_nolen(ST(1)); - char * newvalue = (char *)SvPV_nolen(ST(2)); - int options = (int)SvIV(ST(3)); - char * duration = (char *)SvPV_nolen(ST(4)); - Mob * other = nullptr; + Mob *THIS; + char *varname = (char *) SvPV_nolen(ST(1)); + char *newvalue = (char *) SvPV_nolen(ST(2)); + int options = (int) SvIV(ST(3)); + char *duration = (char *) SvPV_nolen(ST(4)); + Mob *other = nullptr; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 5) { if (sv_derived_from(ST(5), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(5))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(5))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); } @@ -7479,27 +6995,26 @@ XS(XS_Mob_SetGlobal) } XS(XS_Mob_TarGlobal); -XS(XS_Mob_TarGlobal) -{ +XS(XS_Mob_TarGlobal) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: TarGlobal(THIS, varname, value, duration, npcid, charid, zoneid)"); + Perl_croak(aTHX_ + "Usage: TarGlobal(THIS, string var_name, string value, string duration, int npc_id, int character_id, int zone_id)"); { - Mob * THIS; - char * varname = (char *)SvPV_nolen(ST(1)); - char * value = (char *)SvPV_nolen(ST(2)); - char * duration = (char *)SvPV_nolen(ST(3)); - int npcid = (int)SvIV(ST(4)); - int charid = (int)SvIV(ST(5)); - int zoneid = (int)SvIV(ST(6)); + Mob *THIS; + char *varname = (char *) SvPV_nolen(ST(1)); + char *value = (char *) SvPV_nolen(ST(2)); + char *duration = (char *) SvPV_nolen(ST(3)); + int npcid = (int) SvIV(ST(4)); + int charid = (int) SvIV(ST(5)); + int zoneid = (int) SvIV(ST(6)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->TarGlobal(varname, value, duration, npcid, charid, zoneid); @@ -7508,22 +7023,20 @@ XS(XS_Mob_TarGlobal) } XS(XS_Mob_DelGlobal); -XS(XS_Mob_DelGlobal) -{ +XS(XS_Mob_DelGlobal) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: DelGlobal(THIS, varname)"); + Perl_croak(aTHX_ "Usage: DelGlobal(THIS, string var_name)"); { - Mob * THIS; - char * varname = (char *)SvPV_nolen(ST(1)); + Mob *THIS; + char *varname = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->DelGlobal(varname); @@ -7532,25 +7045,24 @@ XS(XS_Mob_DelGlobal) } XS(XS_Mob_SetSlotTint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetSlotTint) -{ +XS(XS_Mob_SetSlotTint) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: Mob::SetSlotTint(THIS, material_slot, red_tint, green_tint, blue_tint)"); + Perl_croak(aTHX_ + "Usage: Mob::SetSlotTint(THIS, uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint)"); { - Mob * THIS; - uint8 material_slot = (uint8)SvIV(ST(1)); - uint8 red_tint = (uint8)SvIV(ST(2)); - uint8 green_tint = (uint8)SvIV(ST(3)); - uint8 blue_tint = (uint8)SvIV(ST(4)); + Mob *THIS; + uint8 material_slot = (uint8) SvIV(ST(1)); + uint8 red_tint = (uint8) SvIV(ST(2)); + uint8 green_tint = (uint8) SvIV(ST(3)); + uint8 blue_tint = (uint8) SvIV(ST(4)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSlotTint(material_slot, red_tint, green_tint, blue_tint); @@ -7559,32 +7071,31 @@ XS(XS_Mob_SetSlotTint) } XS(XS_Mob_WearChange); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_WearChange) -{ +XS(XS_Mob_WearChange) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::WearChange(THIS, material_slot, texture, [color, hero_forge_model])"); + Perl_croak(aTHX_ + "Usage: Mob::WearChange(THIS, uint8 material_slot, uint16 texture, [uint32 color = 0, uint32 hero_forge_model = 0])"); { - Mob * THIS; - uint8 material_slot = (uint8)SvIV(ST(1)); - uint16 texture = (uint16)SvUV(ST(2)); - uint32 color = 0; - uint32 hero_forge_model = 0; + Mob *THIS; + uint8 material_slot = (uint8) SvIV(ST(1)); + uint16 texture = (uint16) SvUV(ST(2)); + uint32 color = 0; + uint32 hero_forge_model = 0; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 3) { - color = (uint32)SvUV(ST(3)); + color = (uint32) SvUV(ST(3)); } if (items > 4) { - hero_forge_model = (uint32)SvUV(ST(3)); + hero_forge_model = (uint32) SvUV(ST(3)); } THIS->WearChange(material_slot, texture, color, hero_forge_model); @@ -7593,33 +7104,30 @@ XS(XS_Mob_WearChange) } XS(XS_Mob_DoKnockback); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DoKnockback) -{ +XS(XS_Mob_DoKnockback) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Mob::DoKnockback(THIS, caster, pushback, pushup)"); + Perl_croak(aTHX_ "Usage: Mob::DoKnockback(THIS, Mob* caster, uint32 push_back_amount, uint32 push_up_amount)"); { - Mob * THIS; - Mob * caster; - uint32 pushback = (uint16)SvUV(ST(2)); - uint32 pushup = (uint16)SvUV(ST(2)); + Mob *THIS; + Mob *caster; + uint32 pushback = (uint16) SvUV(ST(2)); + uint32 pushup = (uint16) SvUV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); THIS->DoKnockback(caster, pushback, pushup); @@ -7628,22 +7136,20 @@ XS(XS_Mob_DoKnockback) } XS(XS_Mob_RemoveNimbusEffect); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_RemoveNimbusEffect) -{ +XS(XS_Mob_RemoveNimbusEffect) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::RemoveNimbusEffect(THIS, effectid)"); + Perl_croak(aTHX_ "Usage: Mob::RemoveNimbusEffect(THIS, int32 effect_id)"); { - Mob * THIS; - int32 effectid = (int32)SvIV(ST(1)); + Mob *THIS; + int32 effectid = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveNimbusEffect(effectid); @@ -7652,22 +7158,20 @@ XS(XS_Mob_RemoveNimbusEffect) } XS(XS_Mob_SetRunning); -XS(XS_Mob_SetRunning) -{ +XS(XS_Mob_SetRunning) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetRunning(THIS, value)"); + Perl_croak(aTHX_ "Usage: Mob::SetRunning(THIS, bool value)"); { - Mob * THIS; - bool value = (bool)SvTRUE(ST(1)); + Mob *THIS; + bool value = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetRunning(value); @@ -7676,23 +7180,21 @@ XS(XS_Mob_SetRunning) } XS(XS_Mob_IsRunning); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsRunning) -{ +XS(XS_Mob_IsRunning) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: Mob:::IsRunning(THIS)"); + Perl_croak(aTHX_ "Usage: Mob::IsRunning(THIS)"); { - Mob * THIS; + Mob *THIS; bool RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsRunning(); @@ -7703,51 +7205,47 @@ XS(XS_Mob_IsRunning) } XS(XS_Mob_SetBodyType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetBodyType) -{ +XS(XS_Mob_SetBodyType) { dXSARGS; if (items < 2 || items > 3) - Perl_croak(aTHX_ "Usage: Mob::SetBodyType(THIS, type, overwrite_orig = false)"); + Perl_croak(aTHX_ "Usage: Mob::SetBodyType(THIS, int32 type, [bool overwrite_orig = false])"); { - Mob * THIS; - int32 type = (int32)SvIV(ST(1)); - bool overwrite_orig = false; + Mob *THIS; + int32 type = (int32) SvIV(ST(1)); + bool overwrite_orig = false; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if(items == 3) { - overwrite_orig = (bool)SvTRUE(ST(2)); + if (items == 3) { + overwrite_orig = (bool) SvTRUE(ST(2)); } - THIS->SetBodyType((bodyType)type, overwrite_orig); + THIS->SetBodyType((bodyType) type, overwrite_orig); } XSRETURN_EMPTY; } XS(XS_Mob_SetDeltas); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetDeltas) -{ +XS(XS_Mob_SetDeltas) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: Mob::SetDeltas(THIS, delta_x, delta_y, delta_z, delta_h)"); + Perl_croak(aTHX_ "Usage: Mob::SetDeltas(THIS, float delta_x, float delta_y, float delta_z, float delta_h)"); { - Mob * THIS; - auto delta = glm::vec4((float)SvNV(ST(1)), (float)SvNV(ST(2)), (float)SvNV(ST(3)), (float)SvNV(ST(4))); + Mob *THIS; + auto delta = glm::vec4((float) SvNV(ST(1)), (float) SvNV(ST(2)), (float) SvNV(ST(3)), (float) SvNV(ST(4))); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetDelta(delta); @@ -7756,22 +7254,20 @@ XS(XS_Mob_SetDeltas) } XS(XS_Mob_SetLD); -XS(XS_Mob_SetLD) -{ +XS(XS_Mob_SetLD) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetLD(THIS, value)"); + Perl_croak(aTHX_ "Usage: Mob::SetLD(THIS, bool value)"); { - Mob * THIS; - bool value = (bool)SvTRUE(ST(1)); + Mob *THIS; + bool value = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SendAppearancePacket(AT_Linkdead, value); @@ -7780,22 +7276,20 @@ XS(XS_Mob_SetLD) } XS(XS_Mob_SetTargetDestSteps); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetTargetDestSteps) -{ +XS(XS_Mob_SetTargetDestSteps) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetTargetDestSteps(THIS, target_steps)"); + Perl_croak(aTHX_ "Usage: Mob::SetTargetDestSteps(THIS, uint8 target_steps)"); { - Mob * THIS; - uint8 target_steps = (uint8)SvIV(ST(1)); + Mob *THIS; + uint8 target_steps = (uint8) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetTargetDestSteps(target_steps); @@ -7804,22 +7298,20 @@ XS(XS_Mob_SetTargetDestSteps) } XS(XS_Mob_SetTargetable); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetTargetable) -{ +XS(XS_Mob_SetTargetable) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetTargetable(THIS, on)"); + Perl_croak(aTHX_ "Usage: Mob::SetTargetable(THIS, bool targetable)"); { - Mob * THIS; - bool on = (bool)SvTRUE(ST(1)); + Mob *THIS; + bool on = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetTargetable(on); @@ -7828,101 +7320,95 @@ XS(XS_Mob_SetTargetable) } XS(XS_Mob_ModSkillDmgTaken); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ModSkillDmgTaken) -{ +XS(XS_Mob_ModSkillDmgTaken) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::ModSkillDmgTaken(THIS, skill, value)"); + Perl_croak(aTHX_ "Usage: Mob::ModSkillDmgTaken(THIS, int skill, int16 value)"); { - Mob * THIS; - EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType)SvUV(ST(1)); - int16 value = (int16)SvIV(ST(2)); + Mob *THIS; + EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType) SvUV(ST(1)); + int16 value = (int16) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->ModSkillDmgTaken(skill_num,value); + THIS->ModSkillDmgTaken(skill_num, value); } XSRETURN_EMPTY; } XS(XS_Mob_GetModSkillDmgTaken); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetModSkillDmgTaken) -{ +XS(XS_Mob_GetModSkillDmgTaken) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetModSkillDmgTaken(THIS, skill_num)"); + Perl_croak(aTHX_ "Usage: Mob::GetModSkillDmgTaken(THIS, int skill_id)"); { - Mob * THIS; - int16 RETVAL; + Mob *THIS; + int16 RETVAL; dXSTARG; - EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType)SvUV(ST(1)); + EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetModSkillDmgTaken(skill_num); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSkillDmgTaken); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSkillDmgTaken) -{ +XS(XS_Mob_GetSkillDmgTaken) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetSkillDmgTaken(THIS, skill_num)"); + Perl_croak(aTHX_ "Usage: Mob::GetSkillDmgTaken(THIS, int skill_id)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType)SvUV(ST(1)); + EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSkillDmgTaken(skill_num); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetAllowBeneficial); -XS(XS_Mob_SetAllowBeneficial) -{ +XS(XS_Mob_SetAllowBeneficial) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetAllowBeneficial(THIS, value)"); + Perl_croak(aTHX_ "Usage: Mob::SetAllowBeneficial(THIS, bool value)"); { - Mob * THIS; - bool value = (bool)SvTRUE(ST(1)); + Mob *THIS; + bool value = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetAllowBeneficial(value); @@ -7931,22 +7417,20 @@ XS(XS_Mob_SetAllowBeneficial) } XS(XS_Mob_GetAllowBeneficial); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetAllowBeneficial) -{ +XS(XS_Mob_GetAllowBeneficial) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetAllowBeneficial(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAllowBeneficial(); @@ -7957,34 +7441,31 @@ XS(XS_Mob_GetAllowBeneficial) } XS(XS_Mob_IsBeneficialAllowed); -XS(XS_Mob_IsBeneficialAllowed) -{ +XS(XS_Mob_IsBeneficialAllowed) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::IsBeneficialAllowed(THIS, target)"); + Perl_croak(aTHX_ "Usage: Mob::IsBeneficialAllowed(THIS, Mob* target)"); { dXSTARG; - Mob * THIS; - Mob * target; + Mob *THIS; + Mob *target; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else - Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) - Perl_croak(aTHX_ "target is nullptr, avoiding crash."); + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else + Perl_croak(aTHX_ "target is not of type Mob"); + if (target == nullptr) + Perl_croak(aTHX_ "target is nullptr, avoiding crash."); RETVAL = THIS->IsBeneficialAllowed(target); ST(0) = boolSV(RETVAL); @@ -7994,23 +7475,21 @@ XS(XS_Mob_IsBeneficialAllowed) } XS(XS_Mob_ModVulnerability); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ModVulnerability) -{ +XS(XS_Mob_ModVulnerability) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Mob::ModVulnerability(THIS, resist, value)"); + Perl_croak(aTHX_ "Usage: Mob::ModVulnerability(THIS, uint8 resist, int16 value)"); { - Mob * THIS; - uint8 resist = (uint8)SvIV(ST(1)); - int16 value = (int16)SvIV(ST(2)); + Mob *THIS; + uint8 resist = (uint8) SvIV(ST(1)); + int16 value = (int16) SvIV(ST(2)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ModVulnerability(resist, value); @@ -8019,63 +7498,60 @@ XS(XS_Mob_ModVulnerability) } XS(XS_Mob_GetModVulnerability); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetModVulnerability) -{ +XS(XS_Mob_GetModVulnerability) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetModVulnerability(THIS, resist)"); + Perl_croak(aTHX_ "Usage: Mob::GetModVulnerability(THIS, uint8 resist)"); { - Mob * THIS; - int32 RETVAL; + Mob *THIS; + int32 RETVAL; dXSTARG; - uint8 resist = (uint8)SvUV(ST(1)); + uint8 resist = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetModVulnerability(resist); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_DoMeleeSkillAttackDmg); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DoMeleeSkillAttackDmg) -{ +XS(XS_Mob_DoMeleeSkillAttackDmg) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Mob::DoMeleeSkillAttackDmg(THIS, target, weapon_damage, skill, chance_mod, focus, CanRiposte)"); + Perl_croak(aTHX_ + "Usage: Mob::DoMeleeSkillAttackDmg(THIS, Mob* target, uint16 weapon_damage, int skill, int16 chance_mod, int16 focus, uint8 can_riposte)"); { - Mob * THIS; - Mob* target; - uint16 weapon_damage = (uint16)SvIV(ST(2)); - EQEmu::skills::SkillType skill = (EQEmu::skills::SkillType)SvUV(ST(3)); - int16 chance_mod = (int16)SvIV(ST(4)); - int16 focus = (int16)SvIV(ST(5)); - uint8 CanRiposte = (uint8)SvIV(ST(6)); + Mob *THIS; + Mob *target; + uint16 weapon_damage = (uint16) SvIV(ST(2)); + EQEmu::skills::SkillType skill = (EQEmu::skills::SkillType) SvUV(ST(3)); + int16 chance_mod = (int16) SvIV(ST(4)); + int16 focus = (int16) SvIV(ST(5)); + uint8 CanRiposte = (uint8) SvIV(ST(6)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) + if (target == nullptr) Perl_croak(aTHX_ "target is nullptr, avoiding crash."); THIS->DoMeleeSkillAttackDmg(target, weapon_damage, skill, chance_mod, focus, CanRiposte); @@ -8084,36 +7560,34 @@ XS(XS_Mob_DoMeleeSkillAttackDmg) } XS(XS_Mob_DoArcheryAttackDmg); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DoArcheryAttackDmg) -{ +XS(XS_Mob_DoArcheryAttackDmg) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Mob::DoArcheryAttackDmg(THIS, target, RangeWeapon=nullptr, Ammo=nullptr, weapon_damage, chance_mod, focus)"); + Perl_croak(aTHX_ + "Usage: Mob::DoArcheryAttackDmg(THIS, Mob* target, [range_weapon_item_instance = nullptr], [ammo_item_instance = nullptr], uint16 weapon_damage, int16 chance_mod, int16 focus)"); { - Mob * THIS; - Mob* target; - EQEmu::ItemInstance* RangeWeapon = nullptr; - EQEmu::ItemInstance* Ammo = nullptr; - uint16 weapon_damage = (uint16)SvIV(ST(4)); - int16 chance_mod = (int16)SvIV(ST(5)); - int16 focus = (int16)SvIV(ST(6)); + Mob *THIS; + Mob *target; + EQEmu::ItemInstance *RangeWeapon = nullptr; + EQEmu::ItemInstance *Ammo = nullptr; + uint16 weapon_damage = (uint16) SvIV(ST(4)); + int16 chance_mod = (int16) SvIV(ST(5)); + int16 focus = (int16) SvIV(ST(6)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) + if (target == nullptr) Perl_croak(aTHX_ "target is nullptr, avoiding crash."); THIS->DoArcheryAttackDmg(target, RangeWeapon, Ammo, weapon_damage, chance_mod, focus); @@ -8122,36 +7596,34 @@ XS(XS_Mob_DoArcheryAttackDmg) } XS(XS_Mob_DoThrowingAttackDmg); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_DoThrowingAttackDmg) -{ +XS(XS_Mob_DoThrowingAttackDmg) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Mob::DoThrowingAttackDmg(THIS, target, RangeWeapon=nullptr,item=nullptr,weapon_damage, chance_mod, focus)"); + Perl_croak(aTHX_ + "Usage: Mob::DoThrowingAttackDmg(THIS, Mob* target, [range_weapon_item_instance = nullptr], [ammo_item_instance = nullptr], uint16 weapon_damage, int16 chance_mod, int16 focus)"); { - Mob * THIS; - Mob* target; - EQEmu::ItemInstance* RangeWeapon = nullptr; - EQEmu::ItemData* item = nullptr; - uint16 weapon_damage = (uint16)SvIV(ST(4)); - int16 chance_mod = (int16)SvIV(ST(5)); - int16 focus = (int16)SvIV(ST(6)); + Mob *THIS; + Mob *target; + EQEmu::ItemInstance *RangeWeapon = nullptr; + EQEmu::ItemData *item = nullptr; + uint16 weapon_damage = (uint16) SvIV(ST(4)); + int16 chance_mod = (int16) SvIV(ST(5)); + int16 focus = (int16) SvIV(ST(6)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) + if (target == nullptr) Perl_croak(aTHX_ "target is nullptr, avoiding crash."); THIS->DoThrowingAttackDmg(target, RangeWeapon, item, weapon_damage, chance_mod, focus); @@ -8160,22 +7632,20 @@ XS(XS_Mob_DoThrowingAttackDmg) } XS(XS_Mob_SetDisableMelee); -XS(XS_Mob_SetDisableMelee) -{ +XS(XS_Mob_SetDisableMelee) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetDisableMelee(THIS, value)"); + Perl_croak(aTHX_ "Usage: Mob::SetDisableMelee(THIS, bool value)"); { - Mob * THIS; - bool value = (bool)SvTRUE(ST(1)); + Mob *THIS; + bool value = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetDisableMelee(value); @@ -8184,22 +7654,20 @@ XS(XS_Mob_SetDisableMelee) } XS(XS_Mob_IsMeleeDisabled); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_IsMeleeDisabled) -{ +XS(XS_Mob_IsMeleeDisabled) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsMeleeDisabled(THIS)"); { - Mob * THIS; - bool RETVAL; + Mob *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsMeleeDisabled(); @@ -8210,22 +7678,20 @@ XS(XS_Mob_IsMeleeDisabled) } XS(XS_Mob_SetFlurryChance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetFlurryChance) -{ +XS(XS_Mob_SetFlurryChance) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::SetFlurryChance(THIS, value)"); + Perl_croak(aTHX_ "Usage: Mob::SetFlurryChance(THIS, uint8 value)"); { - Mob * THIS; - uint8 value = (uint8)SvIV(ST(1)); + Mob *THIS; + uint8 value = (uint8) SvIV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetFlurryChance(value); @@ -8234,136 +7700,130 @@ XS(XS_Mob_SetFlurryChance) } XS(XS_Mob_GetFlurryChance); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetFlurryChance) -{ +XS(XS_Mob_GetFlurryChance) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetFlurryChance(THIS)"); { - Mob * THIS; - uint8 RETVAL; + Mob *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetFlurryChance(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSpellStat); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSpellStat) -{ +XS(XS_Mob_GetSpellStat) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::GetSpellStat(THIS, itemid, stat, slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetSpellStat(THIS, uint32 spell_id, string stat, uint8 slot)"); { - Mob * THIS; - int32 RETVAL; - uint32 spellid = (uint32)SvUV(ST(1)); - Const_char * stat = (Const_char *)SvPV_nolen(ST(2)); - uint8 slot = (uint8)SvUV(ST(3)); + Mob *THIS; + int32 RETVAL; + uint32 spellid = (uint32) SvUV(ST(1)); + Const_char *stat = (Const_char *) SvPV_nolen(ST(2)); + uint8 slot = (uint8) SvUV(ST(3)); dXSTARG; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 4) { slot = 0; } + if (items > 4) { slot = 0; } RETVAL = THIS->GetSpellStat(spellid, stat, slot); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSpecialAbility); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSpecialAbility) -{ +XS(XS_Mob_GetSpecialAbility) { dXSARGS; - if(items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetSpecialAbility(THIS, special_ability)"); + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::GetSpecialAbility(THIS, int special_ability)"); { int RETVAL; - Mob* THIS; + Mob *THIS; int ability = SvIV(ST(1)); dXSTARG; - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpecialAbility(ability); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_GetSpecialAbilityParam); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GetSpecialAbilityParam) -{ +XS(XS_Mob_GetSpecialAbilityParam) { dXSARGS; - if(items != 3) - Perl_croak(aTHX_ "Usage: Mob::GetSpecialAbilityParam(THIS, special_ability, param)"); + if (items != 3) + Perl_croak(aTHX_ "Usage: Mob::GetSpecialAbilityParam(THIS, int special_ability, int param)"); { int RETVAL; - Mob* THIS; + Mob *THIS; int ability = SvIV(ST(1)); - int param = SvIV(ST(2)); + int param = SvIV(ST(2)); dXSTARG; - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpecialAbilityParam(ability, param); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_Mob_SetSpecialAbility); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetSpecialAbility) -{ +XS(XS_Mob_SetSpecialAbility) { dXSARGS; - if(items != 3) - Perl_croak(aTHX_ "Usage: Mob::SetSpecialAbility(THIS, ability, value)"); + if (items != 3) + Perl_croak(aTHX_ "Usage: Mob::SetSpecialAbility(THIS, int ability, int value)"); { - Mob* THIS; + Mob *THIS; int ability = SvIV(ST(1)); - int value = SvIV(ST(2)); + int value = SvIV(ST(2)); - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSpecialAbility(ability, value); @@ -8372,24 +7832,22 @@ XS(XS_Mob_SetSpecialAbility) } XS(XS_Mob_SetSpecialAbilityParam); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SetSpecialAbilityParam) -{ +XS(XS_Mob_SetSpecialAbilityParam) { dXSARGS; - if(items != 4) - Perl_croak(aTHX_ "Usage: Mob::SetSpecialAbilityParam(THIS, ability, param, value)"); + if (items != 4) + Perl_croak(aTHX_ "Usage: Mob::SetSpecialAbilityParam(THIS, int ability, int param, int value)"); { - Mob* THIS; + Mob *THIS; int ability = SvIV(ST(1)); - int param = SvIV(ST(2)); - int value = SvIV(ST(3)); + int param = SvIV(ST(2)); + int value = SvIV(ST(3)); - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSpecialAbilityParam(ability, param, value); @@ -8398,21 +7856,19 @@ XS(XS_Mob_SetSpecialAbilityParam) } XS(XS_Mob_ClearSpecialAbilities); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ClearSpecialAbilities) -{ +XS(XS_Mob_ClearSpecialAbilities) { dXSARGS; - if(items != 1) + if (items != 1) Perl_croak(aTHX_ "Usage: Mob::ClearSpecialAbilities(THIS)"); { - Mob* THIS; + Mob *THIS; - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearSpecialAbilities(); @@ -8421,22 +7877,20 @@ XS(XS_Mob_ClearSpecialAbilities) } XS(XS_Mob_ProcessSpecialAbilities); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_ProcessSpecialAbilities) -{ +XS(XS_Mob_ProcessSpecialAbilities) { dXSARGS; - if(items != 2) - Perl_croak(aTHX_ "Usage: Mob::ProcessSpecialAbilities(THIS, str)"); + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::ProcessSpecialAbilities(THIS, string str)"); { - Mob* THIS; - const char *str = (const char*)SvPV_nolen(ST(1)); + Mob *THIS; + const char *str = (const char *) SvPV_nolen(ST(1)); - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob *, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ProcessSpecialAbilities(str); @@ -8445,27 +7899,25 @@ XS(XS_Mob_ProcessSpecialAbilities) } XS(XS_Mob_CanClassEquipItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CanClassEquipItem) -{ +XS(XS_Mob_CanClassEquipItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::CanClassEquipItem(THIS, item_id)"); + Perl_croak(aTHX_ "Usage: Mob::CanClassEquipItem(THIS, uint32 item_id)"); { - Mob * THIS; - bool RETVAL; - uint32 item_id = (uint32)SvUV(ST(1)); + Mob *THIS; + bool RETVAL; + uint32 item_id = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanClassEquipItem(item_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); @@ -8477,18 +7929,17 @@ XS(XS_Mob_IsFeared) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsFeared(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsFeared(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8502,18 +7953,17 @@ XS(XS_Mob_IsBlind) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsBlind(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsBlind(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8527,23 +7977,22 @@ XS(XS_Mob_SeeInvisible) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::SeeInvisible(THIS)"); { - Mob* THIS; + Mob *THIS; uint8 RETVAL; dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->SeeInvisible(); XSprePUSH; - PUSHu((UV)RETVAL); + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -8554,18 +8003,17 @@ XS(XS_Mob_SeeInvisibleUndead) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::SeeInvisibleUndead(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->SeeInvisibleUndead(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8579,18 +8027,17 @@ XS(XS_Mob_SeeHide) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::SeeHide(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->SeeHide(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8604,18 +8051,17 @@ XS(XS_Mob_SeeImprovedHide) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::SeeImprovedHide(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->SeeImprovedHide(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8629,23 +8075,22 @@ XS(XS_Mob_GetNimbusEffect1) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetNimbusEffect1(THIS)"); { - Mob* THIS; + Mob *THIS; uint8 RETVAL; dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetNimbusEffect1(); XSprePUSH; - PUSHu((UV)RETVAL); + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -8656,23 +8101,22 @@ XS(XS_Mob_GetNimbusEffect2) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetNimbusEffect2(THIS)"); { - Mob* THIS; + Mob *THIS; uint8 RETVAL; dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetNimbusEffect2(); XSprePUSH; - PUSHu((UV)RETVAL); + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -8683,23 +8127,22 @@ XS(XS_Mob_GetNimbusEffect3) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetNimbusEffect3(THIS)"); { - Mob* THIS; + Mob *THIS; uint8 RETVAL; dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetNimbusEffect3(); XSprePUSH; - PUSHu((UV)RETVAL); + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -8710,18 +8153,17 @@ XS(XS_Mob_IsTargetable) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsTargetable(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsTargetable(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8735,18 +8177,17 @@ XS(XS_Mob_HasShieldEquiped) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HasShieldEquiped(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->HasShieldEquiped(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8760,18 +8201,17 @@ XS(XS_Mob_HasTwoHandBluntEquiped) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HasTwoHandBluntEquiped(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->HasTwoHandBluntEquiped(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8785,18 +8225,17 @@ XS(XS_Mob_HasTwoHanderEquipped) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HasTwoHanderEquipped(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->HasTwoHanderEquipped(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8808,26 +8247,25 @@ XS(XS_Mob_GetHerosForgeModel); XS(XS_Mob_GetHerosForgeModel) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetHerosForgeModel(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetHerosForgeModel(THIS, uint8 material_slot)"); { - Mob* THIS; + Mob *THIS; int32 RETVAL; - uint8 material_slot = (uint8)SvUV(ST(1)); + uint8 material_slot = (uint8) SvUV(ST(1)); dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetHerosForgeModel(material_slot); XSprePUSH; - PUSHi((IV)RETVAL); + PUSHi((IV) RETVAL); } XSRETURN(1); } @@ -8836,26 +8274,25 @@ XS(XS_Mob_IsEliteMaterialItem); XS(XS_Mob_IsEliteMaterialItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::IsEliteMaterialItem(THIS, material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::IsEliteMaterialItem(THIS, uint8 material_slot)"); { - Mob* THIS; + Mob *THIS; uint32 RETVAL; - uint8 material_slot = (uint8)SvUV(ST(1)); + uint8 material_slot = (uint8) SvUV(ST(1)); dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsEliteMaterialItem(material_slot); XSprePUSH; - PUSHu((UV)RETVAL); + PUSHu((UV) RETVAL); } XSRETURN(1); } @@ -8866,23 +8303,22 @@ XS(XS_Mob_GetBaseSize) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetBaseSize(THIS)"); { - Mob* THIS; + Mob *THIS; float RETVAL; dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetBaseSize(); XSprePUSH; - PUSHn((double)RETVAL); + PUSHn((double) RETVAL); } XSRETURN(1); } @@ -8893,18 +8329,17 @@ XS(XS_Mob_HasOwner) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HasOwner(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->HasOwner(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8918,18 +8353,17 @@ XS(XS_Mob_IsPet) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsPet(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsPet(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8943,18 +8377,17 @@ XS(XS_Mob_HasPet) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::HasPet(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->HasPet(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8968,18 +8401,17 @@ XS(XS_Mob_IsSilenced) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsSilenced(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsSilenced(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -8993,18 +8425,17 @@ XS(XS_Mob_IsAmnesiad) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::IsAmnesiad(THIS)"); { - Mob* THIS; + Mob *THIS; bool RETVAL; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->IsAmnesiad(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -9018,23 +8449,22 @@ XS(XS_Mob_GetMeleeMitigation) { if (items != 1) Perl_croak(aTHX_ "Usage: Mob::GetMeleeMitigation(THIS)"); { - Mob* THIS; + Mob *THIS; int32 RETVAL; dXSTARG; - + if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); + IV tmp = SvIV((SV *) SvRV(ST(0))); THIS = INT2PTR(Mob*, tmp); - } - else + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetMeleeMitigation(); XSprePUSH; - PUSHi((IV)RETVAL); + PUSHi((IV) RETVAL); } XSRETURN(1); } @@ -9043,25 +8473,24 @@ XS(XS_Mob_TryMoveAlong); XS(XS_Mob_TryMoveAlong) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Mob::TryMoveAlong(THIS, distance, angle, send?)"); + Perl_croak(aTHX_ "Usage: Mob::TryMoveAlong(THIS, float distance, float angle, bool send)"); { - Mob* THIS; - float distance = (float)SvNV(ST(1)); - float angle = (float)SvNV(ST(2)); - bool send = true; + Mob *THIS; + float distance = (float) SvNV(ST(1)); + float angle = (float) SvNV(ST(2)); + bool send = true; if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Mob"); - - if(THIS == nullptr) + + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items == 4) - send = (bool)SvTRUE(ST(3)); + send = (bool) SvTRUE(ST(3)); THIS->TryMoveAlong(distance, angle, send); } @@ -9072,337 +8501,335 @@ XS(XS_Mob_TryMoveAlong) { extern "C" #endif XS(boot_Mob); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Mob) -{ +XS(boot_Mob) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "IsClient"), XS_Mob_IsClient, file, "$"); - newXSproto(strcpy(buf, "IsNPC"), XS_Mob_IsNPC, file, "$"); - newXSproto(strcpy(buf, "IsMob"), XS_Mob_IsMob, file, "$"); - newXSproto(strcpy(buf, "IsCorpse"), XS_Mob_IsCorpse, file, "$"); - newXSproto(strcpy(buf, "IsPlayerCorpse"), XS_Mob_IsPlayerCorpse, file, "$"); - newXSproto(strcpy(buf, "IsNPCCorpse"), XS_Mob_IsNPCCorpse, file, "$"); - newXSproto(strcpy(buf, "IsObject"), XS_Mob_IsObject, file, "$"); - newXSproto(strcpy(buf, "IsDoor"), XS_Mob_IsDoor, file, "$"); - newXSproto(strcpy(buf, "IsTrap"), XS_Mob_IsTrap, file, "$"); - newXSproto(strcpy(buf, "IsBeacon"), XS_Mob_IsBeacon, file, "$"); - newXSproto(strcpy(buf, "CastToClient"), XS_Mob_CastToClient, file, "$"); - newXSproto(strcpy(buf, "CastToNPC"), XS_Mob_CastToNPC, file, "$"); - newXSproto(strcpy(buf, "CastToMob"), XS_Mob_CastToMob, file, "$"); - newXSproto(strcpy(buf, "CastToCorpse"), XS_Mob_CastToCorpse, file, "$"); - newXSproto(strcpy(buf, "GetID"), XS_Mob_GetID, file, "$"); - newXSproto(strcpy(buf, "GetName"), XS_Mob_GetName, file, "$"); - newXSproto(strcpy(buf, "Depop"), XS_Mob_Depop, file, "$;$"); - newXSproto(strcpy(buf, "RogueAssassinate"), XS_Mob_RogueAssassinate, file, "$$"); - newXSproto(strcpy(buf, "BehindMob"), XS_Mob_BehindMob, file, "$;$$$"); - newXSproto(strcpy(buf, "SetLevel"), XS_Mob_SetLevel, file, "$$;$"); - newXSproto(strcpy(buf, "GetSkill"), XS_Mob_GetSkill, file, "$$"); - newXSproto(strcpy(buf, "SendWearChange"), XS_Mob_SendWearChange, file, "$$"); - newXSproto(strcpy(buf, "GetEquipment"), XS_Mob_GetEquipment, file, "$$"); - newXSproto(strcpy(buf, "GetEquipmentMaterial"), XS_Mob_GetEquipmentMaterial, file, "$$"); - newXSproto(strcpy(buf, "GetEquipmentColor"), XS_Mob_GetEquipmentColor, file, "$$"); - newXSproto(strcpy(buf, "GetArmorTint"), XS_Mob_GetArmorTint, file, "$$"); - newXSproto(strcpy(buf, "IsMoving"), XS_Mob_IsMoving, file, "$"); - newXSproto(strcpy(buf, "GoToBind"), XS_Mob_GoToBind, file, "$"); - newXSproto(strcpy(buf, "Gate"), XS_Mob_Gate, file, "$"); - newXSproto(strcpy(buf, "Attack"), XS_Mob_Attack, file, "$$;$$"); - newXSproto(strcpy(buf, "Damage"), XS_Mob_Damage, file, "$$$$$;$$$"); - newXSproto(strcpy(buf, "RangedAttack"), XS_Mob_RangedAttack, file, "$$"); - newXSproto(strcpy(buf, "ThrowingAttack"), XS_Mob_ThrowingAttack, file, "$$"); - newXSproto(strcpy(buf, "Heal"), XS_Mob_Heal, file, "$"); - newXSproto(strcpy(buf, "HealDamage"), XS_Mob_HealDamage, file, "$$;$"); - newXSproto(strcpy(buf, "SetMaxHP"), XS_Mob_SetMaxHP, file, "$"); - newXSproto(strcpy(buf, "GetLevelCon"), XS_Mob_GetLevelCon, file, "$$"); - newXSproto(strcpy(buf, "SetHP"), XS_Mob_SetHP, file, "$$"); - newXSproto(strcpy(buf, "DoAnim"), XS_Mob_DoAnim, file, "$$;$"); - newXSproto(strcpy(buf, "ChangeSize"), XS_Mob_ChangeSize, file, "$$;$"); - newXSproto(strcpy(buf, "GMMove"), XS_Mob_GMMove, file, "$$$$;$"); - newXSproto(strcpy(buf, "SendPosUpdate"), XS_Mob_SendPosUpdate, file, "$;$"); - newXSproto(strcpy(buf, "SendPosition"), XS_Mob_SendPosition, file, "$"); - newXSproto(strcpy(buf, "HasProcs"), XS_Mob_HasProcs, file, "$"); - newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$"); - newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$"); - newXSproto(strcpy(buf, "FindBuff"), XS_Mob_FindBuff, file, "$$"); - newXSproto(strcpy(buf, "FindType"), XS_Mob_FindType, file, "$$;$$"); - newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$"); - newXSproto(strcpy(buf, "MakePet"), XS_Mob_MakePet, file, "$$$;$"); - newXSproto(strcpy(buf, "GetBaseRace"), XS_Mob_GetBaseRace, file, "$"); - newXSproto(strcpy(buf, "GetBaseGender"), XS_Mob_GetBaseGender, file, "$"); - newXSproto(strcpy(buf, "GetDeity"), XS_Mob_GetDeity, file, "$"); - newXSproto(strcpy(buf, "GetRace"), XS_Mob_GetRace, file, "$"); - newXSproto(strcpy(buf, "GetGender"), XS_Mob_GetGender, file, "$"); - newXSproto(strcpy(buf, "GetTexture"), XS_Mob_GetTexture, file, "$"); - newXSproto(strcpy(buf, "GetHelmTexture"), XS_Mob_GetHelmTexture, file, "$"); - newXSproto(strcpy(buf, "GetHairColor"), XS_Mob_GetHairColor, file, "$"); - newXSproto(strcpy(buf, "GetBeardColor"), XS_Mob_GetBeardColor, file, "$"); - newXSproto(strcpy(buf, "GetEyeColor1"), XS_Mob_GetEyeColor1, file, "$"); - newXSproto(strcpy(buf, "GetEyeColor2"), XS_Mob_GetEyeColor2, file, "$"); - newXSproto(strcpy(buf, "GetHairStyle"), XS_Mob_GetHairStyle, file, "$"); - newXSproto(strcpy(buf, "GetLuclinFace"), XS_Mob_GetLuclinFace, file, "$"); - newXSproto(strcpy(buf, "GetBeard"), XS_Mob_GetBeard, file, "$"); - newXSproto(strcpy(buf, "GetDrakkinHeritage"), XS_Mob_GetDrakkinHeritage, file, "$"); - newXSproto(strcpy(buf, "GetDrakkinTattoo"), XS_Mob_GetDrakkinTattoo, file, "$"); - newXSproto(strcpy(buf, "GetDrakkinDetails"), XS_Mob_GetDrakkinDetails, file, "$"); - newXSproto(strcpy(buf, "GetClass"), XS_Mob_GetClass, file, "$"); - newXSproto(strcpy(buf, "GetLevel"), XS_Mob_GetLevel, file, "$"); - newXSproto(strcpy(buf, "GetCleanName"), XS_Mob_GetCleanName, file, "$"); - newXSproto(strcpy(buf, "GetTarget"), XS_Mob_GetTarget, file, "$"); - newXSproto(strcpy(buf, "SetTarget"), XS_Mob_SetTarget, file, "$$"); - newXSproto(strcpy(buf, "GetHPRatio"), XS_Mob_GetHPRatio, file, "$"); - newXSproto(strcpy(buf, "IsWarriorClass"), XS_Mob_IsWarriorClass, file, "$"); - newXSproto(strcpy(buf, "GetHP"), XS_Mob_GetHP, file, "$"); - newXSproto(strcpy(buf, "GetMaxHP"), XS_Mob_GetMaxHP, file, "$"); - newXSproto(strcpy(buf, "GetItemHPBonuses"), XS_Mob_GetItemHPBonuses, file, "$"); - newXSproto(strcpy(buf, "GetSpellHPBonuses"), XS_Mob_GetSpellHPBonuses, file, "$"); - newXSproto(strcpy(buf, "GetSpellIDFromSlot"), XS_Mob_GetSpellIDFromSlot, file, "$$"); - newXSproto(strcpy(buf, "GetWalkspeed"), XS_Mob_GetWalkspeed, file, "$"); - newXSproto(strcpy(buf, "GetRunspeed"), XS_Mob_GetRunspeed, file, "$"); - newXSproto(strcpy(buf, "GetCasterLevel"), XS_Mob_GetCasterLevel, file, "$$"); - newXSproto(strcpy(buf, "GetMaxMana"), XS_Mob_GetMaxMana, file, "$"); - newXSproto(strcpy(buf, "GetMana"), XS_Mob_GetMana, file, "$"); - newXSproto(strcpy(buf, "SetMana"), XS_Mob_SetMana, file, "$$"); - newXSproto(strcpy(buf, "GetManaRatio"), XS_Mob_GetManaRatio, file, "$"); - newXSproto(strcpy(buf, "GetAC"), XS_Mob_GetAC, file, "$"); - newXSproto(strcpy(buf, "GetATK"), XS_Mob_GetATK, file, "$"); - newXSproto(strcpy(buf, "GetSTR"), XS_Mob_GetSTR, file, "$"); - newXSproto(strcpy(buf, "GetSTA"), XS_Mob_GetSTA, file, "$"); - newXSproto(strcpy(buf, "GetDEX"), XS_Mob_GetDEX, file, "$"); - newXSproto(strcpy(buf, "GetAGI"), XS_Mob_GetAGI, file, "$"); - newXSproto(strcpy(buf, "GetINT"), XS_Mob_GetINT, file, "$"); - newXSproto(strcpy(buf, "GetWIS"), XS_Mob_GetWIS, file, "$"); - newXSproto(strcpy(buf, "GetCHA"), XS_Mob_GetCHA, file, "$"); - newXSproto(strcpy(buf, "GetMR"), XS_Mob_GetMR, file, "$"); - newXSproto(strcpy(buf, "GetFR"), XS_Mob_GetFR, file, "$"); - newXSproto(strcpy(buf, "GetDR"), XS_Mob_GetDR, file, "$"); - newXSproto(strcpy(buf, "GetPR"), XS_Mob_GetPR, file, "$"); - newXSproto(strcpy(buf, "GetCR"), XS_Mob_GetCR, file, "$"); - newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCorruption, file, "$"); - newXSproto(strcpy(buf, "GetPhR"), XS_Mob_GetPhR, file, "$"); - newXSproto(strcpy(buf, "GetMaxSTR"), XS_Mob_GetMaxSTR, file, "$"); - newXSproto(strcpy(buf, "GetMaxSTA"), XS_Mob_GetMaxSTA, file, "$"); - newXSproto(strcpy(buf, "GetMaxDEX"), XS_Mob_GetMaxDEX, file, "$"); - newXSproto(strcpy(buf, "GetMaxAGI"), XS_Mob_GetMaxAGI, file, "$"); - newXSproto(strcpy(buf, "GetMaxINT"), XS_Mob_GetMaxINT, file, "$"); - newXSproto(strcpy(buf, "GetMaxWIS"), XS_Mob_GetMaxWIS, file, "$"); - newXSproto(strcpy(buf, "GetMaxCHA"), XS_Mob_GetMaxCHA, file, "$"); - newXSproto(strcpy(buf, "GetActSpellRange"), XS_Mob_GetActSpellRange, file, "$$$"); - newXSproto(strcpy(buf, "GetActSpellDamage"), XS_Mob_GetActSpellDamage, file, "$$$"); - newXSproto(strcpy(buf, "GetActSpellHealing"), XS_Mob_GetActSpellHealing, file, "$$$"); - newXSproto(strcpy(buf, "GetActSpellCost"), XS_Mob_GetActSpellCost, file, "$$$"); - newXSproto(strcpy(buf, "GetActSpellDuration"), XS_Mob_GetActSpellDuration, file, "$$$"); - newXSproto(strcpy(buf, "GetActSpellCasttime"), XS_Mob_GetActSpellCasttime, file, "$$$"); - newXSproto(strcpy(buf, "ResistSpell"), XS_Mob_ResistSpell, file, "$$$$"); - newXSproto(strcpy(buf, "GetSpecializeSkillValue"), XS_Mob_GetSpecializeSkillValue, file, "$$"); - newXSproto(strcpy(buf, "GetNPCTypeID"), XS_Mob_GetNPCTypeID, file, "$"); - newXSproto(strcpy(buf, "IsTargeted"), XS_Mob_IsTargeted, file, "$"); - newXSproto(strcpy(buf, "GetX"), XS_Mob_GetX, file, "$"); - newXSproto(strcpy(buf, "GetY"), XS_Mob_GetY, file, "$"); - newXSproto(strcpy(buf, "GetZ"), XS_Mob_GetZ, file, "$"); - newXSproto(strcpy(buf, "GetHeading"), XS_Mob_GetHeading, file, "$"); - newXSproto(strcpy(buf, "GetWaypointX"), XS_Mob_GetWaypointX, file, "$"); - newXSproto(strcpy(buf, "GetWaypointY"), XS_Mob_GetWaypointY, file, "$"); - newXSproto(strcpy(buf, "GetWaypointZ"), XS_Mob_GetWaypointZ, file, "$"); - newXSproto(strcpy(buf, "GetWaypointH"), XS_Mob_GetWaypointH, file, "$"); - newXSproto(strcpy(buf, "GetWaypointPause"), XS_Mob_GetWaypointPause, file, "$"); - newXSproto(strcpy(buf, "GetWaypointID"), XS_Mob_GetWaypointID, file, "$"); - newXSproto(strcpy(buf, "SetCurrentWP"), XS_Mob_SetCurrentWP, file, "$$"); - newXSproto(strcpy(buf, "GetSize"), XS_Mob_GetSize, file, "$"); - newXSproto(strcpy(buf, "SetFollowID"), XS_Mob_SetFollowID, file, "$$"); - newXSproto(strcpy(buf, "GetFollowID"), XS_Mob_GetFollowID, file, "$"); - newXSproto(strcpy(buf, "Message"), XS_Mob_Message, file, "$$$;@"); - newXSproto(strcpy(buf, "Message_StringID"), XS_Mob_Message_StringID, file, "$$$;$"); - newXSproto(strcpy(buf, "Say"), XS_Mob_Say, file, "$$;@"); - newXSproto(strcpy(buf, "Shout"), XS_Mob_Shout, file, "$$;@"); - newXSproto(strcpy(buf, "Emote"), XS_Mob_Emote, file, "$$;@"); - newXSproto(strcpy(buf, "InterruptSpell"), XS_Mob_InterruptSpell, file, "$;$"); - newXSproto(strcpy(buf, "CastSpell"), XS_Mob_CastSpell, file, "$$$;$$$"); - newXSproto(strcpy(buf, "SpellFinished"), XS_Mob_SpellFinished, file, "$$;$$"); - newXSproto(strcpy(buf, "IsImmuneToSpell"), XS_Mob_IsImmuneToSpell, file, "$$$"); - newXSproto(strcpy(buf, "BuffFadeBySpellID"), XS_Mob_BuffFadeBySpellID, file, "$$"); - newXSproto(strcpy(buf, "BuffFadeByEffect"), XS_Mob_BuffFadeByEffect, file, "$$;$"); - newXSproto(strcpy(buf, "BuffFadeAll"), XS_Mob_BuffFadeAll, file, "$"); - newXSproto(strcpy(buf, "BuffFadeBySlot"), XS_Mob_BuffFadeBySlot, file, "$$;$"); - newXSproto(strcpy(buf, "CanBuffStack"), XS_Mob_CanBuffStack, file, "$$$;$"); - newXSproto(strcpy(buf, "IsCasting"), XS_Mob_IsCasting, file, "$"); - newXSproto(strcpy(buf, "CastingSpellID"), XS_Mob_CastingSpellID, file, "$"); - newXSproto(strcpy(buf, "SetAppearance"), XS_Mob_SetAppearance, file, "$$;$"); - newXSproto(strcpy(buf, "GetAppearance"), XS_Mob_GetAppearance, file, "$"); - newXSproto(strcpy(buf, "GetRunAnimSpeed"), XS_Mob_GetRunAnimSpeed, file, "$"); - newXSproto(strcpy(buf, "SetRunAnimSpeed"), XS_Mob_SetRunAnimSpeed, file, "$$"); - newXSproto(strcpy(buf, "SetPetID"), XS_Mob_SetPetID, file, "$$"); - newXSproto(strcpy(buf, "GetPetID"), XS_Mob_GetPetID, file, "$"); - newXSproto(strcpy(buf, "SetOwnerID"), XS_Mob_SetOwnerID, file, "$$"); - newXSproto(strcpy(buf, "GetOwnerID"), XS_Mob_GetOwnerID, file, "$"); - newXSproto(strcpy(buf, "GetPetType"), XS_Mob_GetPetType, file, "$"); - newXSproto(strcpy(buf, "GetBodyType"), XS_Mob_GetBodyType, file, "$"); - newXSproto(strcpy(buf, "Stun"), XS_Mob_Stun, file, "$$"); - newXSproto(strcpy(buf, "Spin"), XS_Mob_Spin, file, "$"); - newXSproto(strcpy(buf, "Kill"), XS_Mob_Kill, file, "$"); - newXSproto(strcpy(buf, "SetInvul"), XS_Mob_SetInvul, file, "$$"); - newXSproto(strcpy(buf, "GetInvul"), XS_Mob_GetInvul, file, "$"); - newXSproto(strcpy(buf, "SetExtraHaste"), XS_Mob_SetExtraHaste, file, "$$"); - newXSproto(strcpy(buf, "GetHaste"), XS_Mob_GetHaste, file, "$"); - newXSproto(strcpy(buf, "GetHandToHandDamage"), XS_Mob_GetHandToHandDamage, file, "$"); - newXSproto(strcpy(buf, "CanThisClassDoubleAttack"), XS_Mob_CanThisClassDoubleAttack, file, "$"); - newXSproto(strcpy(buf, "CanThisClassDualWield"), XS_Mob_CanThisClassDualWield, file, "$"); - newXSproto(strcpy(buf, "CanThisClassRiposte"), XS_Mob_CanThisClassRiposte, file, "$"); - newXSproto(strcpy(buf, "CanThisClassDodge"), XS_Mob_CanThisClassDodge, file, "$"); - newXSproto(strcpy(buf, "CanThisClassParry"), XS_Mob_CanThisClassParry, file, "$"); - newXSproto(strcpy(buf, "GetHandToHandDelay"), XS_Mob_GetHandToHandDelay, file, "$"); - newXSproto(strcpy(buf, "GetClassLevelFactor"), XS_Mob_GetClassLevelFactor, file, "$"); - newXSproto(strcpy(buf, "Mesmerize"), XS_Mob_Mesmerize, file, "$"); - newXSproto(strcpy(buf, "IsMezzed"), XS_Mob_IsMezzed, file, "$"); - newXSproto(strcpy(buf, "IsStunned"), XS_Mob_IsStunned, file, "$"); - newXSproto(strcpy(buf, "StartEnrage"), XS_Mob_StartEnrage, file, "$"); - newXSproto(strcpy(buf, "IsEnraged"), XS_Mob_IsEnraged, file, "$"); - newXSproto(strcpy(buf, "GetReverseFactionCon"), XS_Mob_GetReverseFactionCon, file, "$$"); - newXSproto(strcpy(buf, "IsAIControlled"), XS_Mob_IsAIControlled, file, "$"); - newXSproto(strcpy(buf, "GetAggroRange"), XS_Mob_GetAggroRange, file, "$"); - newXSproto(strcpy(buf, "GetAssistRange"), XS_Mob_GetAssistRange, file, "$"); - newXSproto(strcpy(buf, "SetPetOrder"), XS_Mob_SetPetOrder, file, "$$"); - newXSproto(strcpy(buf, "GetPetOrder"), XS_Mob_GetPetOrder, file, "$"); - newXSproto(strcpy(buf, "IsRoamer"), XS_Mob_IsRoamer, file, "$"); - newXSproto(strcpy(buf, "IsRooted"), XS_Mob_IsRooted, file, "$"); - newXSproto(strcpy(buf, "AddToHateList"), XS_Mob_AddToHateList, file, "$$;$$$$$"); - newXSproto(strcpy(buf, "SetHate"), XS_Mob_SetHate, file, "$$;$$"); - newXSproto(strcpy(buf, "HalveAggro"), XS_Mob_HalveAggro, file, "$$"); - newXSproto(strcpy(buf, "DoubleAggro"), XS_Mob_DoubleAggro, file, "$$"); - newXSproto(strcpy(buf, "GetHateAmount"), XS_Mob_GetHateAmount, file, "$$;$"); - newXSproto(strcpy(buf, "GetDamageAmount"), XS_Mob_GetDamageAmount, file, "$$"); - newXSproto(strcpy(buf, "GetHateTop"), XS_Mob_GetHateTop, file, "$"); - newXSproto(strcpy(buf, "GetHateDamageTop"), XS_Mob_GetHateDamageTop, file, "$$"); - newXSproto(strcpy(buf, "GetHateRandom"), XS_Mob_GetHateRandom, file, "$"); - newXSproto(strcpy(buf, "IsEngaged"), XS_Mob_IsEngaged, file, "$"); - newXSproto(strcpy(buf, "HateSummon"), XS_Mob_HateSummon, file, "$"); - newXSproto(strcpy(buf, "FaceTarget"), XS_Mob_FaceTarget, file, "$;$$"); - newXSproto(strcpy(buf, "SetHeading"), XS_Mob_SetHeading, file, "$$"); - newXSproto(strcpy(buf, "WipeHateList"), XS_Mob_WipeHateList, file, "$"); - newXSproto(strcpy(buf, "CheckAggro"), XS_Mob_CheckAggro, file, "$$"); - newXSproto(strcpy(buf, "CalculateHeadingToTarget"), XS_Mob_CalculateHeadingToTarget, file, "$$$"); - newXSproto(strcpy(buf, "CalculateNewPosition"), XS_Mob_CalculateNewPosition, file, "$$$$$;$"); - newXSproto(strcpy(buf, "CalculateNewPosition2"), XS_Mob_CalculateNewPosition2, file, "$$$$$;$"); - newXSproto(strcpy(buf, "CalculateDistance"), XS_Mob_CalculateDistance, file, "$$$$"); - newXSproto(strcpy(buf, "SendTo"), XS_Mob_SendTo, file, "$$$$"); - newXSproto(strcpy(buf, "SendToFixZ"), XS_Mob_SendToFixZ, file, "$$$$"); - newXSproto(strcpy(buf, "NPCSpecialAttacks"), XS_Mob_NPCSpecialAttacks, file, "$$$;$$"); - newXSproto(strcpy(buf, "DontHealMeBefore"), XS_Mob_DontHealMeBefore, file, "$"); - newXSproto(strcpy(buf, "DontBuffMeBefore"), XS_Mob_DontBuffMeBefore, file, "$"); - newXSproto(strcpy(buf, "DontDotMeBefore"), XS_Mob_DontDotMeBefore, file, "$"); - newXSproto(strcpy(buf, "DontRootMeBefore"), XS_Mob_DontRootMeBefore, file, "$"); - newXSproto(strcpy(buf, "DontSnareMeBefore"), XS_Mob_DontSnareMeBefore, file, "$"); - newXSproto(strcpy(buf, "GetResist"), XS_Mob_GetResist, file, "$$"); - newXSproto(strcpy(buf, "GetShieldTarget"), XS_Mob_GetShieldTarget, file, "$"); - newXSproto(strcpy(buf, "SetShieldTarget"), XS_Mob_SetShieldTarget, file, "$$"); - newXSproto(strcpy(buf, "Charmed"), XS_Mob_Charmed, file, "$"); - newXSproto(strcpy(buf, "GetLevelHP"), XS_Mob_GetLevelHP, file, "$$"); - newXSproto(strcpy(buf, "GetZoneID"), XS_Mob_GetZoneID, file, "$"); - newXSproto(strcpy(buf, "CheckAggroAmount"), XS_Mob_CheckAggroAmount, file, "$$"); - newXSproto(strcpy(buf, "CheckHealAggroAmount"), XS_Mob_CheckHealAggroAmount, file, "$$"); - newXSproto(strcpy(buf, "GetAA"), XS_Mob_GetAA, file, "$$"); - newXSproto(strcpy(buf, "GetAAByAAID"), XS_Mob_GetAAByAAID, file, "$$"); - newXSproto(strcpy(buf, "SetAA"), XS_Mob_SetAA, file, "$$$;$"); - newXSproto(strcpy(buf, "DivineAura"), XS_Mob_DivineAura, file, "$"); - newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$"); - newXSproto(strcpy(buf, "RemoveFromFeignMemory"), XS_Mob_RemoveFromFeignMemory, file, "$$"); - newXSproto(strcpy(buf, "ClearFeignMemory"), XS_Mob_ClearFeignMemory, file, "$"); - newXSproto(strcpy(buf, "SetOOCRegen"), XS_Mob_SetOOCRegen, file, "$$"); - newXSproto(strcpy(buf, "GetEntityVariable"), XS_Mob_GetEntityVariable, file, "$$"); - newXSproto(strcpy(buf, "SetEntityVariable"), XS_Mob_SetEntityVariable, file, "$$$"); - newXSproto(strcpy(buf, "EntityVariableExists"), XS_Mob_EntityVariableExists, file, "$$"); - newXSproto(strcpy(buf, "GetHateList"), XS_Mob_GetHateList, file, "$"); - newXSproto(strcpy(buf, "SignalClient"), XS_Mob_SignalClient, file, "$$$"); - newXSproto(strcpy(buf, "CombatRange"), XS_Mob_CombatRange, file, "$$"); - newXSproto(strcpy(buf, "DoSpecialAttackDamage"), XS_Mob_DoSpecialAttackDamage, file, "$$$$;$$"); - newXSproto(strcpy(buf, "CheckLoS"), XS_Mob_CheckLoS, file, "$$"); - newXSproto(strcpy(buf, "CheckLoSToLoc"), XS_Mob_CheckLoSToLoc, file, "$$$$;$"); - newXSproto(strcpy(buf, "FindGroundZ"), XS_Mob_FindGroundZ, file, "$$$;$"); - newXSproto(strcpy(buf, "ProjectileAnim"), XS_Mob_ProjectileAnim, file, "$$$;$$$$$$"); - newXSproto(strcpy(buf, "HasNPCSpecialAtk"), XS_Mob_HasNPCSpecialAtk, file, "$$"); - newXSproto(strcpy(buf, "SendAppearanceEffect"), XS_Mob_SendAppearanceEffect, file, "$$;$$$$"); - newXSproto(strcpy(buf, "SetFlyMode"), XS_Mob_SetFlyMode, file, "$$"); - newXSproto(strcpy(buf, "SetTexture"), XS_Mob_SetTexture, file, "$$"); - newXSproto(strcpy(buf, "SetRace"), XS_Mob_SetRace, file, "$$"); - newXSproto(strcpy(buf, "SetGender"), XS_Mob_SetGender, file, "$$"); - newXSproto(strcpy(buf, "SendIllusion"), XS_Mob_SendIllusion, file, "$$;$$$$$$$$$$$$"); - newXSproto(strcpy(buf, "MakeTempPet"), XS_Mob_MakeTempPet, file, "$$;$$$$"); - newXSproto(strcpy(buf, "TypesTempPet"), XS_Mob_TypesTempPet, file, "$$;$$$$$"); - newXSproto(strcpy(buf, "CameraEffect"), XS_Mob_CameraEffect, file, "$$;$$$"); - newXSproto(strcpy(buf, "SpellEffect"), XS_Mob_SpellEffect, file, "$$;$$$$$$"); - newXSproto(strcpy(buf, "TempName"), XS_Mob_TempName, file, "$:$"); - newXSproto(strcpy(buf, "GetItemStat"), XS_Mob_GetItemStat, file, "$$$"); - newXSproto(strcpy(buf, "GetGlobal"), XS_Mob_GetGlobal, file, "$$"); - newXSproto(strcpy(buf, "SetGlobal"), XS_Mob_SetGlobal, file, "$$$$$;$"); - newXSproto(strcpy(buf, "TarGlobal"), XS_Mob_TarGlobal, file, "$$$$$$$"); - newXSproto(strcpy(buf, "DelGlobal"), XS_Mob_DelGlobal, file, "$$"); - newXSproto(strcpy(buf, "SetSlotTint"), XS_Mob_SetSlotTint, file, "$$$$$"); - newXSproto(strcpy(buf, "WearChange"), XS_Mob_WearChange, file, "$$$;$$"); - newXSproto(strcpy(buf, "DoKnockback"), XS_Mob_DoKnockback, file, "$$$$"); - newXSproto(strcpy(buf, "RemoveNimbusEffect"), XS_Mob_RemoveNimbusEffect, file, "$$"); - newXSproto(strcpy(buf, "IsRunning"), XS_Mob_IsRunning, file, "$"); - newXSproto(strcpy(buf, "SetRunning"), XS_Mob_SetRunning, file, "$$"); - newXSproto(strcpy(buf, "SetBodyType"), XS_Mob_SetBodyType, file, "$$;$"); - newXSproto(strcpy(buf, "SetDeltas"), XS_Mob_SetDeltas, file, "$$$$$"); - newXSproto(strcpy(buf, "SetLD"), XS_Mob_SetLD, file, "$$"); - newXSproto(strcpy(buf, "SetTargetDestSteps"), XS_Mob_SetTargetDestSteps, file, "$$"); - newXSproto(strcpy(buf, "SetTargetable"), XS_Mob_SetTargetable, file, "$$"); - newXSproto(strcpy(buf, "MakeTempPet"), XS_Mob_MakeTempPet, file, "$$;$$$$"); - newXSproto(strcpy(buf, "ModSkillDmgTaken"), XS_Mob_ModSkillDmgTaken, file, "$$$"); - newXSproto(strcpy(buf, "GetModSkillDmgTaken"), XS_Mob_GetModSkillDmgTaken, file, "$$"); - newXSproto(strcpy(buf, "GetSkillDmgTaken"), XS_Mob_GetSkillDmgTaken, file, "$$"); - newXSproto(strcpy(buf, "SetAllowBeneficial"), XS_Mob_SetAllowBeneficial, file, "$$"); - newXSproto(strcpy(buf, "GetAllowBeneficial"), XS_Mob_GetAllowBeneficial, file, "$$"); - newXSproto(strcpy(buf, "IsBeneficialAllowed"), XS_Mob_IsBeneficialAllowed, file, "$$"); - newXSproto(strcpy(buf, "ModVulnerability"), XS_Mob_ModVulnerability, file, "$$$"); - newXSproto(strcpy(buf, "GetModVulnerability"), XS_Mob_GetModVulnerability, file, "$$"); - newXSproto(strcpy(buf, "DoMeleeSkillAttackDmg"), XS_Mob_DoMeleeSkillAttackDmg, file, "$$$$$$$"); - newXSproto(strcpy(buf, "DoArcheryAttackDmg"), XS_Mob_DoArcheryAttackDmg, file, "$$$$$$$"); - newXSproto(strcpy(buf, "DoThrowingAttackDmg"), XS_Mob_DoThrowingAttackDmg, file, "$$$$$$$"); - newXSproto(strcpy(buf, "SetDisableMelee"), XS_Mob_SetDisableMelee, file, "$$"); - newXSproto(strcpy(buf, "IsMeleeDisabled"), XS_Mob_IsMeleeDisabled, file, "$"); - newXSproto(strcpy(buf, "SetFlurryChance"), XS_Mob_SetFlurryChance, file, "$$"); - newXSproto(strcpy(buf, "GetFlurryChance"), XS_Mob_GetFlurryChance, file, "$"); - newXSproto(strcpy(buf, "GetSpellStat"), XS_Mob_GetSpellStat, file, "$$$$"); - newXSproto(strcpy(buf, "GetSpecialAbility"), XS_Mob_GetSpecialAbility, file, "$$"); - newXSproto(strcpy(buf, "GetSpecialAbilityParam"), XS_Mob_GetSpecialAbilityParam, file, "$$$"); - newXSproto(strcpy(buf, "SetSpecialAbility"), XS_Mob_SetSpecialAbility, file, "$$$"); - newXSproto(strcpy(buf, "SetSpecialAbilityParam"), XS_Mob_SetSpecialAbilityParam, file, "$$$$"); - newXSproto(strcpy(buf, "ClearSpecialAbilities"), XS_Mob_ClearSpecialAbilities, file, "$"); - newXSproto(strcpy(buf, "ProcessSpecialAbilities"), XS_Mob_ProcessSpecialAbilities, file, "$$"); - newXSproto(strcpy(buf, "CanClassEquipItem"), XS_Mob_CanClassEquipItem, file, "$$"); - newXSproto(strcpy(buf, "IsFeared"), XS_Mob_IsFeared, file, "$"); - newXSproto(strcpy(buf, "IsBlind"), XS_Mob_IsBlind, file, "$"); - newXSproto(strcpy(buf, "SeeInvisible"), XS_Mob_SeeInvisible, file, "$"); - newXSproto(strcpy(buf, "SeeInvisibleUndead"), XS_Mob_SeeInvisibleUndead, file, "$"); - newXSproto(strcpy(buf, "SeeHide"), XS_Mob_SeeHide, file, "$"); - newXSproto(strcpy(buf, "SeeImprovedHide"), XS_Mob_SeeImprovedHide, file, "$"); - newXSproto(strcpy(buf, "GetNimbusEffect1"), XS_Mob_GetNimbusEffect1, file, "$"); - newXSproto(strcpy(buf, "GetNimbusEffect2"), XS_Mob_GetNimbusEffect2, file, "$"); - newXSproto(strcpy(buf, "GetNimbusEffect3"), XS_Mob_GetNimbusEffect3, file, "$"); - newXSproto(strcpy(buf, "IsTargetable"), XS_Mob_IsTargetable, file, "$"); - newXSproto(strcpy(buf, "HasShieldEquiped"), XS_Mob_HasShieldEquiped, file, "$"); - newXSproto(strcpy(buf, "HasTwoHandBluntEquiped"), XS_Mob_HasTwoHandBluntEquiped, file, "$"); - newXSproto(strcpy(buf, "HasTwoHanderEquipped"), XS_Mob_HasTwoHanderEquipped, file, "$"); - newXSproto(strcpy(buf, "GetHerosForgeModel"), XS_Mob_GetHerosForgeModel, file, "$$"); - newXSproto(strcpy(buf, "IsEliteMaterialItem"), XS_Mob_IsEliteMaterialItem, file, "$$"); - newXSproto(strcpy(buf, "GetBaseSize"), XS_Mob_GetBaseSize, file, "$"); - newXSproto(strcpy(buf, "HasOwner"), XS_Mob_HasOwner, file, "$"); - newXSproto(strcpy(buf, "IsPet"), XS_Mob_IsPet, file, "$"); - newXSproto(strcpy(buf, "HasPet"), XS_Mob_HasPet, file, "$"); - newXSproto(strcpy(buf, "IsSilenced"), XS_Mob_IsSilenced, file, "$"); - newXSproto(strcpy(buf, "IsAmnesiad"), XS_Mob_IsAmnesiad, file, "$"); - newXSproto(strcpy(buf, "GetMeleeMitigation"), XS_Mob_GetMeleeMitigation, file, "$"); - newXSproto(strcpy(buf, "TryMoveAlong"), XS_Mob_TryMoveAlong, file, "$$$;$"); + newXSproto(strcpy(buf, "IsClient"), XS_Mob_IsClient, file, "$"); + newXSproto(strcpy(buf, "IsNPC"), XS_Mob_IsNPC, file, "$"); + newXSproto(strcpy(buf, "IsMob"), XS_Mob_IsMob, file, "$"); + newXSproto(strcpy(buf, "IsCorpse"), XS_Mob_IsCorpse, file, "$"); + newXSproto(strcpy(buf, "IsPlayerCorpse"), XS_Mob_IsPlayerCorpse, file, "$"); + newXSproto(strcpy(buf, "IsNPCCorpse"), XS_Mob_IsNPCCorpse, file, "$"); + newXSproto(strcpy(buf, "IsObject"), XS_Mob_IsObject, file, "$"); + newXSproto(strcpy(buf, "IsDoor"), XS_Mob_IsDoor, file, "$"); + newXSproto(strcpy(buf, "IsTrap"), XS_Mob_IsTrap, file, "$"); + newXSproto(strcpy(buf, "IsBeacon"), XS_Mob_IsBeacon, file, "$"); + newXSproto(strcpy(buf, "CastToClient"), XS_Mob_CastToClient, file, "$"); + newXSproto(strcpy(buf, "CastToNPC"), XS_Mob_CastToNPC, file, "$"); + newXSproto(strcpy(buf, "CastToMob"), XS_Mob_CastToMob, file, "$"); + newXSproto(strcpy(buf, "CastToCorpse"), XS_Mob_CastToCorpse, file, "$"); + newXSproto(strcpy(buf, "GetID"), XS_Mob_GetID, file, "$"); + newXSproto(strcpy(buf, "GetName"), XS_Mob_GetName, file, "$"); + newXSproto(strcpy(buf, "Depop"), XS_Mob_Depop, file, "$;$"); + newXSproto(strcpy(buf, "RogueAssassinate"), XS_Mob_RogueAssassinate, file, "$$"); + newXSproto(strcpy(buf, "BehindMob"), XS_Mob_BehindMob, file, "$;$$$"); + newXSproto(strcpy(buf, "SetLevel"), XS_Mob_SetLevel, file, "$$;$"); + newXSproto(strcpy(buf, "GetSkill"), XS_Mob_GetSkill, file, "$$"); + newXSproto(strcpy(buf, "SendWearChange"), XS_Mob_SendWearChange, file, "$$"); + newXSproto(strcpy(buf, "GetEquipment"), XS_Mob_GetEquipment, file, "$$"); + newXSproto(strcpy(buf, "GetEquipmentMaterial"), XS_Mob_GetEquipmentMaterial, file, "$$"); + newXSproto(strcpy(buf, "GetEquipmentColor"), XS_Mob_GetEquipmentColor, file, "$$"); + newXSproto(strcpy(buf, "GetArmorTint"), XS_Mob_GetArmorTint, file, "$$"); + newXSproto(strcpy(buf, "IsMoving"), XS_Mob_IsMoving, file, "$"); + newXSproto(strcpy(buf, "GoToBind"), XS_Mob_GoToBind, file, "$"); + newXSproto(strcpy(buf, "Gate"), XS_Mob_Gate, file, "$"); + newXSproto(strcpy(buf, "Attack"), XS_Mob_Attack, file, "$$;$$"); + newXSproto(strcpy(buf, "Damage"), XS_Mob_Damage, file, "$$$$$;$$$"); + newXSproto(strcpy(buf, "RangedAttack"), XS_Mob_RangedAttack, file, "$$"); + newXSproto(strcpy(buf, "ThrowingAttack"), XS_Mob_ThrowingAttack, file, "$$"); + newXSproto(strcpy(buf, "Heal"), XS_Mob_Heal, file, "$"); + newXSproto(strcpy(buf, "HealDamage"), XS_Mob_HealDamage, file, "$$;$"); + newXSproto(strcpy(buf, "SetMaxHP"), XS_Mob_SetMaxHP, file, "$"); + newXSproto(strcpy(buf, "GetLevelCon"), XS_Mob_GetLevelCon, file, "$$"); + newXSproto(strcpy(buf, "SetHP"), XS_Mob_SetHP, file, "$$"); + newXSproto(strcpy(buf, "DoAnim"), XS_Mob_DoAnim, file, "$$;$"); + newXSproto(strcpy(buf, "ChangeSize"), XS_Mob_ChangeSize, file, "$$;$"); + newXSproto(strcpy(buf, "GMMove"), XS_Mob_GMMove, file, "$$$$;$"); + newXSproto(strcpy(buf, "SendPosUpdate"), XS_Mob_SendPosUpdate, file, "$;$"); + newXSproto(strcpy(buf, "SendPosition"), XS_Mob_SendPosition, file, "$"); + newXSproto(strcpy(buf, "HasProcs"), XS_Mob_HasProcs, file, "$"); + newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$"); + newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$"); + newXSproto(strcpy(buf, "FindBuff"), XS_Mob_FindBuff, file, "$$"); + newXSproto(strcpy(buf, "FindType"), XS_Mob_FindType, file, "$$;$$"); + newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$"); + newXSproto(strcpy(buf, "MakePet"), XS_Mob_MakePet, file, "$$$;$"); + newXSproto(strcpy(buf, "GetBaseRace"), XS_Mob_GetBaseRace, file, "$"); + newXSproto(strcpy(buf, "GetBaseGender"), XS_Mob_GetBaseGender, file, "$"); + newXSproto(strcpy(buf, "GetDeity"), XS_Mob_GetDeity, file, "$"); + newXSproto(strcpy(buf, "GetRace"), XS_Mob_GetRace, file, "$"); + newXSproto(strcpy(buf, "GetGender"), XS_Mob_GetGender, file, "$"); + newXSproto(strcpy(buf, "GetTexture"), XS_Mob_GetTexture, file, "$"); + newXSproto(strcpy(buf, "GetHelmTexture"), XS_Mob_GetHelmTexture, file, "$"); + newXSproto(strcpy(buf, "GetHairColor"), XS_Mob_GetHairColor, file, "$"); + newXSproto(strcpy(buf, "GetBeardColor"), XS_Mob_GetBeardColor, file, "$"); + newXSproto(strcpy(buf, "GetEyeColor1"), XS_Mob_GetEyeColor1, file, "$"); + newXSproto(strcpy(buf, "GetEyeColor2"), XS_Mob_GetEyeColor2, file, "$"); + newXSproto(strcpy(buf, "GetHairStyle"), XS_Mob_GetHairStyle, file, "$"); + newXSproto(strcpy(buf, "GetLuclinFace"), XS_Mob_GetLuclinFace, file, "$"); + newXSproto(strcpy(buf, "GetBeard"), XS_Mob_GetBeard, file, "$"); + newXSproto(strcpy(buf, "GetDrakkinHeritage"), XS_Mob_GetDrakkinHeritage, file, "$"); + newXSproto(strcpy(buf, "GetDrakkinTattoo"), XS_Mob_GetDrakkinTattoo, file, "$"); + newXSproto(strcpy(buf, "GetDrakkinDetails"), XS_Mob_GetDrakkinDetails, file, "$"); + newXSproto(strcpy(buf, "GetClass"), XS_Mob_GetClass, file, "$"); + newXSproto(strcpy(buf, "GetLevel"), XS_Mob_GetLevel, file, "$"); + newXSproto(strcpy(buf, "GetCleanName"), XS_Mob_GetCleanName, file, "$"); + newXSproto(strcpy(buf, "GetTarget"), XS_Mob_GetTarget, file, "$"); + newXSproto(strcpy(buf, "SetTarget"), XS_Mob_SetTarget, file, "$$"); + newXSproto(strcpy(buf, "GetHPRatio"), XS_Mob_GetHPRatio, file, "$"); + newXSproto(strcpy(buf, "IsWarriorClass"), XS_Mob_IsWarriorClass, file, "$"); + newXSproto(strcpy(buf, "GetHP"), XS_Mob_GetHP, file, "$"); + newXSproto(strcpy(buf, "GetMaxHP"), XS_Mob_GetMaxHP, file, "$"); + newXSproto(strcpy(buf, "GetItemHPBonuses"), XS_Mob_GetItemHPBonuses, file, "$"); + newXSproto(strcpy(buf, "GetSpellHPBonuses"), XS_Mob_GetSpellHPBonuses, file, "$"); + newXSproto(strcpy(buf, "GetSpellIDFromSlot"), XS_Mob_GetSpellIDFromSlot, file, "$$"); + newXSproto(strcpy(buf, "GetWalkspeed"), XS_Mob_GetWalkspeed, file, "$"); + newXSproto(strcpy(buf, "GetRunspeed"), XS_Mob_GetRunspeed, file, "$"); + newXSproto(strcpy(buf, "GetCasterLevel"), XS_Mob_GetCasterLevel, file, "$$"); + newXSproto(strcpy(buf, "GetMaxMana"), XS_Mob_GetMaxMana, file, "$"); + newXSproto(strcpy(buf, "GetMana"), XS_Mob_GetMana, file, "$"); + newXSproto(strcpy(buf, "SetMana"), XS_Mob_SetMana, file, "$$"); + newXSproto(strcpy(buf, "GetManaRatio"), XS_Mob_GetManaRatio, file, "$"); + newXSproto(strcpy(buf, "GetAC"), XS_Mob_GetAC, file, "$"); + newXSproto(strcpy(buf, "GetATK"), XS_Mob_GetATK, file, "$"); + newXSproto(strcpy(buf, "GetSTR"), XS_Mob_GetSTR, file, "$"); + newXSproto(strcpy(buf, "GetSTA"), XS_Mob_GetSTA, file, "$"); + newXSproto(strcpy(buf, "GetDEX"), XS_Mob_GetDEX, file, "$"); + newXSproto(strcpy(buf, "GetAGI"), XS_Mob_GetAGI, file, "$"); + newXSproto(strcpy(buf, "GetINT"), XS_Mob_GetINT, file, "$"); + newXSproto(strcpy(buf, "GetWIS"), XS_Mob_GetWIS, file, "$"); + newXSproto(strcpy(buf, "GetCHA"), XS_Mob_GetCHA, file, "$"); + newXSproto(strcpy(buf, "GetMR"), XS_Mob_GetMR, file, "$"); + newXSproto(strcpy(buf, "GetFR"), XS_Mob_GetFR, file, "$"); + newXSproto(strcpy(buf, "GetDR"), XS_Mob_GetDR, file, "$"); + newXSproto(strcpy(buf, "GetPR"), XS_Mob_GetPR, file, "$"); + newXSproto(strcpy(buf, "GetCR"), XS_Mob_GetCR, file, "$"); + newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCorruption, file, "$"); + newXSproto(strcpy(buf, "GetPhR"), XS_Mob_GetPhR, file, "$"); + newXSproto(strcpy(buf, "GetMaxSTR"), XS_Mob_GetMaxSTR, file, "$"); + newXSproto(strcpy(buf, "GetMaxSTA"), XS_Mob_GetMaxSTA, file, "$"); + newXSproto(strcpy(buf, "GetMaxDEX"), XS_Mob_GetMaxDEX, file, "$"); + newXSproto(strcpy(buf, "GetMaxAGI"), XS_Mob_GetMaxAGI, file, "$"); + newXSproto(strcpy(buf, "GetMaxINT"), XS_Mob_GetMaxINT, file, "$"); + newXSproto(strcpy(buf, "GetMaxWIS"), XS_Mob_GetMaxWIS, file, "$"); + newXSproto(strcpy(buf, "GetMaxCHA"), XS_Mob_GetMaxCHA, file, "$"); + newXSproto(strcpy(buf, "GetActSpellRange"), XS_Mob_GetActSpellRange, file, "$$$"); + newXSproto(strcpy(buf, "GetActSpellDamage"), XS_Mob_GetActSpellDamage, file, "$$$"); + newXSproto(strcpy(buf, "GetActSpellHealing"), XS_Mob_GetActSpellHealing, file, "$$$"); + newXSproto(strcpy(buf, "GetActSpellCost"), XS_Mob_GetActSpellCost, file, "$$$"); + newXSproto(strcpy(buf, "GetActSpellDuration"), XS_Mob_GetActSpellDuration, file, "$$$"); + newXSproto(strcpy(buf, "GetActSpellCasttime"), XS_Mob_GetActSpellCasttime, file, "$$$"); + newXSproto(strcpy(buf, "ResistSpell"), XS_Mob_ResistSpell, file, "$$$$"); + newXSproto(strcpy(buf, "GetSpecializeSkillValue"), XS_Mob_GetSpecializeSkillValue, file, "$$"); + newXSproto(strcpy(buf, "GetNPCTypeID"), XS_Mob_GetNPCTypeID, file, "$"); + newXSproto(strcpy(buf, "IsTargeted"), XS_Mob_IsTargeted, file, "$"); + newXSproto(strcpy(buf, "GetX"), XS_Mob_GetX, file, "$"); + newXSproto(strcpy(buf, "GetY"), XS_Mob_GetY, file, "$"); + newXSproto(strcpy(buf, "GetZ"), XS_Mob_GetZ, file, "$"); + newXSproto(strcpy(buf, "GetHeading"), XS_Mob_GetHeading, file, "$"); + newXSproto(strcpy(buf, "GetWaypointX"), XS_Mob_GetWaypointX, file, "$"); + newXSproto(strcpy(buf, "GetWaypointY"), XS_Mob_GetWaypointY, file, "$"); + newXSproto(strcpy(buf, "GetWaypointZ"), XS_Mob_GetWaypointZ, file, "$"); + newXSproto(strcpy(buf, "GetWaypointH"), XS_Mob_GetWaypointH, file, "$"); + newXSproto(strcpy(buf, "GetWaypointPause"), XS_Mob_GetWaypointPause, file, "$"); + newXSproto(strcpy(buf, "GetWaypointID"), XS_Mob_GetWaypointID, file, "$"); + newXSproto(strcpy(buf, "SetCurrentWP"), XS_Mob_SetCurrentWP, file, "$$"); + newXSproto(strcpy(buf, "GetSize"), XS_Mob_GetSize, file, "$"); + newXSproto(strcpy(buf, "SetFollowID"), XS_Mob_SetFollowID, file, "$$"); + newXSproto(strcpy(buf, "GetFollowID"), XS_Mob_GetFollowID, file, "$"); + newXSproto(strcpy(buf, "Message"), XS_Mob_Message, file, "$$$;@"); + newXSproto(strcpy(buf, "Message_StringID"), XS_Mob_Message_StringID, file, "$$$;$"); + newXSproto(strcpy(buf, "Say"), XS_Mob_Say, file, "$$;@"); + newXSproto(strcpy(buf, "Shout"), XS_Mob_Shout, file, "$$;@"); + newXSproto(strcpy(buf, "Emote"), XS_Mob_Emote, file, "$$;@"); + newXSproto(strcpy(buf, "InterruptSpell"), XS_Mob_InterruptSpell, file, "$;$"); + newXSproto(strcpy(buf, "CastSpell"), XS_Mob_CastSpell, file, "$$$;$$$"); + newXSproto(strcpy(buf, "SpellFinished"), XS_Mob_SpellFinished, file, "$$;$$"); + newXSproto(strcpy(buf, "IsImmuneToSpell"), XS_Mob_IsImmuneToSpell, file, "$$$"); + newXSproto(strcpy(buf, "BuffFadeBySpellID"), XS_Mob_BuffFadeBySpellID, file, "$$"); + newXSproto(strcpy(buf, "BuffFadeByEffect"), XS_Mob_BuffFadeByEffect, file, "$$;$"); + newXSproto(strcpy(buf, "BuffFadeAll"), XS_Mob_BuffFadeAll, file, "$"); + newXSproto(strcpy(buf, "BuffFadeBySlot"), XS_Mob_BuffFadeBySlot, file, "$$;$"); + newXSproto(strcpy(buf, "CanBuffStack"), XS_Mob_CanBuffStack, file, "$$$;$"); + newXSproto(strcpy(buf, "IsCasting"), XS_Mob_IsCasting, file, "$"); + newXSproto(strcpy(buf, "CastingSpellID"), XS_Mob_CastingSpellID, file, "$"); + newXSproto(strcpy(buf, "SetAppearance"), XS_Mob_SetAppearance, file, "$$;$"); + newXSproto(strcpy(buf, "GetAppearance"), XS_Mob_GetAppearance, file, "$"); + newXSproto(strcpy(buf, "GetRunAnimSpeed"), XS_Mob_GetRunAnimSpeed, file, "$"); + newXSproto(strcpy(buf, "SetRunAnimSpeed"), XS_Mob_SetRunAnimSpeed, file, "$$"); + newXSproto(strcpy(buf, "SetPetID"), XS_Mob_SetPetID, file, "$$"); + newXSproto(strcpy(buf, "GetPetID"), XS_Mob_GetPetID, file, "$"); + newXSproto(strcpy(buf, "SetOwnerID"), XS_Mob_SetOwnerID, file, "$$"); + newXSproto(strcpy(buf, "GetOwnerID"), XS_Mob_GetOwnerID, file, "$"); + newXSproto(strcpy(buf, "GetPetType"), XS_Mob_GetPetType, file, "$"); + newXSproto(strcpy(buf, "GetBodyType"), XS_Mob_GetBodyType, file, "$"); + newXSproto(strcpy(buf, "Stun"), XS_Mob_Stun, file, "$$"); + newXSproto(strcpy(buf, "Spin"), XS_Mob_Spin, file, "$"); + newXSproto(strcpy(buf, "Kill"), XS_Mob_Kill, file, "$"); + newXSproto(strcpy(buf, "SetInvul"), XS_Mob_SetInvul, file, "$$"); + newXSproto(strcpy(buf, "GetInvul"), XS_Mob_GetInvul, file, "$"); + newXSproto(strcpy(buf, "SetExtraHaste"), XS_Mob_SetExtraHaste, file, "$$"); + newXSproto(strcpy(buf, "GetHaste"), XS_Mob_GetHaste, file, "$"); + newXSproto(strcpy(buf, "GetHandToHandDamage"), XS_Mob_GetHandToHandDamage, file, "$"); + newXSproto(strcpy(buf, "CanThisClassDoubleAttack"), XS_Mob_CanThisClassDoubleAttack, file, "$"); + newXSproto(strcpy(buf, "CanThisClassDualWield"), XS_Mob_CanThisClassDualWield, file, "$"); + newXSproto(strcpy(buf, "CanThisClassRiposte"), XS_Mob_CanThisClassRiposte, file, "$"); + newXSproto(strcpy(buf, "CanThisClassDodge"), XS_Mob_CanThisClassDodge, file, "$"); + newXSproto(strcpy(buf, "CanThisClassParry"), XS_Mob_CanThisClassParry, file, "$"); + newXSproto(strcpy(buf, "GetHandToHandDelay"), XS_Mob_GetHandToHandDelay, file, "$"); + newXSproto(strcpy(buf, "GetClassLevelFactor"), XS_Mob_GetClassLevelFactor, file, "$"); + newXSproto(strcpy(buf, "Mesmerize"), XS_Mob_Mesmerize, file, "$"); + newXSproto(strcpy(buf, "IsMezzed"), XS_Mob_IsMezzed, file, "$"); + newXSproto(strcpy(buf, "IsStunned"), XS_Mob_IsStunned, file, "$"); + newXSproto(strcpy(buf, "StartEnrage"), XS_Mob_StartEnrage, file, "$"); + newXSproto(strcpy(buf, "IsEnraged"), XS_Mob_IsEnraged, file, "$"); + newXSproto(strcpy(buf, "GetReverseFactionCon"), XS_Mob_GetReverseFactionCon, file, "$$"); + newXSproto(strcpy(buf, "IsAIControlled"), XS_Mob_IsAIControlled, file, "$"); + newXSproto(strcpy(buf, "GetAggroRange"), XS_Mob_GetAggroRange, file, "$"); + newXSproto(strcpy(buf, "GetAssistRange"), XS_Mob_GetAssistRange, file, "$"); + newXSproto(strcpy(buf, "SetPetOrder"), XS_Mob_SetPetOrder, file, "$$"); + newXSproto(strcpy(buf, "GetPetOrder"), XS_Mob_GetPetOrder, file, "$"); + newXSproto(strcpy(buf, "IsRoamer"), XS_Mob_IsRoamer, file, "$"); + newXSproto(strcpy(buf, "IsRooted"), XS_Mob_IsRooted, file, "$"); + newXSproto(strcpy(buf, "AddToHateList"), XS_Mob_AddToHateList, file, "$$;$$$$$"); + newXSproto(strcpy(buf, "SetHate"), XS_Mob_SetHate, file, "$$;$$"); + newXSproto(strcpy(buf, "HalveAggro"), XS_Mob_HalveAggro, file, "$$"); + newXSproto(strcpy(buf, "DoubleAggro"), XS_Mob_DoubleAggro, file, "$$"); + newXSproto(strcpy(buf, "GetHateAmount"), XS_Mob_GetHateAmount, file, "$$;$"); + newXSproto(strcpy(buf, "GetDamageAmount"), XS_Mob_GetDamageAmount, file, "$$"); + newXSproto(strcpy(buf, "GetHateTop"), XS_Mob_GetHateTop, file, "$"); + newXSproto(strcpy(buf, "GetHateDamageTop"), XS_Mob_GetHateDamageTop, file, "$$"); + newXSproto(strcpy(buf, "GetHateRandom"), XS_Mob_GetHateRandom, file, "$"); + newXSproto(strcpy(buf, "IsEngaged"), XS_Mob_IsEngaged, file, "$"); + newXSproto(strcpy(buf, "HateSummon"), XS_Mob_HateSummon, file, "$"); + newXSproto(strcpy(buf, "FaceTarget"), XS_Mob_FaceTarget, file, "$;$$"); + newXSproto(strcpy(buf, "SetHeading"), XS_Mob_SetHeading, file, "$$"); + newXSproto(strcpy(buf, "WipeHateList"), XS_Mob_WipeHateList, file, "$"); + newXSproto(strcpy(buf, "CheckAggro"), XS_Mob_CheckAggro, file, "$$"); + newXSproto(strcpy(buf, "CalculateHeadingToTarget"), XS_Mob_CalculateHeadingToTarget, file, "$$$"); + newXSproto(strcpy(buf, "CalculateNewPosition"), XS_Mob_CalculateNewPosition, file, "$$$$$;$"); + newXSproto(strcpy(buf, "CalculateDistance"), XS_Mob_CalculateDistance, file, "$$$$"); + newXSproto(strcpy(buf, "SendTo"), XS_Mob_SendTo, file, "$$$$"); + newXSproto(strcpy(buf, "SendToFixZ"), XS_Mob_SendToFixZ, file, "$$$$"); + newXSproto(strcpy(buf, "NPCSpecialAttacks"), XS_Mob_NPCSpecialAttacks, file, "$$$;$$"); + newXSproto(strcpy(buf, "DontHealMeBefore"), XS_Mob_DontHealMeBefore, file, "$"); + newXSproto(strcpy(buf, "DontBuffMeBefore"), XS_Mob_DontBuffMeBefore, file, "$"); + newXSproto(strcpy(buf, "DontDotMeBefore"), XS_Mob_DontDotMeBefore, file, "$"); + newXSproto(strcpy(buf, "DontRootMeBefore"), XS_Mob_DontRootMeBefore, file, "$"); + newXSproto(strcpy(buf, "DontSnareMeBefore"), XS_Mob_DontSnareMeBefore, file, "$"); + newXSproto(strcpy(buf, "GetResist"), XS_Mob_GetResist, file, "$$"); + newXSproto(strcpy(buf, "GetShieldTarget"), XS_Mob_GetShieldTarget, file, "$"); + newXSproto(strcpy(buf, "SetShieldTarget"), XS_Mob_SetShieldTarget, file, "$$"); + newXSproto(strcpy(buf, "Charmed"), XS_Mob_Charmed, file, "$"); + newXSproto(strcpy(buf, "GetLevelHP"), XS_Mob_GetLevelHP, file, "$$"); + newXSproto(strcpy(buf, "GetZoneID"), XS_Mob_GetZoneID, file, "$"); + newXSproto(strcpy(buf, "CheckAggroAmount"), XS_Mob_CheckAggroAmount, file, "$$"); + newXSproto(strcpy(buf, "CheckHealAggroAmount"), XS_Mob_CheckHealAggroAmount, file, "$$"); + newXSproto(strcpy(buf, "GetAA"), XS_Mob_GetAA, file, "$$"); + newXSproto(strcpy(buf, "GetAAByAAID"), XS_Mob_GetAAByAAID, file, "$$"); + newXSproto(strcpy(buf, "SetAA"), XS_Mob_SetAA, file, "$$$;$"); + newXSproto(strcpy(buf, "DivineAura"), XS_Mob_DivineAura, file, "$"); + newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$"); + newXSproto(strcpy(buf, "RemoveFromFeignMemory"), XS_Mob_RemoveFromFeignMemory, file, "$$"); + newXSproto(strcpy(buf, "ClearFeignMemory"), XS_Mob_ClearFeignMemory, file, "$"); + newXSproto(strcpy(buf, "SetOOCRegen"), XS_Mob_SetOOCRegen, file, "$$"); + newXSproto(strcpy(buf, "GetEntityVariable"), XS_Mob_GetEntityVariable, file, "$$"); + newXSproto(strcpy(buf, "SetEntityVariable"), XS_Mob_SetEntityVariable, file, "$$$"); + newXSproto(strcpy(buf, "EntityVariableExists"), XS_Mob_EntityVariableExists, file, "$$"); + newXSproto(strcpy(buf, "GetHateList"), XS_Mob_GetHateList, file, "$"); + newXSproto(strcpy(buf, "SignalClient"), XS_Mob_SignalClient, file, "$$$"); + newXSproto(strcpy(buf, "CombatRange"), XS_Mob_CombatRange, file, "$$"); + newXSproto(strcpy(buf, "DoSpecialAttackDamage"), XS_Mob_DoSpecialAttackDamage, file, "$$$$;$$"); + newXSproto(strcpy(buf, "CheckLoS"), XS_Mob_CheckLoS, file, "$$"); + newXSproto(strcpy(buf, "CheckLoSToLoc"), XS_Mob_CheckLoSToLoc, file, "$$$$;$"); + newXSproto(strcpy(buf, "FindGroundZ"), XS_Mob_FindGroundZ, file, "$$$;$"); + newXSproto(strcpy(buf, "ProjectileAnim"), XS_Mob_ProjectileAnim, file, "$$$;$$$$$$"); + newXSproto(strcpy(buf, "HasNPCSpecialAtk"), XS_Mob_HasNPCSpecialAtk, file, "$$"); + newXSproto(strcpy(buf, "SendAppearanceEffect"), XS_Mob_SendAppearanceEffect, file, "$$;$$$$"); + newXSproto(strcpy(buf, "SetFlyMode"), XS_Mob_SetFlyMode, file, "$$"); + newXSproto(strcpy(buf, "SetTexture"), XS_Mob_SetTexture, file, "$$"); + newXSproto(strcpy(buf, "SetRace"), XS_Mob_SetRace, file, "$$"); + newXSproto(strcpy(buf, "SetGender"), XS_Mob_SetGender, file, "$$"); + newXSproto(strcpy(buf, "SendIllusion"), XS_Mob_SendIllusion, file, "$$;$$$$$$$$$$$$"); + newXSproto(strcpy(buf, "MakeTempPet"), XS_Mob_MakeTempPet, file, "$$;$$$$"); + newXSproto(strcpy(buf, "TypesTempPet"), XS_Mob_TypesTempPet, file, "$$;$$$$$"); + newXSproto(strcpy(buf, "CameraEffect"), XS_Mob_CameraEffect, file, "$$;$$$"); + newXSproto(strcpy(buf, "SpellEffect"), XS_Mob_SpellEffect, file, "$$;$$$$$$"); + newXSproto(strcpy(buf, "TempName"), XS_Mob_TempName, file, "$:$"); + newXSproto(strcpy(buf, "GetItemStat"), XS_Mob_GetItemStat, file, "$$$"); + newXSproto(strcpy(buf, "GetGlobal"), XS_Mob_GetGlobal, file, "$$"); + newXSproto(strcpy(buf, "SetGlobal"), XS_Mob_SetGlobal, file, "$$$$$;$"); + newXSproto(strcpy(buf, "TarGlobal"), XS_Mob_TarGlobal, file, "$$$$$$$"); + newXSproto(strcpy(buf, "DelGlobal"), XS_Mob_DelGlobal, file, "$$"); + newXSproto(strcpy(buf, "SetSlotTint"), XS_Mob_SetSlotTint, file, "$$$$$"); + newXSproto(strcpy(buf, "WearChange"), XS_Mob_WearChange, file, "$$$;$$"); + newXSproto(strcpy(buf, "DoKnockback"), XS_Mob_DoKnockback, file, "$$$$"); + newXSproto(strcpy(buf, "RemoveNimbusEffect"), XS_Mob_RemoveNimbusEffect, file, "$$"); + newXSproto(strcpy(buf, "IsRunning"), XS_Mob_IsRunning, file, "$"); + newXSproto(strcpy(buf, "SetRunning"), XS_Mob_SetRunning, file, "$$"); + newXSproto(strcpy(buf, "SetBodyType"), XS_Mob_SetBodyType, file, "$$;$"); + newXSproto(strcpy(buf, "SetDeltas"), XS_Mob_SetDeltas, file, "$$$$$"); + newXSproto(strcpy(buf, "SetLD"), XS_Mob_SetLD, file, "$$"); + newXSproto(strcpy(buf, "SetTargetDestSteps"), XS_Mob_SetTargetDestSteps, file, "$$"); + newXSproto(strcpy(buf, "SetTargetable"), XS_Mob_SetTargetable, file, "$$"); + newXSproto(strcpy(buf, "MakeTempPet"), XS_Mob_MakeTempPet, file, "$$;$$$$"); + newXSproto(strcpy(buf, "ModSkillDmgTaken"), XS_Mob_ModSkillDmgTaken, file, "$$$"); + newXSproto(strcpy(buf, "GetModSkillDmgTaken"), XS_Mob_GetModSkillDmgTaken, file, "$$"); + newXSproto(strcpy(buf, "GetSkillDmgTaken"), XS_Mob_GetSkillDmgTaken, file, "$$"); + newXSproto(strcpy(buf, "SetAllowBeneficial"), XS_Mob_SetAllowBeneficial, file, "$$"); + newXSproto(strcpy(buf, "GetAllowBeneficial"), XS_Mob_GetAllowBeneficial, file, "$$"); + newXSproto(strcpy(buf, "IsBeneficialAllowed"), XS_Mob_IsBeneficialAllowed, file, "$$"); + newXSproto(strcpy(buf, "ModVulnerability"), XS_Mob_ModVulnerability, file, "$$$"); + newXSproto(strcpy(buf, "GetModVulnerability"), XS_Mob_GetModVulnerability, file, "$$"); + newXSproto(strcpy(buf, "DoMeleeSkillAttackDmg"), XS_Mob_DoMeleeSkillAttackDmg, file, "$$$$$$$"); + newXSproto(strcpy(buf, "DoArcheryAttackDmg"), XS_Mob_DoArcheryAttackDmg, file, "$$$$$$$"); + newXSproto(strcpy(buf, "DoThrowingAttackDmg"), XS_Mob_DoThrowingAttackDmg, file, "$$$$$$$"); + newXSproto(strcpy(buf, "SetDisableMelee"), XS_Mob_SetDisableMelee, file, "$$"); + newXSproto(strcpy(buf, "IsMeleeDisabled"), XS_Mob_IsMeleeDisabled, file, "$"); + newXSproto(strcpy(buf, "SetFlurryChance"), XS_Mob_SetFlurryChance, file, "$$"); + newXSproto(strcpy(buf, "GetFlurryChance"), XS_Mob_GetFlurryChance, file, "$"); + newXSproto(strcpy(buf, "GetSpellStat"), XS_Mob_GetSpellStat, file, "$$$$"); + newXSproto(strcpy(buf, "GetSpecialAbility"), XS_Mob_GetSpecialAbility, file, "$$"); + newXSproto(strcpy(buf, "GetSpecialAbilityParam"), XS_Mob_GetSpecialAbilityParam, file, "$$$"); + newXSproto(strcpy(buf, "SetSpecialAbility"), XS_Mob_SetSpecialAbility, file, "$$$"); + newXSproto(strcpy(buf, "SetSpecialAbilityParam"), XS_Mob_SetSpecialAbilityParam, file, "$$$$"); + newXSproto(strcpy(buf, "ClearSpecialAbilities"), XS_Mob_ClearSpecialAbilities, file, "$"); + newXSproto(strcpy(buf, "ProcessSpecialAbilities"), XS_Mob_ProcessSpecialAbilities, file, "$$"); + newXSproto(strcpy(buf, "CanClassEquipItem"), XS_Mob_CanClassEquipItem, file, "$$"); + newXSproto(strcpy(buf, "IsFeared"), XS_Mob_IsFeared, file, "$"); + newXSproto(strcpy(buf, "IsBlind"), XS_Mob_IsBlind, file, "$"); + newXSproto(strcpy(buf, "SeeInvisible"), XS_Mob_SeeInvisible, file, "$"); + newXSproto(strcpy(buf, "SeeInvisibleUndead"), XS_Mob_SeeInvisibleUndead, file, "$"); + newXSproto(strcpy(buf, "SeeHide"), XS_Mob_SeeHide, file, "$"); + newXSproto(strcpy(buf, "SeeImprovedHide"), XS_Mob_SeeImprovedHide, file, "$"); + newXSproto(strcpy(buf, "GetNimbusEffect1"), XS_Mob_GetNimbusEffect1, file, "$"); + newXSproto(strcpy(buf, "GetNimbusEffect2"), XS_Mob_GetNimbusEffect2, file, "$"); + newXSproto(strcpy(buf, "GetNimbusEffect3"), XS_Mob_GetNimbusEffect3, file, "$"); + newXSproto(strcpy(buf, "IsTargetable"), XS_Mob_IsTargetable, file, "$"); + newXSproto(strcpy(buf, "HasShieldEquiped"), XS_Mob_HasShieldEquiped, file, "$"); + newXSproto(strcpy(buf, "HasTwoHandBluntEquiped"), XS_Mob_HasTwoHandBluntEquiped, file, "$"); + newXSproto(strcpy(buf, "HasTwoHanderEquipped"), XS_Mob_HasTwoHanderEquipped, file, "$"); + newXSproto(strcpy(buf, "GetHerosForgeModel"), XS_Mob_GetHerosForgeModel, file, "$$"); + newXSproto(strcpy(buf, "IsEliteMaterialItem"), XS_Mob_IsEliteMaterialItem, file, "$$"); + newXSproto(strcpy(buf, "GetBaseSize"), XS_Mob_GetBaseSize, file, "$"); + newXSproto(strcpy(buf, "HasOwner"), XS_Mob_HasOwner, file, "$"); + newXSproto(strcpy(buf, "IsPet"), XS_Mob_IsPet, file, "$"); + newXSproto(strcpy(buf, "HasPet"), XS_Mob_HasPet, file, "$"); + newXSproto(strcpy(buf, "IsSilenced"), XS_Mob_IsSilenced, file, "$"); + newXSproto(strcpy(buf, "IsAmnesiad"), XS_Mob_IsAmnesiad, file, "$"); + newXSproto(strcpy(buf, "GetMeleeMitigation"), XS_Mob_GetMeleeMitigation, file, "$"); + newXSproto(strcpy(buf, "TryMoveAlong"), XS_Mob_TryMoveAlong, file, "$$$;$"); XSRETURN_YES; } diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index eef7b1717..1eaddf3a2 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -44,22 +46,20 @@ typedef const char Const_char; XS(XS_NPC_SignalNPC); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SignalNPC) -{ +XS(XS_NPC_SignalNPC) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SignalNPC(THIS, _signal_id)"); + Perl_croak(aTHX_ "Usage: NPC::SignalNPC(THIS, int signal_id)"); { - NPC * THIS; - int _signal_id = (int)SvIV(ST(1)); + NPC *THIS; + int _signal_id = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SignalNPC(_signal_id); @@ -68,75 +68,73 @@ XS(XS_NPC_SignalNPC) } XS(XS_NPC_CheckNPCFactionAlly); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_CheckNPCFactionAlly) -{ +XS(XS_NPC_CheckNPCFactionAlly) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::CheckNPCFactionAlly(THIS, other_faction)"); + Perl_croak(aTHX_ "Usage: NPC::CheckNPCFactionAlly(THIS, int32 faction_id)"); { - NPC * THIS; - FACTION_VALUE RETVAL; + NPC *THIS; + FACTION_VALUE RETVAL; dXSTARG; - int32 other_faction = (int32)SvIV(ST(1)); + int32 other_faction = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CheckNPCFactionAlly(other_faction); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_NPC_AddItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_AddItem) -{ +XS(XS_NPC_AddItem) { dXSARGS; if (items < 2 || items > 10) - Perl_croak(aTHX_ "Usage: NPC::AddItem(THIS, itemid, charges = 0, equipitem = true, aug1 = 0, aug2 = 0, aug3 = 0, aug4 = 0, aug5 = 0, aug6 = 0)"); + Perl_croak(aTHX_ + "Usage: NPC::AddItem(THIS, uint32 item_id, [uint16 charges = 0], [bool equip_item = true], [uint32 aug1 = 0], [uint32 aug2 = 0], [uint32 aug3 = 0], [uint32 aug4 = 0], [uint32 aug5 = 0], [uint32 aug6 = 0])"); { - NPC * THIS; - uint32 itemid = (uint32)SvUV(ST(1)); - uint16 charges = 0; - bool equipitem = true; - uint32 aug1 = 0; - uint32 aug2 = 0; - uint32 aug3 = 0; - uint32 aug4 = 0; - uint32 aug5 = 0; - uint32 aug6 = 0; + NPC *THIS; + uint32 itemid = (uint32) SvUV(ST(1)); + uint16 charges = 0; + bool equipitem = true; + uint32 aug1 = 0; + uint32 aug2 = 0; + uint32 aug3 = 0; + uint32 aug4 = 0; + uint32 aug5 = 0; + uint32 aug6 = 0; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items > 2) - charges = (uint16)SvUV(ST(2)); + charges = (uint16) SvUV(ST(2)); if (items > 3) - equipitem = (bool)SvTRUE(ST(3)); + equipitem = (bool) SvTRUE(ST(3)); if (items > 4) - aug1 = (uint32)SvUV(ST(4)); + aug1 = (uint32) SvUV(ST(4)); if (items > 5) - aug2 = (uint32)SvUV(ST(5)); + aug2 = (uint32) SvUV(ST(5)); if (items > 6) - aug3 = (uint32)SvUV(ST(6)); + aug3 = (uint32) SvUV(ST(6)); if (items > 7) - aug4 = (uint32)SvUV(ST(7)); + aug4 = (uint32) SvUV(ST(7)); if (items > 8) - aug5 = (uint32)SvUV(ST(8)); + aug5 = (uint32) SvUV(ST(8)); if (items > 9) - aug6 = (uint32)SvUV(ST(9)); + aug6 = (uint32) SvUV(ST(9)); THIS->AddItem(itemid, charges, equipitem, aug1, aug2, aug3, aug4, aug5, aug6); } @@ -144,32 +142,27 @@ XS(XS_NPC_AddItem) } XS(XS_NPC_AddLootTable); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_AddLootTable) -{ +XS(XS_NPC_AddLootTable) { dXSARGS; if (items < 1) - Perl_croak(aTHX_ "Usage: NPC::AddLootTable(THIS, [loottable_id])"); + Perl_croak(aTHX_ "Usage: NPC::AddLootTable(THIS, [uint32 loottable_id])"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); uint32 loottable_id = 0; - if(items > 1) - { - loottable_id = (uint32)SvUV(ST(1)); + if (items > 1) { + loottable_id = (uint32) SvUV(ST(1)); THIS->AddLootTable(loottable_id); - } - else - { + } else { THIS->AddLootTable(); } } @@ -177,36 +170,34 @@ XS(XS_NPC_AddLootTable) } XS(XS_NPC_RemoveItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_RemoveItem) -{ +XS(XS_NPC_RemoveItem) { dXSARGS; if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: NPC::RemoveItem(THIS, item_id, quantity= 0, slot= 0)"); + Perl_croak(aTHX_ "Usage: NPC::RemoveItem(THIS, uint32 item_id, [uint16 quantity = 0], [uint16 slot_id = 0])"); { - NPC * THIS; - uint32 item_id = (uint32)SvUV(ST(1)); - uint16 quantity; - uint16 slot; + NPC *THIS; + uint32 item_id = (uint32) SvUV(ST(1)); + uint16 quantity; + uint16 slot; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 3) quantity = 0; else { - quantity = (uint16)SvUV(ST(2)); + quantity = (uint16) SvUV(ST(2)); } if (items < 4) slot = 0; else { - slot = (uint16)SvUV(ST(3)); + slot = (uint16) SvUV(ST(3)); } THIS->RemoveItem(item_id, quantity, slot); @@ -215,21 +206,19 @@ XS(XS_NPC_RemoveItem) } XS(XS_NPC_ClearItemList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_ClearItemList) -{ +XS(XS_NPC_ClearItemList) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::ClearItemList(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearItemList(); @@ -238,25 +227,23 @@ XS(XS_NPC_ClearItemList) } XS(XS_NPC_AddCash); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_AddCash) -{ +XS(XS_NPC_AddCash) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: NPC::AddCash(THIS, in_copper, in_silver, in_gold, in_platinum)"); + Perl_croak(aTHX_ "Usage: NPC::AddCash(THIS, uint16 copper, uint16 silver, uint16 gold, uint16 platinum)"); { - NPC * THIS; - uint16 in_copper = (uint16)SvUV(ST(1)); - uint16 in_silver = (uint16)SvUV(ST(2)); - uint16 in_gold = (uint16)SvUV(ST(3)); - uint16 in_platinum = (uint16)SvUV(ST(4)); + NPC *THIS; + uint16 in_copper = (uint16) SvUV(ST(1)); + uint16 in_silver = (uint16) SvUV(ST(2)); + uint16 in_gold = (uint16) SvUV(ST(3)); + uint16 in_platinum = (uint16) SvUV(ST(4)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddCash(in_copper, in_silver, in_gold, in_platinum); @@ -265,21 +252,19 @@ XS(XS_NPC_AddCash) } XS(XS_NPC_RemoveCash); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_RemoveCash) -{ +XS(XS_NPC_RemoveCash) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::RemoveCash(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveCash(); @@ -288,178 +273,170 @@ XS(XS_NPC_RemoveCash) } XS(XS_NPC_CountLoot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_CountLoot) -{ +XS(XS_NPC_CountLoot) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::CountLoot(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CountLoot(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetLoottableID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetLoottableID) -{ +XS(XS_NPC_GetLoottableID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetLoottableID(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLoottableID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetCopper); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetCopper) -{ +XS(XS_NPC_GetCopper) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetCopper(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCopper(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSilver); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSilver) -{ +XS(XS_NPC_GetSilver) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSilver(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSilver(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetGold); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetGold) -{ +XS(XS_NPC_GetGold) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetGold(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGold(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetPlatinum); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetPlatinum) -{ +XS(XS_NPC_GetPlatinum) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetPlatinum(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPlatinum(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_SetCopper); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetCopper) -{ +XS(XS_NPC_SetCopper) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetCopper(THIS, amt)"); + Perl_croak(aTHX_ "Usage: NPC::SetCopper(THIS, uint32 copper_amount)"); { - NPC * THIS; - uint32 amt = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 amt = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetCopper(amt); @@ -468,22 +445,20 @@ XS(XS_NPC_SetCopper) } XS(XS_NPC_SetSilver); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSilver) -{ +XS(XS_NPC_SetSilver) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSilver(THIS, amt)"); + Perl_croak(aTHX_ "Usage: NPC::SetSilver(THIS, uint32 silver_amount)"); { - NPC * THIS; - uint32 amt = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 amt = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSilver(amt); @@ -492,22 +467,20 @@ XS(XS_NPC_SetSilver) } XS(XS_NPC_SetGold); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetGold) -{ +XS(XS_NPC_SetGold) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetGold(THIS, amt)"); + Perl_croak(aTHX_ "Usage: NPC::SetGold(THIS, uint32 gold_amount)"); { - NPC * THIS; - uint32 amt = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 amt = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetGold(amt); @@ -516,22 +489,20 @@ XS(XS_NPC_SetGold) } XS(XS_NPC_SetPlatinum); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetPlatinum) -{ +XS(XS_NPC_SetPlatinum) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetPlatinum(THIS, amt)"); + Perl_croak(aTHX_ "Usage: NPC::SetPlatinum(THIS, uint32 platinum_amount)"); { - NPC * THIS; - uint32 amt = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 amt = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetPlatinum(amt); @@ -540,22 +511,20 @@ XS(XS_NPC_SetPlatinum) } XS(XS_NPC_SetGrid); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetGrid) -{ +XS(XS_NPC_SetGrid) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetGrid(THIS, grid_)"); + Perl_croak(aTHX_ "Usage: NPC::SetGrid(THIS, int32 grid_id)"); { - NPC * THIS; - int32 grid_ = (int32)SvIV(ST(1)); + NPC *THIS; + int32 grid_ = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetGrid(grid_); @@ -564,22 +533,20 @@ XS(XS_NPC_SetGrid) } XS(XS_NPC_SetSaveWaypoint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSaveWaypoint) -{ +XS(XS_NPC_SetSaveWaypoint) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSaveWaypoint(THIS, waypoint)"); + Perl_croak(aTHX_ "Usage: NPC::SetSaveWaypoint(THIS, uint16 waypoint)"); { - NPC * THIS; - uint16 waypoint = (uint16)SvUV(ST(1)); + NPC *THIS; + uint16 waypoint = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSaveWaypoint(waypoint); @@ -588,22 +555,20 @@ XS(XS_NPC_SetSaveWaypoint) } XS(XS_NPC_SetSp2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSp2) -{ +XS(XS_NPC_SetSp2) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSp2(THIS, sg2)"); + Perl_croak(aTHX_ "Usage: NPC::SetSp2(THIS, uint32 set_spawn_group_id)"); { - NPC * THIS; - uint32 sg2 = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 sg2 = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSp2(sg2); @@ -612,198 +577,188 @@ XS(XS_NPC_SetSp2) } XS(XS_NPC_GetWaypointMax); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetWaypointMax) -{ +XS(XS_NPC_GetWaypointMax) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetWaypointMax(THIS)"); { - NPC * THIS; - uint16 RETVAL; + NPC *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetWaypointMax(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetGrid); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetGrid) -{ +XS(XS_NPC_GetGrid) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetGrid(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGrid(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSp2); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSp2) -{ +XS(XS_NPC_GetSp2) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSp2(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSp2(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetNPCFactionID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetNPCFactionID) -{ +XS(XS_NPC_GetNPCFactionID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetNPCFactionID(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetNPCFactionID(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetPrimaryFaction); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetPrimaryFaction) -{ +XS(XS_NPC_GetPrimaryFaction) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetPrimaryFaction(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPrimaryFaction(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetNPCHate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetNPCHate) -{ +XS(XS_NPC_GetNPCHate) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::GetNPCHate(THIS, in_ent)"); + Perl_croak(aTHX_ "Usage: NPC::GetNPCHate(THIS, Mob* entity)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; - Mob* in_ent; + Mob *in_ent; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - in_ent = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + in_ent = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "in_ent is not of type Mob"); - if(in_ent == nullptr) + if (in_ent == nullptr) Perl_croak(aTHX_ "in_ent is nullptr, avoiding crash."); RETVAL = THIS->GetNPCHate(in_ent); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_NPC_IsOnHatelist); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_IsOnHatelist) -{ +XS(XS_NPC_IsOnHatelist) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::IsOnHatelist(THIS, p)"); + Perl_croak(aTHX_ "Usage: NPC::IsOnHatelist(THIS, Mob* target)"); { - NPC * THIS; - bool RETVAL; - Mob* p; + NPC *THIS; + bool RETVAL; + Mob *p; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - p = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + p = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "p is not of type Mob"); - if(p == nullptr) + if (p == nullptr) Perl_croak(aTHX_ "p is nullptr, avoiding crash."); RETVAL = THIS->IsOnHatelist(p); @@ -814,31 +769,28 @@ XS(XS_NPC_IsOnHatelist) } XS(XS_NPC_RemoveFromHateList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_RemoveFromHateList) -{ +XS(XS_NPC_RemoveFromHateList) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::RemoveFromHateList(THIS, ent)"); + Perl_croak(aTHX_ "Usage: NPC::RemoveFromHateList(THIS, Mob* target)"); { - NPC * THIS; - Mob* ent; + NPC *THIS; + Mob *ent; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - ent = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + ent = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "ent is not of type Mob"); - if(ent == nullptr) + if (ent == nullptr) Perl_croak(aTHX_ "ent is nullptr, avoiding crash."); THIS->RemoveFromHateList(ent); @@ -848,24 +800,21 @@ XS(XS_NPC_RemoveFromHateList) } - XS(XS_NPC_SetNPCFactionID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetNPCFactionID) -{ +XS(XS_NPC_SetNPCFactionID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetNPCFactionID(THIS, in)"); + Perl_croak(aTHX_ "Usage: NPC::SetNPCFactionID(THIS, int32 faction_id)"); { - NPC * THIS; - int32 in = (int32)SvIV(ST(1)); + NPC *THIS; + int32 in = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetNPCFactionID(in); @@ -874,75 +823,71 @@ XS(XS_NPC_SetNPCFactionID) } XS(XS_NPC_GetMaxDMG); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetMaxDMG) -{ +XS(XS_NPC_GetMaxDMG) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetMaxDMG(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxDMG(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetMinDMG); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetMinDMG) -{ +XS(XS_NPC_GetMinDMG) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetMinDMG(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMinDMG(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_IsAnimal); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_IsAnimal) -{ +XS(XS_NPC_IsAnimal) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::IsAnimal(THIS)"); { - NPC * THIS; - bool RETVAL; + NPC *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsAnimal(); @@ -953,48 +898,45 @@ XS(XS_NPC_IsAnimal) } XS(XS_NPC_GetPetSpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetPetSpellID) -{ +XS(XS_NPC_GetPetSpellID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetPetSpellID(THIS)"); { - NPC * THIS; - uint16 RETVAL; + NPC *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPetSpellID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_SetPetSpellID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetPetSpellID) -{ +XS(XS_NPC_SetPetSpellID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetPetSpellID(THIS, amt)"); + Perl_croak(aTHX_ "Usage: NPC::SetPetSpellID(THIS, uint16 amount)"); { - NPC * THIS; - uint16 amt = (uint16)SvUV(ST(1)); + NPC *THIS; + uint16 amt = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetPetSpellID(amt); @@ -1003,82 +945,76 @@ XS(XS_NPC_SetPetSpellID) } XS(XS_NPC_GetMaxDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetMaxDamage) -{ +XS(XS_NPC_GetMaxDamage) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::GetMaxDamage(THIS, tlevel)"); + Perl_croak(aTHX_ "Usage: NPC::GetMaxDamage(THIS, uint8 target_level)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; - uint8 tlevel = (uint8)SvUV(ST(1)); + uint8 tlevel = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxDamage(tlevel); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_SetTaunting); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetTaunting) -{ +XS(XS_NPC_SetTaunting) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetTaunting(THIS, tog)"); + Perl_croak(aTHX_ "Usage: NPC::SetTaunting(THIS, bool toggle)"); { - NPC * THIS; - bool tog = (bool)SvTRUE(ST(1)); + NPC *THIS; + bool toggle = (bool) SvTRUE(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetTaunting(tog); + THIS->SetTaunting(toggle); } XSRETURN_EMPTY; } XS(XS_NPC_PickPocket); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_PickPocket) -{ +XS(XS_NPC_PickPocket) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::PickPocket(THIS, thief)"); + Perl_croak(aTHX_ "Usage: NPC::PickPocket(THIS, Client* thief)"); { - NPC * THIS; - Client* thief; + NPC *THIS; + Client *thief; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - thief = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + thief = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "thief is not of type Client"); - if(thief == nullptr) + if (thief == nullptr) Perl_croak(aTHX_ "thief is nullptr, avoiding crash."); THIS->PickPocket(thief); @@ -1087,22 +1023,20 @@ XS(XS_NPC_PickPocket) } XS(XS_NPC_StartSwarmTimer); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_StartSwarmTimer) -{ +XS(XS_NPC_StartSwarmTimer) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::StartSwarmTimer(THIS, duration)"); + Perl_croak(aTHX_ "Usage: NPC::StartSwarmTimer(THIS, uint32 duration)"); { - NPC * THIS; - uint32 duration = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 duration = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->StartSwarmTimer(duration); @@ -1111,31 +1045,28 @@ XS(XS_NPC_StartSwarmTimer) } XS(XS_NPC_DoClassAttacks); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_DoClassAttacks) -{ +XS(XS_NPC_DoClassAttacks) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::DoClassAttacks(THIS, target)"); + Perl_croak(aTHX_ "Usage: NPC::DoClassAttacks(THIS, Mob* target)"); { - NPC * THIS; - Mob * target; + NPC *THIS; + Mob *target; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - target = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + target = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "target is not of type Mob"); - if(target == nullptr) + if (target == nullptr) Perl_croak(aTHX_ "target is nullptr, avoiding crash."); THIS->DoClassAttacks(target); @@ -1144,57 +1075,53 @@ XS(XS_NPC_DoClassAttacks) } XS(XS_NPC_GetMaxWp); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetMaxWp) -{ +XS(XS_NPC_GetMaxWp) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetMaxWp(THIS)"); { - NPC * THIS; - int RETVAL; + NPC *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetMaxWp(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_NPC_DisplayWaypointInfo); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_DisplayWaypointInfo) -{ +XS(XS_NPC_DisplayWaypointInfo) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::DisplayWaypointInfo(THIS, to)"); + Perl_croak(aTHX_ "Usage: NPC::DisplayWaypointInfo(THIS, Client* target)"); { - NPC * THIS; - Client * to; + NPC *THIS; + Client *to; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - to = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + to = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "to is not of type Client"); - if(to == nullptr) + if (to == nullptr) Perl_croak(aTHX_ "to is nullptr, avoiding crash."); THIS->DisplayWaypointInfo(to); @@ -1203,21 +1130,19 @@ XS(XS_NPC_DisplayWaypointInfo) } XS(XS_NPC_CalculateNewWaypoint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_CalculateNewWaypoint) -{ +XS(XS_NPC_CalculateNewWaypoint) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::CalculateNewWaypoint(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->CalculateNewWaypoint(); @@ -1226,22 +1151,20 @@ XS(XS_NPC_CalculateNewWaypoint) } XS(XS_NPC_AssignWaypoints); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_AssignWaypoints) -{ +XS(XS_NPC_AssignWaypoints) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::AssignWaypoints(THIS, grid)"); + Perl_croak(aTHX_ "Usage: NPC::AssignWaypoints(THIS, uint32 grid_id)"); { - NPC * THIS; - uint32 grid = (uint32)SvUV(ST(1)); + NPC *THIS; + uint32 grid = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AssignWaypoints(grid); @@ -1250,21 +1173,19 @@ XS(XS_NPC_AssignWaypoints) } XS(XS_NPC_SetWaypointPause); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetWaypointPause) -{ +XS(XS_NPC_SetWaypointPause) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::SetWaypointPause(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetWaypointPause(); @@ -1273,22 +1194,20 @@ XS(XS_NPC_SetWaypointPause) } XS(XS_NPC_UpdateWaypoint); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_UpdateWaypoint) -{ +XS(XS_NPC_UpdateWaypoint) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::UpdateWaypoint(THIS, wp_index)"); + Perl_croak(aTHX_ "Usage: NPC::UpdateWaypoint(THIS, int wp_index)"); { - NPC * THIS; - int wp_index = (int)SvIV(ST(1)); + NPC *THIS; + int wp_index = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->UpdateWaypoint(wp_index); @@ -1297,21 +1216,19 @@ XS(XS_NPC_UpdateWaypoint) } XS(XS_NPC_StopWandering); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_StopWandering) -{ +XS(XS_NPC_StopWandering) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::StopWandering(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->StopWandering(); @@ -1320,21 +1237,19 @@ XS(XS_NPC_StopWandering) } XS(XS_NPC_ResumeWandering); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_ResumeWandering) -{ +XS(XS_NPC_ResumeWandering) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::ResumeWandering(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ResumeWandering(); @@ -1343,22 +1258,20 @@ XS(XS_NPC_ResumeWandering) } XS(XS_NPC_PauseWandering); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_PauseWandering) -{ +XS(XS_NPC_PauseWandering) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::PauseWandering(THIS, pausetime)"); + Perl_croak(aTHX_ "Usage: NPC::PauseWandering(THIS, int pause_time)"); { - NPC * THIS; - int pausetime = (int)SvIV(ST(1)); + NPC *THIS; + int pausetime = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->PauseWandering(pausetime); @@ -1367,60 +1280,57 @@ XS(XS_NPC_PauseWandering) } XS(XS_NPC_MoveTo); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_MoveTo) -{ +XS(XS_NPC_MoveTo) { dXSARGS; if (items != 4 && items != 5 && items != 6) - Perl_croak(aTHX_ "Usage: NPC::MoveTo(THIS, mtx, mty, mtz, [mth, saveguard?])"); + Perl_croak(aTHX_ + "Usage: NPC::MoveTo(THIS, float x, float y, float z, [float heading], [bool save_guard_location = false])"); { - NPC * THIS; - float mtx = (float)SvNV(ST(1)); - float mty = (float)SvNV(ST(2)); - float mtz = (float)SvNV(ST(3)); - float mth; - bool saveguard; + NPC *THIS; + float mtx = (float) SvNV(ST(1)); + float mty = (float) SvNV(ST(2)); + float mtz = (float) SvNV(ST(3)); + float mth; + bool saveguard; - if(items > 4) - mth = (float)SvNV(ST(4)); + if (items > 4) + mth = (float) SvNV(ST(4)); else mth = 0; - if(items > 5) - saveguard = (bool)SvTRUE(ST(5)); + if (items > 5) + saveguard = (bool) SvTRUE(ST(5)); else saveguard = false; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - auto position = glm::vec4(mtx, mty, mtz, mth); + auto position = glm::vec4(mtx, mty, mtz, mth); THIS->MoveTo(position, saveguard); } XSRETURN_EMPTY; } XS(XS_NPC_NextGuardPosition); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_NextGuardPosition) -{ +XS(XS_NPC_NextGuardPosition) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::NextGuardPosition(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->NextGuardPosition(); @@ -1429,28 +1339,26 @@ XS(XS_NPC_NextGuardPosition) } XS(XS_NPC_SaveGuardSpot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SaveGuardSpot) -{ +XS(XS_NPC_SaveGuardSpot) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: NPC::SaveGuardSpot(THIS, iClearGuardSpot= false)"); + Perl_croak(aTHX_ "Usage: NPC::SaveGuardSpot(THIS, [bool clear_guard_spot = false])"); { - NPC * THIS; - bool iClearGuardSpot; + NPC *THIS; + bool iClearGuardSpot; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) iClearGuardSpot = false; else { - iClearGuardSpot = (bool)SvTRUE(ST(1)); + iClearGuardSpot = (bool) SvTRUE(ST(1)); } THIS->SaveGuardSpot(iClearGuardSpot); @@ -1459,22 +1367,20 @@ XS(XS_NPC_SaveGuardSpot) } XS(XS_NPC_IsGuarding); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_IsGuarding) -{ +XS(XS_NPC_IsGuarding) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::IsGuarding(THIS)"); { - NPC * THIS; - bool RETVAL; + NPC *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsGuarding(); @@ -1485,41 +1391,38 @@ XS(XS_NPC_IsGuarding) } XS(XS_NPC_AI_SetRoambox); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_AI_SetRoambox) -{ +XS(XS_NPC_AI_SetRoambox) { dXSARGS; if (items < 6 || items > 8) - Perl_croak(aTHX_ "Usage: NPC::AI_SetRoambox(THIS, iDist, iMaxX, iMinX, iMaxY, iMinY, iDelay= 2500, iMinDelay= 2500)"); + Perl_croak(aTHX_ + "Usage: NPC::AI_SetRoambox(THIS, float distance, float max_x, float min_x, float max_y, float min_y, [uint32 max_delay = 2500], [uint32 min_delay = 2500])"); { - NPC * THIS; - float iDist = (float)SvNV(ST(1)); - float iMaxX = (float)SvNV(ST(2)); - float iMinX = (float)SvNV(ST(3)); - float iMaxY = (float)SvNV(ST(4)); - float iMinY = (float)SvNV(ST(5)); - uint32 iDelay; - uint32 iMinDelay; + NPC *THIS; + float iDist = (float) SvNV(ST(1)); + float iMaxX = (float) SvNV(ST(2)); + float iMinX = (float) SvNV(ST(3)); + float iMaxY = (float) SvNV(ST(4)); + float iMinY = (float) SvNV(ST(5)); + uint32 iDelay; + uint32 iMinDelay; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items < 7){ + if (items < 7) { iMinDelay = 2500; - iDelay = 2500; - } - else if (items < 8){ + iDelay = 2500; + } else if (items < 8) { iMinDelay = 2500; - iDelay = (uint32)SvUV(ST(6)); - } - else { - iDelay = (uint32)SvUV(ST(6)); - iMinDelay = (uint32)SvUV(ST(7)); + iDelay = (uint32) SvUV(ST(6)); + } else { + iDelay = (uint32) SvUV(ST(6)); + iMinDelay = (uint32) SvUV(ST(7)); } THIS->AI_SetRoambox(iDist, iMaxX, iMinX, iMaxY, iMinY, iDelay, iMinDelay); @@ -1528,263 +1431,252 @@ XS(XS_NPC_AI_SetRoambox) } XS(XS_NPC_GetNPCSpellsID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetNPCSpellsID) -{ +XS(XS_NPC_GetNPCSpellsID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetNPCSpellsID(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetNPCSpellsID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSpawnPointID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpawnPointID) -{ +XS(XS_NPC_GetSpawnPointID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpawnPointID(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpawnPointID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSpawnPointX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpawnPointX) -{ +XS(XS_NPC_GetSpawnPointX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpawnPointX(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpawnPoint().x; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSpawnPointY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpawnPointY) -{ +XS(XS_NPC_GetSpawnPointY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpawnPointY(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpawnPoint().y; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSpawnPointZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpawnPointZ) -{ +XS(XS_NPC_GetSpawnPointZ) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpawnPointZ(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpawnPoint().z; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSpawnPointH); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpawnPointH) -{ +XS(XS_NPC_GetSpawnPointH) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpawnPointH(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpawnPoint().w; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetGuardPointX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetGuardPointX) -{ +XS(XS_NPC_GetGuardPointX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetGuardPointX(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGuardPoint().x; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetGuardPointY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetGuardPointY) -{ +XS(XS_NPC_GetGuardPointY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetGuardPointY(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGuardPoint().y; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetGuardPointZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetGuardPointZ) -{ +XS(XS_NPC_GetGuardPointZ) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetGuardPointZ(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGuardPoint().z; - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_SetPrimSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetPrimSkill) -{ +XS(XS_NPC_SetPrimSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetPrimSkill(THIS, skill_id)"); + Perl_croak(aTHX_ "Usage: NPC::SetPrimSkill(THIS, int skill_id)"); { - NPC * THIS; - int skill_id = (int)SvIV(ST(1)); + NPC *THIS; + int skill_id = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetPrimSkill(skill_id); @@ -1793,22 +1685,20 @@ XS(XS_NPC_SetPrimSkill) } XS(XS_NPC_SetSecSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSecSkill) -{ +XS(XS_NPC_SetSecSkill) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSecSkill(THIS, skill_id)"); + Perl_croak(aTHX_ "Usage: NPC::SetSecSkill(THIS, int skill_id)"); { - NPC * THIS; - int skill_id = (int)SvIV(ST(1)); + NPC *THIS; + int skill_id = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSecSkill(skill_id); @@ -1817,126 +1707,120 @@ XS(XS_NPC_SetSecSkill) } XS(XS_NPC_GetPrimSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetPrimSkill) -{ +XS(XS_NPC_GetPrimSkill) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetPrimSkill(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPrimSkill(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSecSkill); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSecSkill) -{ +XS(XS_NPC_GetSecSkill) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSecSkill(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSecSkill(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSwarmOwner); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSwarmOwner) -{ +XS(XS_NPC_GetSwarmOwner) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSwarmOwner(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSwarmOwner(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSwarmTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSwarmTarget) -{ +XS(XS_NPC_GetSwarmTarget) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSwarmTarget(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSwarmTarget(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_SetSwarmTarget); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSwarmTarget) -{ +XS(XS_NPC_SetSwarmTarget) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSwarmTarget(THIS, target_id)"); + Perl_croak(aTHX_ "Usage: NPC::SetSwarmTarget(THIS, int target_id)"); { - NPC * THIS; - int target_id = (int)SvIV(ST(1)); + NPC *THIS; + int target_id = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSwarmTarget(target_id); @@ -1945,23 +1829,21 @@ XS(XS_NPC_SetSwarmTarget) } XS(XS_NPC_ModifyNPCStat); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_ModifyNPCStat) -{ +XS(XS_NPC_ModifyNPCStat) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: NPC::ModifyNPCStat(THIS, identifier, newValue)"); + Perl_croak(aTHX_ "Usage: NPC::ModifyNPCStat(THIS, string key, string value)"); { - NPC * THIS; - Const_char * identifier = (Const_char *)SvPV_nolen(ST(1)); - Const_char * newValue = (Const_char *)SvPV_nolen(ST(2)); + NPC *THIS; + Const_char *identifier = (Const_char *) SvPV_nolen(ST(1)); + Const_char *newValue = (Const_char *) SvPV_nolen(ST(2)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ModifyNPCStat(identifier, newValue); @@ -1970,27 +1852,26 @@ XS(XS_NPC_ModifyNPCStat) } XS(XS_NPC_AddSpellToNPCList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_AddSpellToNPCList) -{ +XS(XS_NPC_AddSpellToNPCList) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: NPC::AddAISpell(THIS, priority, spell_id, type, mana_cost, recast_delay, resist_adjust)"); + Perl_croak(aTHX_ + "Usage: NPC::AddAISpell(THIS, int priority, int spell_id, int type, int mana_cost, int recast_delay, int resist_adjust)"); { - NPC * THIS; - int priority = (int)SvIV(ST(1)); - int spell_id = (int)SvIV(ST(2)); - int type = (int)SvIV(ST(3)); - int mana_cost = (int)SvIV(ST(4)); - int recast_delay = (int)SvIV(ST(5)); - int resist_adjust = (int)SvIV(ST(6)); + NPC *THIS; + int priority = (int) SvIV(ST(1)); + int spell_id = (int) SvIV(ST(2)); + int type = (int) SvIV(ST(3)); + int mana_cost = (int) SvIV(ST(4)); + int recast_delay = (int) SvIV(ST(5)); + int resist_adjust = (int) SvIV(ST(6)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->AddSpellToNPCList(priority, spell_id, type, mana_cost, recast_delay, resist_adjust, 0, 0); @@ -1999,22 +1880,20 @@ XS(XS_NPC_AddSpellToNPCList) } XS(XS_NPC_RemoveSpellFromNPCList); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_RemoveSpellFromNPCList) -{ +XS(XS_NPC_RemoveSpellFromNPCList) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::RemoveAISpell(THIS, spell_id)"); + Perl_croak(aTHX_ "Usage: NPC::RemoveAISpell(THIS, int spell_id)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveSpellFromNPCList(spell_id); @@ -2023,22 +1902,20 @@ XS(XS_NPC_RemoveSpellFromNPCList) } XS(XS_NPC_SetSpellFocusDMG); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSpellFocusDMG) -{ +XS(XS_NPC_SetSpellFocusDMG) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSpellFocusDMG(THIS, NewSpellFocusDMG)"); + Perl_croak(aTHX_ "Usage: NPC::SetSpellFocusDMG(THIS, int new_spell_focus_dmg)"); { - NPC * THIS; - int32 NewSpellFocusDMG = (int32)SvIV(ST(1)); + NPC *THIS; + int32 NewSpellFocusDMG = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSpellFocusDMG(NewSpellFocusDMG); @@ -2047,48 +1924,45 @@ XS(XS_NPC_SetSpellFocusDMG) } XS(XS_NPC_GetSpellFocusDMG); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpellFocusDMG) -{ +XS(XS_NPC_GetSpellFocusDMG) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpellFocusDMG(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpellFocusDMG(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_SetSpellFocusHeal); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_SetSpellFocusHeal) -{ +XS(XS_NPC_SetSpellFocusHeal) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::SetSpellFocusHeal(THIS, NewSpellFocusHeal)"); + Perl_croak(aTHX_ "Usage: NPC::SetSpellFocusHeal(THIS, int32 new_spell_focus_heal)"); { - NPC * THIS; - int32 NewSpellFocusHeal = (int32)SvIV(ST(1)); + NPC *THIS; + int32 NewSpellFocusHeal = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSpellFocusHeal(NewSpellFocusHeal); @@ -2097,209 +1971,201 @@ XS(XS_NPC_SetSpellFocusHeal) } XS(XS_NPC_GetSpellFocusHeal); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpellFocusHeal) -{ +XS(XS_NPC_GetSpellFocusHeal) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpellFocusHeal(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSpellFocusHeal(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSlowMitigation); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSlowMitigation) -{ +XS(XS_NPC_GetSlowMitigation) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSlowMitigation(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSlowMitigation(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetAttackSpeed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetAttackSpeed) -{ +XS(XS_NPC_GetAttackSpeed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetAttackSpeed(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAttackSpeed(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetAttackDelay); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetAttackDelay) -{ +XS(XS_NPC_GetAttackDelay) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetAttackDelay(THIS)"); { - NPC * THIS; - float RETVAL; + NPC *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAttackDelay(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetAccuracyRating); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetAccuracyRating) -{ +XS(XS_NPC_GetAccuracyRating) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetAccuracyRating(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAccuracyRating(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetAvoidanceRating); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetAvoidanceRating) -{ +XS(XS_NPC_GetAvoidanceRating) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetAvoidanceyRating(THIS)"); { - NPC * THIS; - int32 RETVAL; + NPC *THIS; + int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAvoidanceRating(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetSpawnKillCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetSpawnKillCount) -{ +XS(XS_NPC_GetSpawnKillCount) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetSpawnKillCount(THIS)"); { - NPC * THIS; - uint32 RETVAL; + NPC *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); RETVAL = THIS->GetSpawnKillCount(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_NPC_GetScore); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetScore) -{ +XS(XS_NPC_GetScore) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetScore(THIS)"); { - NPC * THIS; - int RETVAL; + NPC *THIS; + int RETVAL; dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); RETVAL = THIS->GetScore(); - XSprePUSH; PUSHi((UV)RETVAL); + XSprePUSH; + PUSHi((UV) RETVAL); } XSRETURN(1); } @@ -2308,20 +2174,19 @@ XS(XS_NPC_AddMeleeProc); XS(XS_NPC_AddMeleeProc) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: NPC::AddMeleeProc(THIS,spellid,chance)"); + Perl_croak(aTHX_ "Usage: NPC::AddMeleeProc(THIS, int spell_id, int chance)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); - int chance = (int)SvIV(ST(2)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); + int chance = (int) SvIV(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->AddProcToWeapon(spell_id, true, chance); @@ -2333,23 +2198,22 @@ XS(XS_NPC_AddRangedProc); XS(XS_NPC_AddRangedProc) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: NPC::AddRangedProc(THIS,spellid,chance)"); + Perl_croak(aTHX_ "Usage: NPC::AddRangedProc(THIS, int spell_id, int chance)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); - int chance = (int)SvIV(ST(2)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); + int chance = (int) SvIV(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - THIS->AddRangedProc(spell_id,chance); + THIS->AddRangedProc(spell_id, chance); } XSRETURN_EMPTY; } @@ -2358,23 +2222,22 @@ XS(XS_NPC_AddDefensiveProc); XS(XS_NPC_AddDefensiveProc) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: NPC::AddDefensiveProc(THIS,spellid,chance)"); + Perl_croak(aTHX_ "Usage: NPC::AddDefensiveProc(THIS, int spell_id, int chance)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); - int chance = (int)SvIV(ST(2)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); + int chance = (int) SvIV(ST(2)); dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); - THIS->AddDefensiveProc(spell_id,chance); + THIS->AddDefensiveProc(spell_id, chance); } XSRETURN_EMPTY; } @@ -2383,19 +2246,18 @@ XS(XS_NPC_RemoveMeleeProc); XS(XS_NPC_RemoveMeleeProc) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::RemoveMeleeProc(THIS,spellid)"); + Perl_croak(aTHX_ "Usage: NPC::RemoveMeleeProc(THIS, int spell_id)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->RemoveProcFromWeapon(spell_id, false); @@ -2407,19 +2269,18 @@ XS(XS_NPC_RemoveRangedProc); XS(XS_NPC_RemoveRangedProc) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::RemoveRangedProc(THIS,spellid)"); + Perl_croak(aTHX_ "Usage: NPC::RemoveRangedProc(THIS, int spell_id)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->RemoveRangedProc(spell_id, false); @@ -2431,19 +2292,18 @@ XS(XS_NPC_RemoveDefensiveProc); XS(XS_NPC_RemoveDefensiveProc) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: NPC::RemoveDefensiveProc(THIS,spellid)"); + Perl_croak(aTHX_ "Usage: NPC::RemoveDefensiveProc(THIS, int spell_id)"); { - NPC * THIS; - int spell_id = (int)SvIV(ST(1)); + NPC *THIS; + int spell_id = (int) SvIV(ST(1)); dXSTARG; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == NULL) + if (THIS == NULL) Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); THIS->RemoveDefensiveProc(spell_id, false); @@ -2452,25 +2312,23 @@ XS(XS_NPC_RemoveDefensiveProc) { } XS(XS_NPC_ChangeLastName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_ChangeLastName) -{ +XS(XS_NPC_ChangeLastName) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Mob::ChangeLastName(THIS, name)"); + Perl_croak(aTHX_ "Usage: NPC::ChangeLastName(THIS, string name)"); { - NPC * THIS; - char * name = nullptr; + NPC *THIS; + char *name = nullptr; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { name = (char *)SvPV_nolen(ST(1)); } + if (items > 1) { name = (char *) SvPV_nolen(ST(1)); } THIS->ChangeLastName(name); } @@ -2478,21 +2336,19 @@ XS(XS_NPC_ChangeLastName) } XS(XS_NPC_ClearLastName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_ClearLastName) -{ +XS(XS_NPC_ClearLastName) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: Mob::ClearLastName(THIS)"); + Perl_croak(aTHX_ "Usage: NPC::ClearLastName(THIS)"); { - NPC * THIS; + NPC *THIS; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearLastName(); @@ -2501,22 +2357,20 @@ XS(XS_NPC_ClearLastName) } XS(XS_NPC_GetCombatState); /* prototype to pass -Wmissing-prototypes */ -XS(XS_NPC_GetCombatState) -{ +XS(XS_NPC_GetCombatState) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: NPC::GetCombatState(THIS)"); { - NPC * THIS; - bool RETVAL; + NPC *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "NPC")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(NPC *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type NPC"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCombatEvent(); @@ -2530,114 +2384,113 @@ XS(XS_NPC_GetCombatState) extern "C" #endif XS(boot_NPC); /* prototype to pass -Wmissing-prototypes */ -XS(boot_NPC) -{ +XS(boot_NPC) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "SignalNPC"), XS_NPC_SignalNPC, file, "$$"); - newXSproto(strcpy(buf, "CheckNPCFactionAlly"), XS_NPC_CheckNPCFactionAlly, file, "$$"); - newXSproto(strcpy(buf, "AddItem"), XS_NPC_AddItem, file, "$$;$$$$$$$$"); - newXSproto(strcpy(buf, "AddLootTable"), XS_NPC_AddLootTable, file, "$"); - newXSproto(strcpy(buf, "RemoveItem"), XS_NPC_RemoveItem, file, "$$;$$"); - newXSproto(strcpy(buf, "ClearItemList"), XS_NPC_ClearItemList, file, "$"); - newXSproto(strcpy(buf, "AddCash"), XS_NPC_AddCash, file, "$$$$$"); - newXSproto(strcpy(buf, "RemoveCash"), XS_NPC_RemoveCash, file, "$"); - newXSproto(strcpy(buf, "CountLoot"), XS_NPC_CountLoot, file, "$"); - newXSproto(strcpy(buf, "GetLoottableID"), XS_NPC_GetLoottableID, file, "$"); - newXSproto(strcpy(buf, "GetCopper"), XS_NPC_GetCopper, file, "$"); - newXSproto(strcpy(buf, "GetSilver"), XS_NPC_GetSilver, file, "$"); - newXSproto(strcpy(buf, "GetGold"), XS_NPC_GetGold, file, "$"); - newXSproto(strcpy(buf, "GetPlatinum"), XS_NPC_GetPlatinum, file, "$"); - newXSproto(strcpy(buf, "SetCopper"), XS_NPC_SetCopper, file, "$$"); - newXSproto(strcpy(buf, "SetSilver"), XS_NPC_SetSilver, file, "$$"); - newXSproto(strcpy(buf, "SetGold"), XS_NPC_SetGold, file, "$$"); - newXSproto(strcpy(buf, "SetPlatinum"), XS_NPC_SetPlatinum, file, "$$"); - newXSproto(strcpy(buf, "SetGrid"), XS_NPC_SetGrid, file, "$$"); - newXSproto(strcpy(buf, "SetSaveWaypoint"), XS_NPC_SetSaveWaypoint, file, "$$"); - newXSproto(strcpy(buf, "SetSp2"), XS_NPC_SetSp2, file, "$$"); - newXSproto(strcpy(buf, "GetWaypointMax"), XS_NPC_GetWaypointMax, file, "$"); - newXSproto(strcpy(buf, "GetGrid"), XS_NPC_GetGrid, file, "$"); - newXSproto(strcpy(buf, "GetSp2"), XS_NPC_GetSp2, file, "$"); - newXSproto(strcpy(buf, "GetNPCFactionID"), XS_NPC_GetNPCFactionID, file, "$"); - newXSproto(strcpy(buf, "GetPrimaryFaction"), XS_NPC_GetPrimaryFaction, file, "$"); - newXSproto(strcpy(buf, "GetNPCHate"), XS_NPC_GetNPCHate, file, "$$"); - newXSproto(strcpy(buf, "IsOnHatelist"), XS_NPC_IsOnHatelist, file, "$$"); - newXSproto(strcpy(buf, "RemoveFromHateList"), XS_NPC_RemoveFromHateList, file, "$$"); - newXSproto(strcpy(buf, "SetNPCFactionID"), XS_NPC_SetNPCFactionID, file, "$$"); - newXSproto(strcpy(buf, "GetMaxDMG"), XS_NPC_GetMaxDMG, file, "$"); - newXSproto(strcpy(buf, "GetMinDMG"), XS_NPC_GetMinDMG, file, "$"); - newXSproto(strcpy(buf, "IsAnimal"), XS_NPC_IsAnimal, file, "$"); - newXSproto(strcpy(buf, "GetPetSpellID"), XS_NPC_GetPetSpellID, file, "$"); - newXSproto(strcpy(buf, "SetPetSpellID"), XS_NPC_SetPetSpellID, file, "$$"); - newXSproto(strcpy(buf, "GetMaxDamage"), XS_NPC_GetMaxDamage, file, "$$"); - newXSproto(strcpy(buf, "SetTaunting"), XS_NPC_SetTaunting, file, "$$"); - newXSproto(strcpy(buf, "PickPocket"), XS_NPC_PickPocket, file, "$$"); - newXSproto(strcpy(buf, "StartSwarmTimer"), XS_NPC_StartSwarmTimer, file, "$$"); - newXSproto(strcpy(buf, "DoClassAttacks"), XS_NPC_DoClassAttacks, file, "$$"); - newXSproto(strcpy(buf, "GetMaxWp"), XS_NPC_GetMaxWp, file, "$"); - newXSproto(strcpy(buf, "DisplayWaypointInfo"), XS_NPC_DisplayWaypointInfo, file, "$$"); - newXSproto(strcpy(buf, "CalculateNewWaypoint"), XS_NPC_CalculateNewWaypoint, file, "$"); - newXSproto(strcpy(buf, "AssignWaypoints"), XS_NPC_AssignWaypoints, file, "$$"); - newXSproto(strcpy(buf, "SetWaypointPause"), XS_NPC_SetWaypointPause, file, "$"); - newXSproto(strcpy(buf, "UpdateWaypoint"), XS_NPC_UpdateWaypoint, file, "$$"); - newXSproto(strcpy(buf, "StopWandering"), XS_NPC_StopWandering, file, "$"); - newXSproto(strcpy(buf, "ResumeWandering"), XS_NPC_ResumeWandering, file, "$"); - newXSproto(strcpy(buf, "PauseWandering"), XS_NPC_PauseWandering, file, "$$"); - newXSproto(strcpy(buf, "MoveTo"), XS_NPC_MoveTo, file, "$$$$"); - newXSproto(strcpy(buf, "NextGuardPosition"), XS_NPC_NextGuardPosition, file, "$"); - newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$;$"); - newXSproto(strcpy(buf, "IsGuarding"), XS_NPC_IsGuarding, file, "$"); - newXSproto(strcpy(buf, "AI_SetRoambox"), XS_NPC_AI_SetRoambox, file, "$$$$$$;$$"); - newXSproto(strcpy(buf, "GetNPCSpellsID"), XS_NPC_GetNPCSpellsID, file, "$"); - newXSproto(strcpy(buf, "GetSpawnPointID"), XS_NPC_GetSpawnPointID, file, "$"); - newXSproto(strcpy(buf, "GetSpawnPointX"), XS_NPC_GetSpawnPointX, file, "$"); - newXSproto(strcpy(buf, "GetSpawnPointY"), XS_NPC_GetSpawnPointY, file, "$"); - newXSproto(strcpy(buf, "GetSpawnPointZ"), XS_NPC_GetSpawnPointZ, file, "$"); - newXSproto(strcpy(buf, "GetSpawnPointH"), XS_NPC_GetSpawnPointH, file, "$"); - newXSproto(strcpy(buf, "GetGuardPointX"), XS_NPC_GetGuardPointX, file, "$"); - newXSproto(strcpy(buf, "GetGuardPointY"), XS_NPC_GetGuardPointY, file, "$"); - newXSproto(strcpy(buf, "GetGuardPointZ"), XS_NPC_GetGuardPointZ, file, "$"); - newXSproto(strcpy(buf, "SetPrimSkill"), XS_NPC_SetPrimSkill, file, "$$"); - newXSproto(strcpy(buf, "SetSecSkill"), XS_NPC_SetSecSkill, file, "$$"); - newXSproto(strcpy(buf, "GetPrimSkill"), XS_NPC_GetPrimSkill, file, "$"); - newXSproto(strcpy(buf, "GetSecSkill"), XS_NPC_GetSecSkill, file, "$"); - newXSproto(strcpy(buf, "GetSwarmOwner"), XS_NPC_GetSwarmOwner, file, "$"); - newXSproto(strcpy(buf, "GetSwarmTarget"), XS_NPC_GetSwarmTarget, file, "$"); - newXSproto(strcpy(buf, "SetSwarmTarget"), XS_NPC_SetSwarmTarget, file, "$$"); - newXSproto(strcpy(buf, "ModifyNPCStat"), XS_NPC_ModifyNPCStat, file, "$$$"); - newXSproto(strcpy(buf, "AddAISpell"), XS_NPC_AddSpellToNPCList, file, "$$$$$$$"); - newXSproto(strcpy(buf, "RemoveAISpell"), XS_NPC_RemoveSpellFromNPCList, file, "$$"); - newXSproto(strcpy(buf, "SetSpellFocusDMG"), XS_NPC_SetSpellFocusDMG, file, "$$"); - newXSproto(strcpy(buf, "SetSpellFocusHeal"), XS_NPC_SetSpellFocusHeal, file, "$$"); - newXSproto(strcpy(buf, "GetSpellFocusDMG"), XS_NPC_GetSpellFocusDMG, file, "$"); - newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$"); - newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$"); - newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$"); - newXSproto(strcpy(buf, "GetAttackDelay"), XS_NPC_GetAttackDelay, file, "$"); - newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$"); - newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$"); - newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$"); - newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$"); - newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$"); - newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$"); - newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$"); - newXSproto(strcpy(buf, "RemoveMeleeProc"), XS_NPC_RemoveMeleeProc, file, "$$"); - newXSproto(strcpy(buf, "RemoveRangedProc"), XS_NPC_RemoveRangedProc, file, "$$"); - newXSproto(strcpy(buf, "RemoveDefensiveProc"), XS_NPC_RemoveDefensiveProc, file, "$$"); - newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$"); - newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$"); - newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$"); + newXSproto(strcpy(buf, "SignalNPC"), XS_NPC_SignalNPC, file, "$$"); + newXSproto(strcpy(buf, "CheckNPCFactionAlly"), XS_NPC_CheckNPCFactionAlly, file, "$$"); + newXSproto(strcpy(buf, "AddItem"), XS_NPC_AddItem, file, "$$;$$$$$$$$"); + newXSproto(strcpy(buf, "AddLootTable"), XS_NPC_AddLootTable, file, "$"); + newXSproto(strcpy(buf, "RemoveItem"), XS_NPC_RemoveItem, file, "$$;$$"); + newXSproto(strcpy(buf, "ClearItemList"), XS_NPC_ClearItemList, file, "$"); + newXSproto(strcpy(buf, "AddCash"), XS_NPC_AddCash, file, "$$$$$"); + newXSproto(strcpy(buf, "RemoveCash"), XS_NPC_RemoveCash, file, "$"); + newXSproto(strcpy(buf, "CountLoot"), XS_NPC_CountLoot, file, "$"); + newXSproto(strcpy(buf, "GetLoottableID"), XS_NPC_GetLoottableID, file, "$"); + newXSproto(strcpy(buf, "GetCopper"), XS_NPC_GetCopper, file, "$"); + newXSproto(strcpy(buf, "GetSilver"), XS_NPC_GetSilver, file, "$"); + newXSproto(strcpy(buf, "GetGold"), XS_NPC_GetGold, file, "$"); + newXSproto(strcpy(buf, "GetPlatinum"), XS_NPC_GetPlatinum, file, "$"); + newXSproto(strcpy(buf, "SetCopper"), XS_NPC_SetCopper, file, "$$"); + newXSproto(strcpy(buf, "SetSilver"), XS_NPC_SetSilver, file, "$$"); + newXSproto(strcpy(buf, "SetGold"), XS_NPC_SetGold, file, "$$"); + newXSproto(strcpy(buf, "SetPlatinum"), XS_NPC_SetPlatinum, file, "$$"); + newXSproto(strcpy(buf, "SetGrid"), XS_NPC_SetGrid, file, "$$"); + newXSproto(strcpy(buf, "SetSaveWaypoint"), XS_NPC_SetSaveWaypoint, file, "$$"); + newXSproto(strcpy(buf, "SetSp2"), XS_NPC_SetSp2, file, "$$"); + newXSproto(strcpy(buf, "GetWaypointMax"), XS_NPC_GetWaypointMax, file, "$"); + newXSproto(strcpy(buf, "GetGrid"), XS_NPC_GetGrid, file, "$"); + newXSproto(strcpy(buf, "GetSp2"), XS_NPC_GetSp2, file, "$"); + newXSproto(strcpy(buf, "GetNPCFactionID"), XS_NPC_GetNPCFactionID, file, "$"); + newXSproto(strcpy(buf, "GetPrimaryFaction"), XS_NPC_GetPrimaryFaction, file, "$"); + newXSproto(strcpy(buf, "GetNPCHate"), XS_NPC_GetNPCHate, file, "$$"); + newXSproto(strcpy(buf, "IsOnHatelist"), XS_NPC_IsOnHatelist, file, "$$"); + newXSproto(strcpy(buf, "RemoveFromHateList"), XS_NPC_RemoveFromHateList, file, "$$"); + newXSproto(strcpy(buf, "SetNPCFactionID"), XS_NPC_SetNPCFactionID, file, "$$"); + newXSproto(strcpy(buf, "GetMaxDMG"), XS_NPC_GetMaxDMG, file, "$"); + newXSproto(strcpy(buf, "GetMinDMG"), XS_NPC_GetMinDMG, file, "$"); + newXSproto(strcpy(buf, "IsAnimal"), XS_NPC_IsAnimal, file, "$"); + newXSproto(strcpy(buf, "GetPetSpellID"), XS_NPC_GetPetSpellID, file, "$"); + newXSproto(strcpy(buf, "SetPetSpellID"), XS_NPC_SetPetSpellID, file, "$$"); + newXSproto(strcpy(buf, "GetMaxDamage"), XS_NPC_GetMaxDamage, file, "$$"); + newXSproto(strcpy(buf, "SetTaunting"), XS_NPC_SetTaunting, file, "$$"); + newXSproto(strcpy(buf, "PickPocket"), XS_NPC_PickPocket, file, "$$"); + newXSproto(strcpy(buf, "StartSwarmTimer"), XS_NPC_StartSwarmTimer, file, "$$"); + newXSproto(strcpy(buf, "DoClassAttacks"), XS_NPC_DoClassAttacks, file, "$$"); + newXSproto(strcpy(buf, "GetMaxWp"), XS_NPC_GetMaxWp, file, "$"); + newXSproto(strcpy(buf, "DisplayWaypointInfo"), XS_NPC_DisplayWaypointInfo, file, "$$"); + newXSproto(strcpy(buf, "CalculateNewWaypoint"), XS_NPC_CalculateNewWaypoint, file, "$"); + newXSproto(strcpy(buf, "AssignWaypoints"), XS_NPC_AssignWaypoints, file, "$$"); + newXSproto(strcpy(buf, "SetWaypointPause"), XS_NPC_SetWaypointPause, file, "$"); + newXSproto(strcpy(buf, "UpdateWaypoint"), XS_NPC_UpdateWaypoint, file, "$$"); + newXSproto(strcpy(buf, "StopWandering"), XS_NPC_StopWandering, file, "$"); + newXSproto(strcpy(buf, "ResumeWandering"), XS_NPC_ResumeWandering, file, "$"); + newXSproto(strcpy(buf, "PauseWandering"), XS_NPC_PauseWandering, file, "$$"); + newXSproto(strcpy(buf, "MoveTo"), XS_NPC_MoveTo, file, "$$$$"); + newXSproto(strcpy(buf, "NextGuardPosition"), XS_NPC_NextGuardPosition, file, "$"); + newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$;$"); + newXSproto(strcpy(buf, "IsGuarding"), XS_NPC_IsGuarding, file, "$"); + newXSproto(strcpy(buf, "AI_SetRoambox"), XS_NPC_AI_SetRoambox, file, "$$$$$$;$$"); + newXSproto(strcpy(buf, "GetNPCSpellsID"), XS_NPC_GetNPCSpellsID, file, "$"); + newXSproto(strcpy(buf, "GetSpawnPointID"), XS_NPC_GetSpawnPointID, file, "$"); + newXSproto(strcpy(buf, "GetSpawnPointX"), XS_NPC_GetSpawnPointX, file, "$"); + newXSproto(strcpy(buf, "GetSpawnPointY"), XS_NPC_GetSpawnPointY, file, "$"); + newXSproto(strcpy(buf, "GetSpawnPointZ"), XS_NPC_GetSpawnPointZ, file, "$"); + newXSproto(strcpy(buf, "GetSpawnPointH"), XS_NPC_GetSpawnPointH, file, "$"); + newXSproto(strcpy(buf, "GetGuardPointX"), XS_NPC_GetGuardPointX, file, "$"); + newXSproto(strcpy(buf, "GetGuardPointY"), XS_NPC_GetGuardPointY, file, "$"); + newXSproto(strcpy(buf, "GetGuardPointZ"), XS_NPC_GetGuardPointZ, file, "$"); + newXSproto(strcpy(buf, "SetPrimSkill"), XS_NPC_SetPrimSkill, file, "$$"); + newXSproto(strcpy(buf, "SetSecSkill"), XS_NPC_SetSecSkill, file, "$$"); + newXSproto(strcpy(buf, "GetPrimSkill"), XS_NPC_GetPrimSkill, file, "$"); + newXSproto(strcpy(buf, "GetSecSkill"), XS_NPC_GetSecSkill, file, "$"); + newXSproto(strcpy(buf, "GetSwarmOwner"), XS_NPC_GetSwarmOwner, file, "$"); + newXSproto(strcpy(buf, "GetSwarmTarget"), XS_NPC_GetSwarmTarget, file, "$"); + newXSproto(strcpy(buf, "SetSwarmTarget"), XS_NPC_SetSwarmTarget, file, "$$"); + newXSproto(strcpy(buf, "ModifyNPCStat"), XS_NPC_ModifyNPCStat, file, "$$$"); + newXSproto(strcpy(buf, "AddAISpell"), XS_NPC_AddSpellToNPCList, file, "$$$$$$$"); + newXSproto(strcpy(buf, "RemoveAISpell"), XS_NPC_RemoveSpellFromNPCList, file, "$$"); + newXSproto(strcpy(buf, "SetSpellFocusDMG"), XS_NPC_SetSpellFocusDMG, file, "$$"); + newXSproto(strcpy(buf, "SetSpellFocusHeal"), XS_NPC_SetSpellFocusHeal, file, "$$"); + newXSproto(strcpy(buf, "GetSpellFocusDMG"), XS_NPC_GetSpellFocusDMG, file, "$"); + newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$"); + newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$"); + newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$"); + newXSproto(strcpy(buf, "GetAttackDelay"), XS_NPC_GetAttackDelay, file, "$"); + newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$"); + newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$"); + newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$"); + newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$"); + newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$"); + newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$"); + newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$"); + newXSproto(strcpy(buf, "RemoveMeleeProc"), XS_NPC_RemoveMeleeProc, file, "$$"); + newXSproto(strcpy(buf, "RemoveRangedProc"), XS_NPC_RemoveRangedProc, file, "$$"); + newXSproto(strcpy(buf, "RemoveDefensiveProc"), XS_NPC_RemoveDefensiveProc, file, "$$"); + newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$"); + newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$"); + newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$"); XSRETURN_YES; } diff --git a/zone/perl_object.cpp b/zone/perl_object.cpp index f8fc9a4ee..df2589de4 100644 --- a/zone/perl_object.cpp +++ b/zone/perl_object.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -41,22 +43,20 @@ #endif XS(XS_Object_IsGroundSpawn); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_IsGroundSpawn) -{ +XS(XS_Object_IsGroundSpawn) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::IsGroundSpawn(THIS)"); { - Object * THIS; - bool RETVAL; + Object *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsGroundSpawn(); @@ -67,23 +67,20 @@ XS(XS_Object_IsGroundSpawn) } - XS(XS_Object_Close); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_Close) -{ +XS(XS_Object_Close) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::Close(THIS)"); { - Object * THIS; + Object *THIS; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Close(); @@ -93,28 +90,26 @@ XS(XS_Object_Close) XS(XS_Object_Delete); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_Delete) -{ +XS(XS_Object_Delete) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Object::Delete(THIS, reset_state=false)"); + Perl_croak(aTHX_ "Usage: Object::Delete(THIS, [bool reset_state = false])"); { - Object * THIS; - bool reset_state; + Object *THIS; + bool reset_state; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 2) reset_state = false; else { - reset_state = (bool)SvTRUE(ST(1)); + reset_state = (bool) SvTRUE(ST(1)); } THIS->Delete(reset_state); @@ -122,21 +117,19 @@ XS(XS_Object_Delete) XSRETURN_EMPTY; } XS(XS_Object_StartDecay); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_StartDecay) -{ +XS(XS_Object_StartDecay) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::StartDecay(THIS)"); { - Object * THIS; + Object *THIS; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->StartDecay(); @@ -146,22 +139,20 @@ XS(XS_Object_StartDecay) XS(XS_Object_DeleteItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_DeleteItem) -{ +XS(XS_Object_DeleteItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::DeleteItem(THIS, index)"); + Perl_croak(aTHX_ "Usage: Object::DeleteItem(THIS, uint8 index)"); { - Object * THIS; - uint8 index = (uint8)SvUV(ST(1)); + Object *THIS; + uint8 index = (uint8) SvUV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->DeleteItem(index); @@ -170,22 +161,20 @@ XS(XS_Object_DeleteItem) } XS(XS_Object_IsObject); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_IsObject) -{ +XS(XS_Object_IsObject) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::IsObject(THIS)"); { - Object * THIS; - bool RETVAL; + Object *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsObject(); @@ -197,22 +186,20 @@ XS(XS_Object_IsObject) XS(XS_Object_Save); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_Save) -{ +XS(XS_Object_Save) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::Save(THIS)"); { - Object * THIS; - bool RETVAL; + Object *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->Save(); @@ -224,22 +211,20 @@ XS(XS_Object_Save) XS(XS_Object_SetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetID) -{ +XS(XS_Object_SetID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetID(THIS, set_id)"); + Perl_croak(aTHX_ "Usage: Object::SetID(THIS, uint16 id)"); { - Object * THIS; - uint16 set_id = (uint16)SvUV(ST(1)); + Object *THIS; + uint16 set_id = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetID(set_id); @@ -249,21 +234,19 @@ XS(XS_Object_SetID) XS(XS_Object_ClearUser); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_ClearUser) -{ +XS(XS_Object_ClearUser) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::ClearUser(THIS)"); { - Object * THIS; + Object *THIS; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ClearUser(); @@ -273,232 +256,222 @@ XS(XS_Object_ClearUser) XS(XS_Object_GetDBID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetDBID) -{ +XS(XS_Object_GetDBID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetDBID(THIS)"); { - Object * THIS; - uint32 RETVAL; + Object *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDBID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_GetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetID) -{ +XS(XS_Object_GetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetID(THIS)"); { - Object * THIS; - uint16 RETVAL; + Object *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_GetX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetX) -{ +XS(XS_Object_GetX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetX(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetX(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Object_GetY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetY) -{ +XS(XS_Object_GetY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetY(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetY(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Object_GetZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetZ) -{ +XS(XS_Object_GetZ) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetZ(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetZ(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Object_GetHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetHeading) -{ +XS(XS_Object_GetHeading) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetHeading(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHeadingData(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Object_VarSave); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_VarSave) -{ +XS(XS_Object_VarSave) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::VarSave(THIS)"); { - Object * THIS; - uint32 RETVAL; + Object *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->VarSave(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_GetType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetType) -{ +XS(XS_Object_GetType) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetType(THIS)"); { - Object * THIS; - uint32 RETVAL; + Object *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetType(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_SetType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetType) -{ +XS(XS_Object_SetType) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetType(THIS, type)"); + Perl_croak(aTHX_ "Usage: Object::SetType(THIS, uint32 type)"); { - Object * THIS; - uint32 type = (uint32)SvUV(ST(1)); + Object *THIS; + uint32 type = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetType(type); @@ -508,49 +481,46 @@ XS(XS_Object_SetType) XS(XS_Object_GetIcon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetIcon) -{ +XS(XS_Object_GetIcon) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetIcon(THIS)"); { - Object * THIS; - uint32 RETVAL; + Object *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetIcon(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_SetIcon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetIcon) -{ +XS(XS_Object_SetIcon) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetIcon(THIS, icon)"); + Perl_croak(aTHX_ "Usage: Object::SetIcon(THIS, uint32 icon)"); { - Object * THIS; - uint32 icon = (uint32)SvUV(ST(1)); + Object *THIS; + uint32 icon = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetIcon(icon); @@ -560,49 +530,46 @@ XS(XS_Object_SetIcon) XS(XS_Object_GetItemID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetItemID) -{ +XS(XS_Object_GetItemID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetItemID(THIS)"); { - Object * THIS; - uint32 RETVAL; + Object *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetItemID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_SetItemID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetItemID) -{ +XS(XS_Object_SetItemID) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetItemID(THIS, itemid)"); + Perl_croak(aTHX_ "Usage: Object::SetItemID(THIS, uint32 item_id)"); { - Object * THIS; - uint32 itemid = (uint32)SvUV(ST(1)); + Object *THIS; + uint32 itemid = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetItemID(itemid); @@ -611,24 +578,22 @@ XS(XS_Object_SetItemID) } XS(XS_Object_SetLocation); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetLocation) -{ +XS(XS_Object_SetLocation) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Object::SetLocation(THIS, x, y, z)"); + Perl_croak(aTHX_ "Usage: Object::SetLocation(THIS, float x, float y, float z)"); { - Object * THIS; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); + Object *THIS; + float x = (float) SvNV(ST(1)); + float y = (float) SvNV(ST(2)); + float z = (float) SvNV(ST(3)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetLocation(x, y, z); @@ -637,22 +602,20 @@ XS(XS_Object_SetLocation) } XS(XS_Object_SetX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetX) -{ +XS(XS_Object_SetX) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetX(THIS, XPos)"); + Perl_croak(aTHX_ "Usage: Object::SetX(THIS, float x)"); { - Object * THIS; - float pos = (float)SvNV(ST(1)); + Object *THIS; + float pos = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetX(pos); @@ -661,22 +624,20 @@ XS(XS_Object_SetX) } XS(XS_Object_SetY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetY) -{ +XS(XS_Object_SetY) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetY(THIS, YPos)"); + Perl_croak(aTHX_ "Usage: Object::SetY(THIS, float y)"); { - Object * THIS; - float pos = (float)SvNV(ST(1)); + Object *THIS; + float pos = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetY(pos); @@ -685,22 +646,20 @@ XS(XS_Object_SetY) } XS(XS_Object_SetZ); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetZ) -{ +XS(XS_Object_SetZ) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetZ(THIS, ZPos)"); + Perl_croak(aTHX_ "Usage: Object::SetZ(THIS, float z)"); { - Object * THIS; - float pos = (float)SvNV(ST(1)); + Object *THIS; + float pos = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetZ(pos); @@ -709,22 +668,20 @@ XS(XS_Object_SetZ) } XS(XS_Object_SetHeading); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetHeading) -{ +XS(XS_Object_SetHeading) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetHeading(THIS, heading)"); + Perl_croak(aTHX_ "Usage: Object::SetHeading(THIS, float heading)"); { - Object * THIS; - float heading = (float)SvNV(ST(1)); + Object *THIS; + float heading = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetHeading(heading); @@ -733,73 +690,69 @@ XS(XS_Object_SetHeading) } XS(XS_Object_SetModelName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetModelName) -{ +XS(XS_Object_SetModelName) { dXSARGS; if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Object::SetModelName(THIS, name)"); + Perl_croak(aTHX_ "Usage: Object::SetModelName(THIS, string name)"); { - Object * THIS; - char * name = nullptr; + Object *THIS; + char *name = nullptr; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items > 1) { name = (char *)SvPV_nolen(ST(1)); } + if (items > 1) { name = (char *) SvPV_nolen(ST(1)); } THIS->SetModelName(name); } XSRETURN_EMPTY; } XS(XS_Object_GetModelName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetModelName) -{ +XS(XS_Object_GetModelName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetModelName(THIS)"); { - Object * THIS; - Const_char * RETVAL; + Object *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetModelName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Object_Repop); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_Repop) -{ +XS(XS_Object_Repop) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::Repop(THIS)"); { - Object * THIS; + Object *THIS; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Repop(); } @@ -807,22 +760,20 @@ XS(XS_Object_Repop) } XS(XS_Object_Depop); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_Depop) -{ +XS(XS_Object_Depop) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::Depop(THIS)"); { - Object * THIS; + Object *THIS; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Depop(); } @@ -831,77 +782,73 @@ XS(XS_Object_Depop) XS(XS_Object_GetEntityVariable); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetEntityVariable) -{ +XS(XS_Object_GetEntityVariable) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::GetEntityVariable(THIS, id)"); + Perl_croak(aTHX_ "Usage: Object::GetEntityVariable(THIS, string key)"); { - Object * THIS; + Object *THIS; Const_char *id = SvPV_nolen(ST(1)); - Const_char * RETVAL; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetEntityVariable(id); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Object_EntityVariableExists); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_EntityVariableExists) -{ +XS(XS_Object_EntityVariableExists) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::EntityVariableExists(THIS, id)"); + Perl_croak(aTHX_ "Usage: Object::EntityVariableExists(THIS, string key)"); { - Object * THIS; + Object *THIS; Const_char *id = SvPV_nolen(ST(1)); - bool RETVAL; + bool RETVAL; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->EntityVariableExists(id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Object_SetEntityVariable); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetEntityVariable) -{ +XS(XS_Object_SetEntityVariable) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Object::SetEntityVariable(THIS, id, var)"); + Perl_croak(aTHX_ "Usage: Object::SetEntityVariable(THIS, string key, string var)"); { - Object * THIS; - Const_char *id = SvPV_nolen(ST(1)); - const char * var = (const char *)SvPV_nolen(ST(2)); + Object *THIS; + Const_char *id = SvPV_nolen(ST(1)); + const char *var = (const char *) SvPV_nolen(ST(2)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetEntityVariable(id, var); @@ -910,49 +857,46 @@ XS(XS_Object_SetEntityVariable) } XS(XS_Object_GetSolidType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetSolidType) -{ +XS(XS_Object_GetSolidType) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetSolidType(THIS)"); { - Object * THIS; - uint16 RETVAL; + Object *THIS; + uint16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSolidType(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Object_SetSolidType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetSolidType) -{ +XS(XS_Object_SetSolidType) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetSolidType(THIS, type)"); + Perl_croak(aTHX_ "Usage: Object::SetSolidType(THIS, uint16 type)"); { - Object * THIS; - uint16 type = (uint16)SvUV(ST(1)); + Object *THIS; + uint16 type = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSolidType(type); @@ -961,49 +905,46 @@ XS(XS_Object_SetSolidType) } XS(XS_Object_GetSize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetSize) -{ +XS(XS_Object_GetSize) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSize(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Object_SetSize); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetSize) -{ +XS(XS_Object_SetSize) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetSize(THIS, type)"); + Perl_croak(aTHX_ "Usage: Object::SetSize(THIS, float size)"); { - Object * THIS; - float size = (float)SvNV(ST(1)); + Object *THIS; + float size = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetSize(size); @@ -1012,22 +953,20 @@ XS(XS_Object_SetSize) } XS(XS_Object_SetTiltX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetTiltX) -{ +XS(XS_Object_SetTiltX) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetTiltX(THIS, pos)"); + Perl_croak(aTHX_ "Usage: Object::SetTiltX(THIS, float tilt_x)"); { - Object * THIS; - float pos = (float)SvNV(ST(1)); + Object *THIS; + float pos = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetTiltX(pos); @@ -1036,22 +975,20 @@ XS(XS_Object_SetTiltX) } XS(XS_Object_SetTiltY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_SetTiltY) -{ +XS(XS_Object_SetTiltY) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Object::SetTiltY(THIS, pos)"); + Perl_croak(aTHX_ "Usage: Object::SetTiltY(THIS, float tilt_y)"); { - Object * THIS; - float pos = (float)SvNV(ST(1)); + Object *THIS; + float pos = (float) SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetTiltY(pos); @@ -1060,53 +997,51 @@ XS(XS_Object_SetTiltY) } XS(XS_Object_GetTiltX); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetTiltX) -{ +XS(XS_Object_GetTiltX) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTiltX(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } XS(XS_Object_GetTiltY); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Object_GetTiltY) -{ +XS(XS_Object_GetTiltY) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); { - Object * THIS; - float RETVAL; + Object *THIS; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Object *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Object *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Object"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetTiltY(); - XSprePUSH; PUSHn((double)RETVAL); + XSprePUSH; + PUSHn((double) RETVAL); } XSRETURN(1); } @@ -1115,61 +1050,60 @@ XS(XS_Object_GetTiltY) extern "C" #endif XS(boot_Object); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Object) -{ +XS(boot_Object) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; - newXSproto(strcpy(buf, "Depop"),XS_Object_Depop, file, "$"); - newXSproto(strcpy(buf, "Repop"),XS_Object_Repop, file, "$"); - newXSproto(strcpy(buf, "SetModelName"),XS_Object_SetModelName, file, "$$"); - newXSproto(strcpy(buf, "GetModelName"),XS_Object_GetModelName, file, "$"); - newXSproto(strcpy(buf, "GetX"),XS_Object_GetX, file, "$"); - newXSproto(strcpy(buf, "GetY"),XS_Object_GetY, file, "$"); - newXSproto(strcpy(buf, "GetZ"),XS_Object_GetZ, file, "$"); - newXSproto(strcpy(buf, "GetHeading"),XS_Object_GetHeading, file, "$"); - newXSproto(strcpy(buf, "SetX"),XS_Object_SetX, file, "$$"); - newXSproto(strcpy(buf, "SetY"),XS_Object_SetY, file, "$$"); - newXSproto(strcpy(buf, "SetZ"),XS_Object_SetZ, file, "$$"); - newXSproto(strcpy(buf, "SetHeading"),XS_Object_SetHeading, file, "$$"); - newXSproto(strcpy(buf, "SetLocation"),XS_Object_SetLocation, file, "$$$$"); - newXSproto(strcpy(buf, "SetItemID"),XS_Object_SetItemID, file, "$$"); - newXSproto(strcpy(buf, "GetItemID"),XS_Object_GetItemID, file, "$"); - newXSproto(strcpy(buf, "SetIcon"),XS_Object_SetIcon, file, "$$"); - newXSproto(strcpy(buf, "GetIcon"),XS_Object_GetIcon, file, "$"); - newXSproto(strcpy(buf, "SetType"),XS_Object_SetType, file, "$$"); - newXSproto(strcpy(buf, "GetType"),XS_Object_GetType, file, "$"); - newXSproto(strcpy(buf, "GetDBID"),XS_Object_GetDBID, file, "$"); - newXSproto(strcpy(buf, "ClearUser"),XS_Object_ClearUser, file, "$"); - newXSproto(strcpy(buf, "SetID"),XS_Object_SetID, file, "$$"); - newXSproto(strcpy(buf, "GetID"),XS_Object_GetID, file, "$"); - newXSproto(strcpy(buf, "Save"),XS_Object_Save, file, "$"); - newXSproto(strcpy(buf, "VarSave"),XS_Object_VarSave, file, "$"); - newXSproto(strcpy(buf, "DeleteItem"),XS_Object_DeleteItem, file, "$$"); - newXSproto(strcpy(buf, "StartDecay"),XS_Object_StartDecay, file, "$$"); - newXSproto(strcpy(buf, "Delete"),XS_Object_Delete, file, "$$"); - newXSproto(strcpy(buf, "IsGroundSpawn"),XS_Object_IsGroundSpawn, file, "$"); - newXSproto(strcpy(buf, "Close"),XS_Object_Close, file, "$"); - newXSproto(strcpy(buf, "GetEntityVariable"), XS_Object_GetEntityVariable, file, "$$"); - newXSproto(strcpy(buf, "SetEntityVariable"), XS_Object_SetEntityVariable, file, "$$$"); - newXSproto(strcpy(buf, "EntityVariableExists"), XS_Object_EntityVariableExists, file, "$$"); - newXSproto(strcpy(buf, "SetSolidType"),XS_Object_SetSolidType, file, "$$"); - newXSproto(strcpy(buf, "GetSolidType"),XS_Object_GetSolidType, file, "$"); - newXSproto(strcpy(buf, "SetSize"),XS_Object_SetSize, file, "$$"); - newXSproto(strcpy(buf, "GetSize"),XS_Object_GetSize, file, "$"); - newXSproto(strcpy(buf, "SetTiltX"),XS_Object_SetTiltX, file, "$$"); - newXSproto(strcpy(buf, "SetTiltY"),XS_Object_SetTiltY, file, "$"); - newXSproto(strcpy(buf, "GetTiltX"),XS_Object_GetTiltX, file, "$$"); - newXSproto(strcpy(buf, "GetTiltY"),XS_Object_GetTiltY, file, "$"); + XS_VERSION_BOOTCHECK; + newXSproto(strcpy(buf, "Depop"), XS_Object_Depop, file, "$"); + newXSproto(strcpy(buf, "Repop"), XS_Object_Repop, file, "$"); + newXSproto(strcpy(buf, "SetModelName"), XS_Object_SetModelName, file, "$$"); + newXSproto(strcpy(buf, "GetModelName"), XS_Object_GetModelName, file, "$"); + newXSproto(strcpy(buf, "GetX"), XS_Object_GetX, file, "$"); + newXSproto(strcpy(buf, "GetY"), XS_Object_GetY, file, "$"); + newXSproto(strcpy(buf, "GetZ"), XS_Object_GetZ, file, "$"); + newXSproto(strcpy(buf, "GetHeading"), XS_Object_GetHeading, file, "$"); + newXSproto(strcpy(buf, "SetX"), XS_Object_SetX, file, "$$"); + newXSproto(strcpy(buf, "SetY"), XS_Object_SetY, file, "$$"); + newXSproto(strcpy(buf, "SetZ"), XS_Object_SetZ, file, "$$"); + newXSproto(strcpy(buf, "SetHeading"), XS_Object_SetHeading, file, "$$"); + newXSproto(strcpy(buf, "SetLocation"), XS_Object_SetLocation, file, "$$$$"); + newXSproto(strcpy(buf, "SetItemID"), XS_Object_SetItemID, file, "$$"); + newXSproto(strcpy(buf, "GetItemID"), XS_Object_GetItemID, file, "$"); + newXSproto(strcpy(buf, "SetIcon"), XS_Object_SetIcon, file, "$$"); + newXSproto(strcpy(buf, "GetIcon"), XS_Object_GetIcon, file, "$"); + newXSproto(strcpy(buf, "SetType"), XS_Object_SetType, file, "$$"); + newXSproto(strcpy(buf, "GetType"), XS_Object_GetType, file, "$"); + newXSproto(strcpy(buf, "GetDBID"), XS_Object_GetDBID, file, "$"); + newXSproto(strcpy(buf, "ClearUser"), XS_Object_ClearUser, file, "$"); + newXSproto(strcpy(buf, "SetID"), XS_Object_SetID, file, "$$"); + newXSproto(strcpy(buf, "GetID"), XS_Object_GetID, file, "$"); + newXSproto(strcpy(buf, "Save"), XS_Object_Save, file, "$"); + newXSproto(strcpy(buf, "VarSave"), XS_Object_VarSave, file, "$"); + newXSproto(strcpy(buf, "DeleteItem"), XS_Object_DeleteItem, file, "$$"); + newXSproto(strcpy(buf, "StartDecay"), XS_Object_StartDecay, file, "$$"); + newXSproto(strcpy(buf, "Delete"), XS_Object_Delete, file, "$$"); + newXSproto(strcpy(buf, "IsGroundSpawn"), XS_Object_IsGroundSpawn, file, "$"); + newXSproto(strcpy(buf, "Close"), XS_Object_Close, file, "$"); + newXSproto(strcpy(buf, "GetEntityVariable"), XS_Object_GetEntityVariable, file, "$$"); + newXSproto(strcpy(buf, "SetEntityVariable"), XS_Object_SetEntityVariable, file, "$$$"); + newXSproto(strcpy(buf, "EntityVariableExists"), XS_Object_EntityVariableExists, file, "$$"); + newXSproto(strcpy(buf, "SetSolidType"), XS_Object_SetSolidType, file, "$$"); + newXSproto(strcpy(buf, "GetSolidType"), XS_Object_GetSolidType, file, "$"); + newXSproto(strcpy(buf, "SetSize"), XS_Object_SetSize, file, "$$"); + newXSproto(strcpy(buf, "GetSize"), XS_Object_GetSize, file, "$"); + newXSproto(strcpy(buf, "SetTiltX"), XS_Object_SetTiltX, file, "$$"); + newXSproto(strcpy(buf, "SetTiltY"), XS_Object_SetTiltY, file, "$"); + newXSproto(strcpy(buf, "GetTiltX"), XS_Object_GetTiltX, file, "$$"); + newXSproto(strcpy(buf, "GetTiltY"), XS_Object_GetTiltY, file, "$"); XSRETURN_YES; } #endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_player_corpse.cpp b/zone/perl_player_corpse.cpp index a417284c8..69be0f48c 100644 --- a/zone/perl_player_corpse.cpp +++ b/zone/perl_player_corpse.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -42,73 +44,69 @@ XS(XS_Corpse_GetCharID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetCharID) -{ +XS(XS_Corpse_GetCharID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetCharID(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCharID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_GetDecayTime); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetDecayTime) -{ +XS(XS_Corpse_GetDecayTime) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetDecayTime(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetDecayTime(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_Lock); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_Lock) -{ +XS(XS_Corpse_Lock) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::Lock(THIS)"); { - Corpse * THIS; + Corpse *THIS; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Lock(); @@ -117,21 +115,19 @@ XS(XS_Corpse_Lock) } XS(XS_Corpse_UnLock); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_UnLock) -{ +XS(XS_Corpse_UnLock) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::UnLock(THIS)"); { - Corpse * THIS; + Corpse *THIS; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->UnLock(); @@ -140,22 +136,20 @@ XS(XS_Corpse_UnLock) } XS(XS_Corpse_IsLocked); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_IsLocked) -{ +XS(XS_Corpse_IsLocked) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::IsLocked(THIS)"); { - Corpse * THIS; - bool RETVAL; + Corpse *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsLocked(); @@ -166,21 +160,19 @@ XS(XS_Corpse_IsLocked) } XS(XS_Corpse_ResetLooter); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_ResetLooter) -{ +XS(XS_Corpse_ResetLooter) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::ResetLooter(THIS)"); { - Corpse * THIS; + Corpse *THIS; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->ResetLooter(); @@ -189,74 +181,71 @@ XS(XS_Corpse_ResetLooter) } XS(XS_Corpse_GetDBID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetDBID) -{ +XS(XS_Corpse_GetDBID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetDBID(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCorpseDBID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_GetOwnerName); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetOwnerName) -{ +XS(XS_Corpse_GetOwnerName) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetOwnerName(THIS)"); { - Corpse * THIS; - char * RETVAL; + Corpse *THIS; + char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetOwnerName(); - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_Corpse_SetDecayTimer); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_SetDecayTimer) -{ +XS(XS_Corpse_SetDecayTimer) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Corpse::SetDecayTimer(THIS, decaytime)"); + Perl_croak(aTHX_ "Usage: Corpse::SetDecayTimer(THIS, uint32 decay_time)"); { - Corpse * THIS; - uint32 decaytime = (uint32)SvUV(ST(1)); + Corpse *THIS; + uint32 decaytime = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetDecayTimer(decaytime); @@ -265,22 +254,20 @@ XS(XS_Corpse_SetDecayTimer) } XS(XS_Corpse_IsEmpty); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_IsEmpty) -{ +XS(XS_Corpse_IsEmpty) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::IsEmpty(THIS)"); { - Corpse * THIS; - bool RETVAL; + Corpse *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsEmpty(); @@ -291,30 +278,28 @@ XS(XS_Corpse_IsEmpty) } XS(XS_Corpse_AddItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_AddItem) -{ +XS(XS_Corpse_AddItem) { dXSARGS; if (items < 3 || items > 4) - Perl_croak(aTHX_ "Usage: Corpse::AddItem(THIS, itemnum, charges, slot= 0)"); + Perl_croak(aTHX_ "Usage: Corpse::AddItem(THIS, uint32 item_id, uint16 charges, [unt16 slot = 0])"); { - Corpse * THIS; - uint32 itemnum = (uint32)SvUV(ST(1)); - uint16 charges = (uint16)SvUV(ST(2)); - int16 slot; + Corpse *THIS; + uint32 itemnum = (uint32) SvUV(ST(1)); + uint16 charges = (uint16) SvUV(ST(2)); + int16 slot; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (items < 4) slot = 0; else { - slot = (int16)SvIV(ST(3)); + slot = (int16) SvIV(ST(3)); } THIS->AddItem(itemnum, charges, slot); @@ -323,49 +308,46 @@ XS(XS_Corpse_AddItem) } XS(XS_Corpse_GetWornItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetWornItem) -{ +XS(XS_Corpse_GetWornItem) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: Corpse::GetWornItem(THIS, equipSlot)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; - int16 equipSlot = (int16)SvIV(ST(1)); + int16 equipSlot = (int16) SvIV(ST(1)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetWornItem(equipSlot); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_RemoveItem); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_RemoveItem) -{ +XS(XS_Corpse_RemoveItem) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Corpse::RemoveItem(THIS, lootslot)"); + Perl_croak(aTHX_ "Usage: Corpse::RemoveItem(THIS, uint16 loot_slot)"); { - Corpse * THIS; - uint16 lootslot = (uint16)SvUV(ST(1)); + Corpse *THIS; + uint16 lootslot = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveItem(lootslot); @@ -374,25 +356,23 @@ XS(XS_Corpse_RemoveItem) } XS(XS_Corpse_SetCash); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_SetCash) -{ +XS(XS_Corpse_SetCash) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: Corpse::SetCash(THIS, in_copper, in_silver, in_gold, in_platinum)"); + Perl_croak(aTHX_ "Usage: Corpse::SetCash(THIS, uint16 copper, uint16 silver, uint16 gold, uint16 platinum)"); { - Corpse * THIS; - uint16 in_copper = (uint16)SvUV(ST(1)); - uint16 in_silver = (uint16)SvUV(ST(2)); - uint16 in_gold = (uint16)SvUV(ST(3)); - uint16 in_platinum = (uint16)SvUV(ST(4)); + Corpse *THIS; + uint16 in_copper = (uint16) SvUV(ST(1)); + uint16 in_silver = (uint16) SvUV(ST(2)); + uint16 in_gold = (uint16) SvUV(ST(3)); + uint16 in_platinum = (uint16) SvUV(ST(4)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SetCash(in_copper, in_silver, in_gold, in_platinum); @@ -401,21 +381,19 @@ XS(XS_Corpse_SetCash) } XS(XS_Corpse_RemoveCash); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_RemoveCash) -{ +XS(XS_Corpse_RemoveCash) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::RemoveCash(THIS)"); { - Corpse * THIS; + Corpse *THIS; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->RemoveCash(); @@ -424,47 +402,44 @@ XS(XS_Corpse_RemoveCash) } XS(XS_Corpse_CountItems); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_CountItems) -{ +XS(XS_Corpse_CountItems) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::CountItems(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CountItems(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_Delete); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_Delete) -{ +XS(XS_Corpse_Delete) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::Delete(THIS)"); { - Corpse * THIS; + Corpse *THIS; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->Delete(); @@ -473,136 +448,129 @@ XS(XS_Corpse_Delete) } XS(XS_Corpse_GetCopper); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetCopper) -{ +XS(XS_Corpse_GetCopper) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetCopper(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCopper(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_GetSilver); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetSilver) -{ +XS(XS_Corpse_GetSilver) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetSilver(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSilver(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_GetGold); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetGold) -{ +XS(XS_Corpse_GetGold) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetGold(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGold(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_GetPlatinum); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_GetPlatinum) -{ +XS(XS_Corpse_GetPlatinum) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::GetPlatinum(THIS)"); { - Corpse * THIS; - uint32 RETVAL; + Corpse *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetPlatinum(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Corpse_Summon); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_Summon) -{ +XS(XS_Corpse_Summon) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Corpse::Summon(THIS, client, spell)"); + Perl_croak(aTHX_ "Usage: Corpse::Summon(THIS, Client* client, bool is_spell)"); { - Corpse * THIS; - Client* client; - bool spell = (bool)SvTRUE(ST(2)); + Corpse *THIS; + Client *client; + bool spell = (bool) SvTRUE(ST(2)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - client = INT2PTR(Client *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + client = INT2PTR(Client *, tmp); + } else Perl_croak(aTHX_ "client is not of type Client"); - if(client == nullptr) + if (client == nullptr) Perl_croak(aTHX_ "client is nullptr, avoiding crash."); THIS->Summon(client, spell, true); @@ -611,32 +579,29 @@ XS(XS_Corpse_Summon) } XS(XS_Corpse_CastRezz); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_CastRezz) -{ +XS(XS_Corpse_CastRezz) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Corpse::CastRezz(THIS, spellid, Caster)"); + Perl_croak(aTHX_ "Usage: Corpse::CastRezz(THIS, uint16 spell_id, [Mob* caster = nullptr])"); { - Corpse * THIS; - uint16 spellid = (uint16)SvUV(ST(1)); - Mob* Caster; + Corpse *THIS; + uint16 spellid = (uint16) SvUV(ST(1)); + Mob *Caster; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - Caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + Caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "Caster is not of type Mob"); - if(Caster == nullptr) + if (Caster == nullptr) Perl_croak(aTHX_ "Caster is nullptr, avoiding crash."); THIS->CastRezz(spellid, Caster); @@ -645,21 +610,19 @@ XS(XS_Corpse_CastRezz) } XS(XS_Corpse_CompleteRezz); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_CompleteRezz) -{ +XS(XS_Corpse_CompleteRezz) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::CompleteRezz(THIS)"); { - Corpse * THIS; + Corpse *THIS; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->CompleteResurrection(); @@ -668,59 +631,54 @@ XS(XS_Corpse_CompleteRezz) } XS(XS_Corpse_CanMobLoot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_CanMobLoot) -{ +XS(XS_Corpse_CanMobLoot) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Corpse::CanMobLoot(THIS, charid)"); + Perl_croak(aTHX_ "Usage: Corpse::CanMobLoot(THIS, int character_id)"); { - Corpse * THIS; - bool RETVAL; - int charid = (int)SvIV(ST(1)); + Corpse *THIS; + bool RETVAL; + int charid = (int) SvIV(ST(1)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->CanPlayerLoot(charid); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Corpse_AllowMobLoot); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_AllowMobLoot) -{ +XS(XS_Corpse_AllowMobLoot) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Corpse::AllowMobLoot(THIS, them, slot)"); + Perl_croak(aTHX_ "Usage: Corpse::AllowMobLoot(THIS, Mob* them, uint8 slot)"); { - Corpse * THIS; - Mob * them; - uint8 slot = (uint8)SvUV(ST(2)); + Corpse *THIS; + Mob *them; + uint8 slot = (uint8) SvUV(ST(2)); if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - them = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + them = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "them is not of type Mob"); - if(them == nullptr) + if (them == nullptr) Perl_croak(aTHX_ "them is nullptr, avoiding crash."); THIS->AllowPlayerLoot(them, slot); @@ -729,31 +687,28 @@ XS(XS_Corpse_AllowMobLoot) } XS(XS_Corpse_AddLooter); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_AddLooter) -{ +XS(XS_Corpse_AddLooter) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Corpse::AddLooter(THIS, who)"); + Perl_croak(aTHX_ "Usage: Corpse::AddLooter(THIS, Mob* who)"); { - Corpse * THIS; - Mob * who; + Corpse *THIS; + Mob *who; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - who = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + who = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "who is not of type Mob"); - if(who == nullptr) + if (who == nullptr) Perl_croak(aTHX_ "who is nullptr, avoiding crash."); THIS->AddLooter(who); @@ -762,22 +717,20 @@ XS(XS_Corpse_AddLooter) } XS(XS_Corpse_IsRezzed); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Corpse_IsRezzed) -{ +XS(XS_Corpse_IsRezzed) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Corpse::IsRezzed(THIS)"); { - Corpse * THIS; - bool RETVAL; + Corpse *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "Corpse")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Corpse *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Corpse *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Corpse"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsRezzed(); @@ -791,49 +744,48 @@ XS(XS_Corpse_IsRezzed) extern "C" #endif XS(boot_Corpse); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Corpse) -{ +XS(boot_Corpse) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "GetCharID"), XS_Corpse_GetCharID, file, "$"); - newXSproto(strcpy(buf, "GetDecayTime"), XS_Corpse_GetDecayTime, file, "$"); - newXSproto(strcpy(buf, "Lock"), XS_Corpse_Lock, file, "$"); - newXSproto(strcpy(buf, "UnLock"), XS_Corpse_UnLock, file, "$"); - newXSproto(strcpy(buf, "IsLocked"), XS_Corpse_IsLocked, file, "$"); - newXSproto(strcpy(buf, "ResetLooter"), XS_Corpse_ResetLooter, file, "$"); - newXSproto(strcpy(buf, "GetDBID"), XS_Corpse_GetDBID, file, "$"); - newXSproto(strcpy(buf, "GetOwnerName"), XS_Corpse_GetOwnerName, file, "$"); - newXSproto(strcpy(buf, "SetDecayTimer"), XS_Corpse_SetDecayTimer, file, "$$"); - newXSproto(strcpy(buf, "IsEmpty"), XS_Corpse_IsEmpty, file, "$"); - newXSproto(strcpy(buf, "AddItem"), XS_Corpse_AddItem, file, "$$$;$"); - newXSproto(strcpy(buf, "GetWornItem"), XS_Corpse_GetWornItem, file, "$$"); - newXSproto(strcpy(buf, "RemoveItem"), XS_Corpse_RemoveItem, file, "$$"); - newXSproto(strcpy(buf, "SetCash"), XS_Corpse_SetCash, file, "$$$$$"); - newXSproto(strcpy(buf, "RemoveCash"), XS_Corpse_RemoveCash, file, "$"); - newXSproto(strcpy(buf, "CountItems"), XS_Corpse_CountItems, file, "$"); - newXSproto(strcpy(buf, "Delete"), XS_Corpse_Delete, file, "$"); - newXSproto(strcpy(buf, "GetCopper"), XS_Corpse_GetCopper, file, "$"); - newXSproto(strcpy(buf, "GetSilver"), XS_Corpse_GetSilver, file, "$"); - newXSproto(strcpy(buf, "GetGold"), XS_Corpse_GetGold, file, "$"); - newXSproto(strcpy(buf, "GetPlatinum"), XS_Corpse_GetPlatinum, file, "$"); - newXSproto(strcpy(buf, "Summon"), XS_Corpse_Summon, file, "$$$"); - newXSproto(strcpy(buf, "CastRezz"), XS_Corpse_CastRezz, file, "$$$"); - newXSproto(strcpy(buf, "CompleteRezz"), XS_Corpse_CompleteRezz, file, "$"); - newXSproto(strcpy(buf, "CanMobLoot"), XS_Corpse_CanMobLoot, file, "$$"); - newXSproto(strcpy(buf, "AllowMobLoot"), XS_Corpse_AllowMobLoot, file, "$$$"); - newXSproto(strcpy(buf, "AddLooter"), XS_Corpse_AddLooter, file, "$$"); - newXSproto(strcpy(buf, "IsRezzed"), XS_Corpse_IsRezzed, file, "$"); + newXSproto(strcpy(buf, "GetCharID"), XS_Corpse_GetCharID, file, "$"); + newXSproto(strcpy(buf, "GetDecayTime"), XS_Corpse_GetDecayTime, file, "$"); + newXSproto(strcpy(buf, "Lock"), XS_Corpse_Lock, file, "$"); + newXSproto(strcpy(buf, "UnLock"), XS_Corpse_UnLock, file, "$"); + newXSproto(strcpy(buf, "IsLocked"), XS_Corpse_IsLocked, file, "$"); + newXSproto(strcpy(buf, "ResetLooter"), XS_Corpse_ResetLooter, file, "$"); + newXSproto(strcpy(buf, "GetDBID"), XS_Corpse_GetDBID, file, "$"); + newXSproto(strcpy(buf, "GetOwnerName"), XS_Corpse_GetOwnerName, file, "$"); + newXSproto(strcpy(buf, "SetDecayTimer"), XS_Corpse_SetDecayTimer, file, "$$"); + newXSproto(strcpy(buf, "IsEmpty"), XS_Corpse_IsEmpty, file, "$"); + newXSproto(strcpy(buf, "AddItem"), XS_Corpse_AddItem, file, "$$$;$"); + newXSproto(strcpy(buf, "GetWornItem"), XS_Corpse_GetWornItem, file, "$$"); + newXSproto(strcpy(buf, "RemoveItem"), XS_Corpse_RemoveItem, file, "$$"); + newXSproto(strcpy(buf, "SetCash"), XS_Corpse_SetCash, file, "$$$$$"); + newXSproto(strcpy(buf, "RemoveCash"), XS_Corpse_RemoveCash, file, "$"); + newXSproto(strcpy(buf, "CountItems"), XS_Corpse_CountItems, file, "$"); + newXSproto(strcpy(buf, "Delete"), XS_Corpse_Delete, file, "$"); + newXSproto(strcpy(buf, "GetCopper"), XS_Corpse_GetCopper, file, "$"); + newXSproto(strcpy(buf, "GetSilver"), XS_Corpse_GetSilver, file, "$"); + newXSproto(strcpy(buf, "GetGold"), XS_Corpse_GetGold, file, "$"); + newXSproto(strcpy(buf, "GetPlatinum"), XS_Corpse_GetPlatinum, file, "$"); + newXSproto(strcpy(buf, "Summon"), XS_Corpse_Summon, file, "$$$"); + newXSproto(strcpy(buf, "CastRezz"), XS_Corpse_CastRezz, file, "$$$"); + newXSproto(strcpy(buf, "CompleteRezz"), XS_Corpse_CompleteRezz, file, "$"); + newXSproto(strcpy(buf, "CanMobLoot"), XS_Corpse_CanMobLoot, file, "$$"); + newXSproto(strcpy(buf, "AllowMobLoot"), XS_Corpse_AllowMobLoot, file, "$$$"); + newXSproto(strcpy(buf, "AddLooter"), XS_Corpse_AddLooter, file, "$$"); + newXSproto(strcpy(buf, "IsRezzed"), XS_Corpse_IsRezzed, file, "$"); XSRETURN_YES; } diff --git a/zone/perl_questitem.cpp b/zone/perl_questitem.cpp index 742a00814..6d728e65e 100644 --- a/zone/perl_questitem.cpp +++ b/zone/perl_questitem.cpp @@ -18,7 +18,9 @@ #include "../common/features.h" #include "client.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -28,7 +30,7 @@ #include "../common/item_instance.h" -#ifdef THIS /* this macro seems to leak out on some systems */ +#ifdef THIS /* this macro seems to leak out on some systems */ #undef THIS #endif @@ -38,76 +40,73 @@ XS(XS_QuestItem_GetName) { if (items != 1) Perl_croak(aTHX_ "Usage: QuestItem::GetName(THIS)"); { - EQEmu::ItemInstance * THIS; - Const_char * RETVAL; + EQEmu::ItemInstance *THIS; + Const_char *RETVAL; dXSTARG; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetItem()->Name; - sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + sv_setpv(TARG, RETVAL); + XSprePUSH; + PUSHTARG; } XSRETURN(1); } XS(XS_QuestItem_SetScale); -XS(XS_QuestItem_SetScale) -{ +XS(XS_QuestItem_SetScale) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: QuestItem::SetScale(THIS, scale factor)"); + Perl_croak(aTHX_ "Usage: QuestItem::SetScale(THIS, float scale_multiplier)"); { - EQEmu::ItemInstance * THIS; - float Mult; + EQEmu::ItemInstance *THIS; + float Mult; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - Mult = (float)SvNV(ST(1)); + Mult = (float) SvNV(ST(1)); - if(THIS->IsScaling()) { - THIS->SetExp((int)(Mult*10000+.5)); + if (THIS->IsScaling()) { + THIS->SetExp((int) (Mult * 10000 + .5)); } } XSRETURN_EMPTY; } XS(XS_QuestItem_ItemSay); -XS(XS_QuestItem_ItemSay) -{ +XS(XS_QuestItem_ItemSay) { dXSARGS; if (items != 2 && items != 3) - Perl_croak(aTHX_ "Usage: QuestItem::ItemSay(THIS, text [, language])"); + Perl_croak(aTHX_ "Usage: QuestItem::ItemSay(THIS, string text [int language_id])"); { - EQEmu::ItemInstance* THIS; - Const_char* text; - int lang = 0; + EQEmu::ItemInstance *THIS; + Const_char *text; + int lang = 0; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - text = SvPV_nolen(ST(1)); - if(items == 3) - lang = (int)SvUV(ST(2)); + text = SvPV_nolen(ST(1)); + if (items == 3) + lang = (int) SvUV(ST(2)); quest_manager.GetInitiator()->ChannelMessageSend(THIS->GetItem()->Name, 0, 8, lang, 100, text); } @@ -115,49 +114,45 @@ XS(XS_QuestItem_ItemSay) } XS(XS_QuestItem_IsType); /* prototype to pass -Wmissing-prototypes */ -XS(XS_QuestItem_IsType) -{ +XS(XS_QuestItem_IsType) { dXSARGS; if (items != 2) Perl_croak(aTHX_ "Usage: QuestItem::IsType(THIS, type)"); { - EQEmu::ItemInstance* THIS; - bool RETVAL; - uint32 type = (int32)SvIV(ST(1)); + EQEmu::ItemInstance *THIS; + bool RETVAL; + uint32 type = (int32) SvIV(ST(1)); if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->IsType((EQEmu::item::ItemClass)type); - ST(0) = boolSV(RETVAL); + RETVAL = THIS->IsType((EQEmu::item::ItemClass) type); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_QuestItem_IsAttuned); /* prototype to pass -Wmissing-prototypes */ -XS(XS_QuestItem_IsAttuned) -{ +XS(XS_QuestItem_IsAttuned) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: QuestItem::IsAttuned(THIS)"); { - EQEmu::ItemInstance* THIS; - bool RETVAL; + EQEmu::ItemInstance *THIS; + bool RETVAL; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsAttuned(); @@ -168,80 +163,76 @@ XS(XS_QuestItem_IsAttuned) } XS(XS_QuestItem_GetCharges); /* prototype to pass -Wmissing-prototypes */ -XS(XS_QuestItem_GetCharges) -{ +XS(XS_QuestItem_GetCharges) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: QuestItem::GetCharges(THIS)"); { - EQEmu::ItemInstance* THIS; - int16 RETVAL; + EQEmu::ItemInstance *THIS; + int16 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetCharges(); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } XS(XS_QuestItem_GetAugment); /* prototype to pass -Wmissing-prototypes */ -XS(XS_QuestItem_GetAugment) -{ +XS(XS_QuestItem_GetAugment) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: QuestItem::GetAugment(THIS, augment_id)"); + Perl_croak(aTHX_ "Usage: QuestItem::GetAugment(THIS, int16 slot_id)"); { - EQEmu::ItemInstance* THIS; - int16 slot_id = (int16)SvIV(ST(1)); - EQEmu::ItemInstance* RETVAL; + EQEmu::ItemInstance *THIS; + int16 slot_id = (int16) SvIV(ST(1)); + EQEmu::ItemInstance *RETVAL; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetAugment(slot_id); ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "QuestItem", (void*)RETVAL); + sv_setref_pv(ST(0), "QuestItem", (void *) RETVAL); } XSRETURN(1); } XS(XS_QuestItem_GetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_QuestItem_GetID) -{ +XS(XS_QuestItem_GetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: QuestItem::GetID(THIS)"); { - EQEmu::ItemInstance* THIS; - uint32 RETVAL; + EQEmu::ItemInstance *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "QuestItem")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(EQEmu::ItemInstance *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(EQEmu::ItemInstance *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type EQEmu::ItemInstance"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetItem()->ID; - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + PUSHi((IV) RETVAL); } XSRETURN(1); } @@ -251,29 +242,28 @@ extern "C" #endif XS(boot_QuestItem); -XS(boot_QuestItem) -{ +XS(boot_QuestItem) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "GetName"), XS_QuestItem_GetName, file, "$"); - newXSproto(strcpy(buf, "SetScale"), XS_QuestItem_SetScale, file, "$"); - newXSproto(strcpy(buf, "ItemSay"), XS_QuestItem_ItemSay, file, "$"); - newXSproto(strcpy(buf, "IsType"), XS_QuestItem_IsType, file, "$$"); - newXSproto(strcpy(buf, "IsAttuned"), XS_QuestItem_IsAttuned, file, "$"); - newXSproto(strcpy(buf, "GetCharges"), XS_QuestItem_GetCharges, file, "$"); - newXSproto(strcpy(buf, "GetAugment"), XS_QuestItem_GetAugment, file, "$$"); - newXSproto(strcpy(buf, "GetID"), XS_QuestItem_GetID, file, "$"); + newXSproto(strcpy(buf, "GetName"), XS_QuestItem_GetName, file, "$"); + newXSproto(strcpy(buf, "SetScale"), XS_QuestItem_SetScale, file, "$"); + newXSproto(strcpy(buf, "ItemSay"), XS_QuestItem_ItemSay, file, "$"); + newXSproto(strcpy(buf, "IsType"), XS_QuestItem_IsType, file, "$$"); + newXSproto(strcpy(buf, "IsAttuned"), XS_QuestItem_IsAttuned, file, "$"); + newXSproto(strcpy(buf, "GetCharges"), XS_QuestItem_GetCharges, file, "$"); + newXSproto(strcpy(buf, "GetAugment"), XS_QuestItem_GetAugment, file, "$$"); + newXSproto(strcpy(buf, "GetID"), XS_QuestItem_GetID, file, "$"); XSRETURN_YES; } diff --git a/zone/perl_raids.cpp b/zone/perl_raids.cpp index 60d94600a..f5b91448e 100644 --- a/zone/perl_raids.cpp +++ b/zone/perl_raids.cpp @@ -26,7 +26,9 @@ */ #include "../common/features.h" + #ifdef EMBPERL_XS_CLASSES + #include "../common/global_define.h" #include "embperl.h" @@ -43,60 +45,55 @@ XS(XS_Raid_IsRaidMember); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_IsRaidMember) -{ +XS(XS_Raid_IsRaidMember) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::IsRaidMember(THIS, name)"); + Perl_croak(aTHX_ "Usage: Raid::IsRaidMember(THIS, string name)"); { - Raid * THIS; - bool RETVAL; - const char* name = (char *)SvPV_nolen(ST(1)); + Raid *THIS; + bool RETVAL; + const char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsRaidMember(name); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Raid_CastGroupSpell); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_CastGroupSpell) -{ +XS(XS_Raid_CastGroupSpell) { dXSARGS; if (items != 4) - Perl_croak(aTHX_ "Usage: Raid::CastGroupSpell(THIS, caster, spellid, gid)"); + Perl_croak(aTHX_ "Usage: Raid::CastGroupSpell(THIS, Mob* caster, uint16 spell_id, uint32 group_id)"); { - Raid * THIS; - Mob* caster; - uint16 spellid = (uint16)SvUV(ST(2)); - uint32 gid = (uint32)SvUV(ST(3)); + Raid *THIS; + Mob *caster; + uint16 spellid = (uint16) SvUV(ST(2)); + uint32 gid = (uint32) SvUV(ST(3)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - caster = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + caster = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "caster is not of type Mob"); - if(caster == nullptr) + if (caster == nullptr) Perl_croak(aTHX_ "caster is nullptr, avoiding crash."); THIS->CastGroupSpell(caster, spellid, gid); @@ -105,112 +102,106 @@ XS(XS_Raid_CastGroupSpell) } XS(XS_Raid_GroupCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GroupCount) -{ +XS(XS_Raid_GroupCount) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::GroupCount(THIS, gid)"); + Perl_croak(aTHX_ "Usage: Raid::GroupCount(THIS, uint32 group_id)"); { - Raid * THIS; - uint8 RETVAL; + Raid *THIS; + uint8 RETVAL; dXSTARG; - uint32 gid = (uint32)SvUV(ST(1)); + uint32 gid = (uint32) SvUV(ST(1)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GroupCount(gid); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_RaidCount); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_RaidCount) -{ +XS(XS_Raid_RaidCount) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Raid::RaidCount(THIS)"); { - Raid * THIS; - uint8 RETVAL; + Raid *THIS; + uint8 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->RaidCount(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_GetGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GetGroup) -{ +XS(XS_Raid_GetGroup) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::GetGroup(THIS, name)"); + Perl_croak(aTHX_ "Usage: Raid::GetGroup(THIS, string name)"); { - Raid * THIS; - uint32 RETVAL; + Raid *THIS; + uint32 RETVAL; dXSTARG; - const char* name = (char *)SvPV_nolen(ST(1)); + const char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetGroup(name); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_SplitExp); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_SplitExp) -{ +XS(XS_Raid_SplitExp) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Raid::SplitExp(THIS, exp, other)"); + Perl_croak(aTHX_ "Usage: Raid::SplitExp(THIS, uint32 experience, [Mob* other = nullptr])"); { - Raid * THIS; - uint32 exp = (uint32)SvUV(ST(1)); - Mob* other; + Raid *THIS; + uint32 exp = (uint32) SvUV(ST(1)); + Mob *other; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(2), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(2))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(2))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); THIS->SplitExp(exp, other); @@ -219,61 +210,57 @@ XS(XS_Raid_SplitExp) } XS(XS_Raid_GetTotalRaidDamage); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GetTotalRaidDamage) -{ +XS(XS_Raid_GetTotalRaidDamage) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::GetTotalRaidDamage(THIS, other)"); + Perl_croak(aTHX_ "Usage: Raid::GetTotalRaidDamage(THIS, [Mob* other = nullptr])"); { - Raid * THIS; - uint32 RETVAL; + Raid *THIS; + uint32 RETVAL; dXSTARG; - Mob* other; + Mob *other; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - other = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + other = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "other is not of type Mob"); - if(other == nullptr) + if (other == nullptr) Perl_croak(aTHX_ "other is nullptr, avoiding crash."); RETVAL = THIS->GetTotalRaidDamage(other); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_SplitMoney); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_SplitMoney) -{ +XS(XS_Raid_SplitMoney) { dXSARGS; if (items != 5) - Perl_croak(aTHX_ "Usage: Raid::SplitMoney(THIS, copper, silver, gold, platinum)"); + Perl_croak(aTHX_ "Usage: Raid::SplitMoney(THIS, uint32 copper, uint32 silver, uint32 gold, uint32 platinum)"); { - Raid * THIS; - uint32 copper = (uint32)SvUV(ST(1)); - uint32 silver = (uint32)SvUV(ST(2)); - uint32 gold = (uint32)SvUV(ST(3)); - uint32 platinum = (uint32)SvUV(ST(4)); + Raid *THIS; + uint32 copper = (uint32) SvUV(ST(1)); + uint32 silver = (uint32) SvUV(ST(2)); + uint32 gold = (uint32) SvUV(ST(3)); + uint32 platinum = (uint32) SvUV(ST(4)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->SplitMoney(copper, silver, gold, platinum); @@ -282,23 +269,21 @@ XS(XS_Raid_SplitMoney) } XS(XS_Raid_BalanceHP); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_BalanceHP) -{ +XS(XS_Raid_BalanceHP) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: Raid::BalanceHP(THIS, penalty, gid)"); + Perl_croak(aTHX_ "Usage: Raid::BalanceHP(THIS, int32 penalty, uint32 group_id)"); { - Raid * THIS; - int32 penalty = (int32)SvUV(ST(1)); - uint32 gid = (uint32)SvUV(ST(2)); + Raid *THIS; + int32 penalty = (int32) SvUV(ST(1)); + uint32 gid = (uint32) SvUV(ST(2)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); THIS->BalanceHP(penalty, gid); @@ -307,170 +292,160 @@ XS(XS_Raid_BalanceHP) } XS(XS_Raid_IsLeader); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_IsLeader) -{ +XS(XS_Raid_IsLeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::IsLeader(THIS, name)"); + Perl_croak(aTHX_ "Usage: Raid::IsLeader(THIS, string name)"); { - Raid * THIS; - bool RETVAL; - const char* name = (char *)SvPV_nolen(ST(1)); + Raid *THIS; + bool RETVAL; + const char *name = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsLeader(name); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Raid_IsGroupLeader); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_IsGroupLeader) -{ +XS(XS_Raid_IsGroupLeader) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::IsGroupLeader(THIS, who)"); + Perl_croak(aTHX_ "Usage: Raid::IsGroupLeader(THIS, string name)"); { - Raid * THIS; - bool RETVAL; - const char* who = (char *)SvPV_nolen(ST(1)); + Raid *THIS; + bool RETVAL; + const char *who = (char *) SvPV_nolen(ST(1)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->IsGroupLeader(who); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); } XS(XS_Raid_GetHighestLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GetHighestLevel) -{ +XS(XS_Raid_GetHighestLevel) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Raid::GetHighestLevel(THIS)"); { - Raid * THIS; - uint32 RETVAL; + Raid *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetHighestLevel(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_GetLowestLevel); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GetLowestLevel) -{ +XS(XS_Raid_GetLowestLevel) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Raid::GetLowestLevel(THIS)"); { - Raid * THIS; - uint32 RETVAL; + Raid *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetLowestLevel(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_GetClientByIndex); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GetClientByIndex) -{ +XS(XS_Raid_GetClientByIndex) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::GetClientByIndex(THIS, index)"); + Perl_croak(aTHX_ "Usage: Raid::GetClientByIndex(THIS, uint16 raid_indez)"); { - Raid * THIS; - Client * RETVAL; - uint16 index = (uint16)SvUV(ST(1)); + Raid *THIS; + Client *RETVAL; + uint16 index = (uint16) SvUV(ST(1)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetClientByIndex(index); - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } XS(XS_Raid_TeleportGroup); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_TeleportGroup) -{ +XS(XS_Raid_TeleportGroup) { dXSARGS; if (items != 8) - Perl_croak(aTHX_ "Usage: Raid::TeleportGroup(THIS, sender, zoneID, x, y, z, heading, gid)"); + Perl_croak(aTHX_ + "Usage: Raid::TeleportGroup(THIS, Mob* sender, uint32 zone_id, float x, float y, float z, float heading, uint32 group_id)"); { - Raid * THIS; - Mob* sender; - uint32 zoneID = (uint32)SvUV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); - float heading = (float)SvNV(ST(6)); - uint32 gid = (uint32)SvUV(ST(7)); + Raid *THIS; + Mob *sender; + uint32 zoneID = (uint32) SvUV(ST(2)); + float x = (float) SvNV(ST(3)); + float y = (float) SvNV(ST(4)); + float z = (float) SvNV(ST(5)); + float heading = (float) SvNV(ST(6)); + uint32 gid = (uint32) SvUV(ST(7)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - sender = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + sender = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "sender is not of type Mob"); - if(sender == nullptr) + if (sender == nullptr) Perl_croak(aTHX_ "sender is nullptr, avoiding crash."); THIS->TeleportGroup(sender, zoneID, 0, x, y, z, heading, gid); @@ -479,36 +454,34 @@ XS(XS_Raid_TeleportGroup) } XS(XS_Raid_TeleportRaid); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_TeleportRaid) -{ +XS(XS_Raid_TeleportRaid) { dXSARGS; if (items != 7) - Perl_croak(aTHX_ "Usage: Raid::TeleportRaid(THIS, sender, zoneID, x, y, z, heading)"); + Perl_croak(aTHX_ + "Usage: Raid::TeleportRaid(THIS, Mob* sender, uint32 zone_id, float x, float y, float z, float heading)"); { - Raid * THIS; - Mob* sender; - uint32 zoneID = (uint32)SvUV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); - float heading = (float)SvNV(ST(6)); + Raid *THIS; + Mob *sender; + uint32 zoneID = (uint32) SvUV(ST(2)); + float x = (float) SvNV(ST(3)); + float y = (float) SvNV(ST(4)); + float z = (float) SvNV(ST(5)); + float heading = (float) SvNV(ST(6)); if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); if (sv_derived_from(ST(1), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(1))); - sender = INT2PTR(Mob *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(1))); + sender = INT2PTR(Mob *, tmp); + } else Perl_croak(aTHX_ "sender is not of type Mob"); - if(sender == nullptr) + if (sender == nullptr) Perl_croak(aTHX_ "sender is nullptr, avoiding crash."); THIS->TeleportRaid(sender, zoneID, 0, x, y, z, heading); @@ -517,61 +490,58 @@ XS(XS_Raid_TeleportRaid) } XS(XS_Raid_GetID); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Raid_GetID) -{ +XS(XS_Raid_GetID) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: Raid::GetID(THIS)"); { - Raid * THIS; - uint32 RETVAL; + Raid *THIS; + uint32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetID(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; + PUSHu((UV) RETVAL); } XSRETURN(1); } XS(XS_Raid_GetMember); -XS(XS_Raid_GetMember) -{ +XS(XS_Raid_GetMember) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Raid::GetMember(THIS, index)"); + Perl_croak(aTHX_ "Usage: Raid::GetMember(THIS, int raid_index)"); { - Raid * THIS; - Client* RETVAL = nullptr; + Raid *THIS; + Client *RETVAL = nullptr; dXSTARG; if (sv_derived_from(ST(0), "Raid")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Raid *,tmp); - } - else + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Raid *, tmp); + } else Perl_croak(aTHX_ "THIS is not of type Raid"); - if(THIS == nullptr) + if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - int index = (int)SvUV(ST(1)); + int index = (int) SvUV(ST(1)); if (index < 0 || index > 71) RETVAL = nullptr; else { - if(THIS->members[index].member != nullptr) + if (THIS->members[index].member != nullptr) RETVAL = THIS->members[index].member->CastToClient(); } - ST(0) = sv_newmortal(); - sv_setref_pv(ST(0), "Client", (void*)RETVAL); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Client", (void *) RETVAL); } XSRETURN(1); } @@ -580,39 +550,38 @@ XS(XS_Raid_GetMember) extern "C" #endif XS(boot_Raid); /* prototype to pass -Wmissing-prototypes */ -XS(boot_Raid) -{ +XS(boot_Raid) { dXSARGS; char file[256]; strncpy(file, __FILE__, 256); file[255] = 0; - if(items != 1) + if (items != 1) fprintf(stderr, "boot_quest does not take any arguments."); char buf[128]; //add the strcpy stuff to get rid of const warnings.... - XS_VERSION_BOOTCHECK ; + XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "IsRaidMember"), XS_Raid_IsRaidMember, file, "$$"); - newXSproto(strcpy(buf, "CastGroupSpell"), XS_Raid_CastGroupSpell, file, "$$$$"); - newXSproto(strcpy(buf, "GroupCount"), XS_Raid_GroupCount, file, "$$"); - newXSproto(strcpy(buf, "RaidCount"), XS_Raid_RaidCount, file, "$"); - newXSproto(strcpy(buf, "GetGroup"), XS_Raid_GetGroup, file, "$$"); - newXSproto(strcpy(buf, "SplitExp"), XS_Raid_SplitExp, file, "$$$"); - newXSproto(strcpy(buf, "GetTotalRaidDamage"), XS_Raid_GetTotalRaidDamage, file, "$$"); - newXSproto(strcpy(buf, "SplitMoney"), XS_Raid_SplitMoney, file, "$$$$$"); - newXSproto(strcpy(buf, "BalanceHP"), XS_Raid_BalanceHP, file, "$$$"); - newXSproto(strcpy(buf, "IsLeader"), XS_Raid_IsLeader, file, "$$"); - newXSproto(strcpy(buf, "IsGroupLeader"), XS_Raid_IsGroupLeader, file, "$$"); - newXSproto(strcpy(buf, "GetHighestLevel"), XS_Raid_GetHighestLevel, file, "$"); - newXSproto(strcpy(buf, "GetLowestLevel"), XS_Raid_GetLowestLevel, file, "$"); - newXSproto(strcpy(buf, "GetClientByIndex"), XS_Raid_GetClientByIndex, file, "$$"); - newXSproto(strcpy(buf, "TeleportGroup"), XS_Raid_TeleportGroup, file, "$$$$$$$$"); - newXSproto(strcpy(buf, "TeleportRaid"), XS_Raid_TeleportRaid, file, "$$$$$$$"); - newXSproto(strcpy(buf, "GetID"), XS_Raid_GetID, file, "$"); - newXSproto(strcpy(buf, "GetMember"), XS_Raid_GetMember, file, "$$"); + newXSproto(strcpy(buf, "IsRaidMember"), XS_Raid_IsRaidMember, file, "$$"); + newXSproto(strcpy(buf, "CastGroupSpell"), XS_Raid_CastGroupSpell, file, "$$$$"); + newXSproto(strcpy(buf, "GroupCount"), XS_Raid_GroupCount, file, "$$"); + newXSproto(strcpy(buf, "RaidCount"), XS_Raid_RaidCount, file, "$"); + newXSproto(strcpy(buf, "GetGroup"), XS_Raid_GetGroup, file, "$$"); + newXSproto(strcpy(buf, "SplitExp"), XS_Raid_SplitExp, file, "$$$"); + newXSproto(strcpy(buf, "GetTotalRaidDamage"), XS_Raid_GetTotalRaidDamage, file, "$$"); + newXSproto(strcpy(buf, "SplitMoney"), XS_Raid_SplitMoney, file, "$$$$$"); + newXSproto(strcpy(buf, "BalanceHP"), XS_Raid_BalanceHP, file, "$$$"); + newXSproto(strcpy(buf, "IsLeader"), XS_Raid_IsLeader, file, "$$"); + newXSproto(strcpy(buf, "IsGroupLeader"), XS_Raid_IsGroupLeader, file, "$$"); + newXSproto(strcpy(buf, "GetHighestLevel"), XS_Raid_GetHighestLevel, file, "$"); + newXSproto(strcpy(buf, "GetLowestLevel"), XS_Raid_GetLowestLevel, file, "$"); + newXSproto(strcpy(buf, "GetClientByIndex"), XS_Raid_GetClientByIndex, file, "$$"); + newXSproto(strcpy(buf, "TeleportGroup"), XS_Raid_TeleportGroup, file, "$$$$$$$$"); + newXSproto(strcpy(buf, "TeleportRaid"), XS_Raid_TeleportRaid, file, "$$$$$$$"); + newXSproto(strcpy(buf, "GetID"), XS_Raid_GetID, file, "$"); + newXSproto(strcpy(buf, "GetMember"), XS_Raid_GetMember, file, "$$"); XSRETURN_YES; } diff --git a/zone/pets.cpp b/zone/pets.cpp index be17a3293..e4f7c417b 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -385,12 +385,12 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, // the base items for the pet. These are always loaded // so that a rank 1 suspend minion does not kill things // like the special back items some focused pets may receive. - uint32 petinv[EQEmu::legacy::EQUIPMENT_SIZE]; + uint32 petinv[EQEmu::invslot::EQUIPMENT_COUNT]; memset(petinv, 0, sizeof(petinv)); const EQEmu::ItemData *item = nullptr; if (database.GetBasePetItems(record.equipmentset, petinv)) { - for (int i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++) + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) if (petinv[i]) { item = database.GetItem(petinv[i]); npc->AddLootDrop(item, &npc->itemlist, 0, 1, 127, true, true); @@ -524,7 +524,7 @@ void NPC::GetPetState(SpellBuff_Struct *pet_buffs, uint32 *items, char *name) { strn0cpy(name, GetName(), 64); //save their items, we only care about what they are actually wearing - memcpy(items, equipment, sizeof(uint32) * EQEmu::legacy::EQUIPMENT_SIZE); + memcpy(items, equipment, sizeof(uint32) * EQEmu::invslot::EQUIPMENT_COUNT); //save their buffs. for (int i=0; i < GetPetMaxTotalSlots(); i++) { @@ -612,7 +612,7 @@ void NPC::SetPetState(SpellBuff_Struct *pet_buffs, uint32 *items) { } //restore their equipment... - for (i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++) { + for (i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) { if(items[i] == 0) continue; @@ -679,7 +679,7 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) { { slot = atoi(row[0]); - if (slot >= EQEmu::legacy::EQUIPMENT_SIZE) + if (slot > EQEmu::invslot::EQUIPMENT_END) continue; if (items[slot] == 0) diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index d6e8a004c..1393b0221 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -779,79 +779,6 @@ void QuestManager::repopzone() { } } -void QuestManager::ConnectNodeToNode(int node1, int node2, int teleport, int doorid) { - if (!node1 || !node2) - { - Log(Logs::General, Logs::Quests, "QuestManager::ConnectNodeToNode called without node1 or node2. Probably syntax error in quest file."); - } - else - { - if (!teleport) - { - teleport = 0; - } - else if (teleport == 1 || teleport == -1) - { - teleport = -1; - } - - if (!doorid) - { - doorid = 0; - } - - if (!zone->pathing) - { - // if no pathing bits available, make them available. - zone->pathing = new PathManager(); - } - - if (zone->pathing) - { - zone->pathing->ConnectNodeToNode(node1, node2, teleport, doorid); - Log(Logs::Moderate, Logs::Quests, "QuestManager::ConnectNodeToNode connecting node %i to node %i.", node1, node2); - } - } -} - -void QuestManager::AddNode(float x, float y, float z, float best_z, int32 requested_id) -{ - if (!x || !y || !z) - { - Log(Logs::General, Logs::Quests, "QuestManager::AddNode called without x, y, z. Probably syntax error in quest file."); - } - - if (!best_z || best_z == 0) - { - if (zone->zonemap) - { - glm::vec3 loc(x, y, z); - best_z = zone->zonemap->FindBestZ(loc, nullptr); - } - else - { - best_z = z; - } - } - - if (!requested_id) - { - requested_id = 0; - } - - if (!zone->pathing) - { - // if no pathing bits available, make them available. - zone->pathing = new PathManager(); - } - - if (zone->pathing) - { - zone->pathing->AddNode(x, y, z, best_z, requested_id); - Log(Logs::Moderate, Logs::Quests, "QuestManager::AddNode adding node at (%i, %i, %i).", x, y, z); - } -} - void QuestManager::settarget(const char *type, int target_id) { QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) @@ -2222,7 +2149,7 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level void QuestManager::taskselector(int taskcount, int *tasks) { QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner && taskmanager) - taskmanager->SendTaskSelector(initiator, owner, taskcount, tasks); + initiator->TaskQuestSetSelector(owner, taskcount, tasks); } void QuestManager::enabletask(int taskcount, int *tasks) { QuestManagerCurrentQuestVars(); @@ -2551,12 +2478,12 @@ int QuestManager::collectitems(uint32 item_id, bool remove) int quantity = 0; int slot_id; - for (slot_id = EQEmu::legacy::GENERAL_BEGIN; slot_id <= EQEmu::legacy::GENERAL_END; ++slot_id) + for (slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) { quantity += collectitems_processSlot(slot_id, item_id, remove); } - for (slot_id = EQEmu::legacy::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::legacy::GENERAL_BAGS_END; ++slot_id) + for (slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::GENERAL_BAGS_END; ++slot_id) { quantity += collectitems_processSlot(slot_id, item_id, remove); } diff --git a/zone/questmgr.h b/zone/questmgr.h index 93ba8267d..a3b9fac43 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -100,8 +100,6 @@ public: void depopall(int npc_type = 0); void depopzone(bool StartSpawnTimer = true); void repopzone(); - void ConnectNodeToNode(int node1, int node2, int teleport, int doorid); - void AddNode(float x, float y, float z, float best_z, int32 requested_id); void settarget(const char *type, int target_id); void follow(int entity_id, int distance); void sfollow(); diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 7c91c97a7..538934694 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -48,7 +48,7 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) base++; return base; case EQEmu::skills::SkillFrenzy: - if (IsClient() && CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary)) { + if (IsClient() && CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary)) { if (GetLevel() > 15) base += GetLevel() - 15; if (base > 23) @@ -65,7 +65,7 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) float skill_bonus = skill_level / 9.0f; float ac_bonus = 0.0f; if (IsClient()) { - auto inst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotFeet); + auto inst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotFeet); if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; } @@ -78,7 +78,7 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) float skill_bonus = skill_level / 10.0f; float ac_bonus = 0.0f; if (IsClient()) { - auto inst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotFeet); + auto inst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotFeet); if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; } @@ -92,9 +92,9 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) const EQEmu::ItemInstance *inst = nullptr; if (IsClient()) { if (HasShieldEquiped()) - inst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary); + inst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotSecondary); else if (HasTwoHanderEquipped()) - inst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); + inst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); } if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; @@ -109,7 +109,7 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) base = 3; // There seems to be a base 3 for NPCs or some how BS w/o weapon? // until we get a better inv system for NPCs they get nerfed! if (IsClient()) { - auto *inst = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); + auto *inst = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if (inst && inst->GetItem() && inst->GetItem()->ItemType == EQEmu::item::ItemType1HPiercing) { base = inst->GetItemBackstabDamage(true); if (!inst->GetItemBackstabDamage()) @@ -168,7 +168,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 if (skill == EQEmu::skills::SkillBash) { if (IsClient()) { - EQEmu::ItemInstance *item = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary); + EQEmu::ItemInstance *item = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotSecondary); if (item) { if (item->GetItem()->ItemType == EQEmu::item::ItemTypeShield) { hate += item->GetItem()->AC; @@ -185,10 +185,10 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 my_hit.offense = offense(my_hit.skill); my_hit.tohit = GetTotalToHit(my_hit.skill, 0); - my_hit.hand = EQEmu::inventory::slotPrimary; // Avoid checks hand for throwing/archery exclusion, primary should + my_hit.hand = EQEmu::invslot::slotPrimary; // Avoid checks hand for throwing/archery exclusion, primary should // work for most if (skill == EQEmu::skills::SkillThrowing || skill == EQEmu::skills::SkillArchery) - my_hit.hand = EQEmu::inventory::slotRange; + my_hit.hand = EQEmu::invslot::slotRange; DoAttack(who, my_hit); @@ -259,7 +259,7 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) // These two are not subject to the combat ability timer, as they // allready do their checking in conjunction with the attack timer // throwing weapons - if (ca_atk->m_atk == EQEmu::inventory::slotRange) { + if (ca_atk->m_atk == EQEmu::invslot::slotRange) { if (ca_atk->m_skill == EQEmu::skills::SkillThrowing) { SetAttackTimer(); ThrowingAttack(GetTarget()); @@ -309,8 +309,8 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) DoAnim(animTailRake, 0, false); int32 ht = 0; - if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::inventory::slotSecondary)) <= 0 && - GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::inventory::slotShoulders)) <= 0) + if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::invslot::slotSecondary)) <= 0 && + GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::invslot::slotShoulders)) <= 0) dmg = -5; else ht = dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash, GetTarget()); @@ -366,7 +366,7 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) DoAnim(animKick, 0, false); int32 ht = 0; - if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::inventory::slotFeet)) <= 0) + if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQEmu::invslot::slotFeet)) <= 0) dmg = -5; else ht = dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick, GetTarget()); @@ -445,7 +445,7 @@ int Mob::MonkSpecialAttack(Mob *other, uint8 unchecked_type) int32 min_dmg = 0; int reuse = 0; EQEmu::skills::SkillType skill_type; // to avoid casting... even though it "would work" - uint8 itemslot = EQEmu::inventory::slotFeet; + uint8 itemslot = EQEmu::invslot::slotFeet; if (IsNPC()) { auto *npc = CastToNPC(); min_dmg = npc->GetMinDamage(); @@ -462,21 +462,21 @@ int Mob::MonkSpecialAttack(Mob *other, uint8 unchecked_type) case EQEmu::skills::SkillDragonPunch: skill_type = EQEmu::skills::SkillDragonPunch; max_dmg = GetBaseSkillDamage(skill_type); - itemslot = EQEmu::inventory::slotHands; + itemslot = EQEmu::invslot::slotHands; DoAnim(animTailRake, 0, false); reuse = TailRakeReuseTime; break; case EQEmu::skills::SkillEagleStrike: skill_type = EQEmu::skills::SkillEagleStrike; max_dmg = GetBaseSkillDamage(skill_type); - itemslot = EQEmu::inventory::slotHands; + itemslot = EQEmu::invslot::slotHands; DoAnim(animEagleStrike, 0, false); reuse = EagleStrikeReuseTime; break; case EQEmu::skills::SkillTigerClaw: skill_type = EQEmu::skills::SkillTigerClaw; max_dmg = GetBaseSkillDamage(skill_type); - itemslot = EQEmu::inventory::slotHands; + itemslot = EQEmu::invslot::slotHands; DoAnim(animTigerClaw, 0, false); reuse = TigerClawReuseTime; break; @@ -528,7 +528,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { //make sure we have a proper weapon if we are a client. if(IsClient()) { - const EQEmu::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); + const EQEmu::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if (!wpn || (wpn->GetItem()->ItemType != EQEmu::item::ItemType1HPiercing)){ Message_StringID(13, BACKSTAB_WEAPON); return; @@ -583,7 +583,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { m_specialattacks = eSpecialAttacks::None; } else { //We do a single regular attack if we attack from the front without chaotic stab - Attack(other, EQEmu::inventory::slotPrimary); + Attack(other, EQEmu::invslot::slotPrimary); } } @@ -597,7 +597,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) // make sure we can hit (bane, magical, etc) if (IsClient()) { - const EQEmu::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); + const EQEmu::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if (!GetWeaponDamage(other, wpn)) return; } else if (!GetWeaponDamage(other, (const EQEmu::ItemData*)nullptr)){ @@ -616,7 +616,7 @@ void Mob::RogueAssassinate(Mob* other) { //can you dodge, parry, etc.. an assassinate?? //if so, use DoSpecialAttackDamage(other, BACKSTAB, 32000); instead - if (GetWeaponDamage(other, IsClient() ? CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary) : (const EQEmu::ItemInstance*)nullptr) > 0){ + if (GetWeaponDamage(other, IsClient() ? CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary) : (const EQEmu::ItemInstance*)nullptr) > 0){ other->Damage(this, 32000, SPELL_UNKNOWN, EQEmu::skills::SkillBackstab); }else{ other->Damage(this, -5, SPELL_UNKNOWN, EQEmu::skills::SkillBackstab); @@ -636,20 +636,20 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { //Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime()); return; } - const EQEmu::ItemInstance* RangeWeapon = m_inv[EQEmu::inventory::slotRange]; + const EQEmu::ItemInstance* RangeWeapon = m_inv[EQEmu::invslot::slotRange]; //locate ammo - int ammo_slot = EQEmu::inventory::slotAmmo; - const EQEmu::ItemInstance* Ammo = m_inv[EQEmu::inventory::slotAmmo]; + int ammo_slot = EQEmu::invslot::slotAmmo; + const EQEmu::ItemInstance* Ammo = m_inv[EQEmu::invslot::slotAmmo]; if (!RangeWeapon || !RangeWeapon->IsClassCommon()) { - Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(EQEmu::inventory::slotRange), EQEmu::inventory::slotRange); - Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have no bow!", GetItemIDAt(EQEmu::inventory::slotRange)); + Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(EQEmu::invslot::slotRange), EQEmu::invslot::slotRange); + Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have no bow!", GetItemIDAt(EQEmu::invslot::slotRange)); return; } if (!Ammo || !Ammo->IsClassCommon()) { - Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ammo item (%d) in slot %d", GetItemIDAt(EQEmu::inventory::slotAmmo), EQEmu::inventory::slotAmmo); - Message(0, "Error: Ammo: GetItem(%i)==0, you have no ammo!", GetItemIDAt(EQEmu::inventory::slotAmmo)); + Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ammo item (%d) in slot %d", GetItemIDAt(EQEmu::invslot::slotAmmo), EQEmu::invslot::slotAmmo); + Message(0, "Error: Ammo: GetItem(%i)==0, you have no ammo!", GetItemIDAt(EQEmu::invslot::slotAmmo)); return; } @@ -674,7 +674,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { //first look for quivers int r; bool found = false; - for (r = EQEmu::legacy::GENERAL_BEGIN; r <= EQEmu::legacy::GENERAL_END; r++) { + for (r = EQEmu::invslot::GENERAL_BEGIN; r <= EQEmu::invslot::GENERAL_END; r++) { const EQEmu::ItemInstance *pi = m_inv[r]; if (pi == nullptr || !pi->IsClassBag()) continue; @@ -791,7 +791,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon, if (!RangeWeapon && !Ammo && range_id && ammo_id) { if (IsClient()) { - _RangeWeapon = CastToClient()->m_inv[EQEmu::inventory::slotRange]; + _RangeWeapon = CastToClient()->m_inv[EQEmu::invslot::slotRange]; if (_RangeWeapon && _RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID == range_id) RangeWeapon = _RangeWeapon; @@ -859,7 +859,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon, my_hit.skill = EQEmu::skills::SkillArchery; my_hit.offense = offense(my_hit.skill); my_hit.tohit = GetTotalToHit(my_hit.skill, chance_mod); - my_hit.hand = EQEmu::inventory::slotRange; + my_hit.hand = EQEmu::invslot::slotRange; DoAttack(other, my_hit); TotalDmg = my_hit.damage_done; @@ -877,7 +877,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon, if (ReuseTime) TrySkillProc(other, EQEmu::skills::SkillArchery, ReuseTime); else - TrySkillProc(other, EQEmu::skills::SkillArchery, 0, true, EQEmu::inventory::slotRange); + TrySkillProc(other, EQEmu::skills::SkillArchery, 0, true, EQEmu::invslot::slotRange); } // end of old fuck @@ -886,20 +886,20 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon, // Weapon Proc if (RangeWeapon && other && !other->HasDied()) - TryWeaponProc(RangeWeapon, other, EQEmu::inventory::slotRange); + TryWeaponProc(RangeWeapon, other, EQEmu::invslot::slotRange); // Ammo Proc if (ammo_lost) - TryWeaponProc(nullptr, ammo_lost, other, EQEmu::inventory::slotRange); + TryWeaponProc(nullptr, ammo_lost, other, EQEmu::invslot::slotRange); else if (Ammo && other && !other->HasDied()) - TryWeaponProc(Ammo, other, EQEmu::inventory::slotRange); + TryWeaponProc(Ammo, other, EQEmu::invslot::slotRange); // Skill Proc if (HasSkillProcs() && other && !other->HasDied()) { if (ReuseTime) TrySkillProc(other, EQEmu::skills::SkillArchery, ReuseTime); else - TrySkillProc(other, EQEmu::skills::SkillArchery, 0, false, EQEmu::inventory::slotRange); + TrySkillProc(other, EQEmu::skills::SkillArchery, 0, false, EQEmu::invslot::slotRange); } } @@ -1190,7 +1190,7 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha my_hit.skill = skill; my_hit.offense = offense(my_hit.skill); my_hit.tohit = GetTotalToHit(my_hit.skill, chance_mod); - my_hit.hand = EQEmu::inventory::slotRange; + my_hit.hand = EQEmu::invslot::slotRange; DoAttack(other, my_hit); @@ -1206,14 +1206,14 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillInUse); if (TotalDmg > 0 && HasSkillProcSuccess() && !other->HasDied()) - TrySkillProc(other, skillInUse, 0, true, EQEmu::inventory::slotRange); + TrySkillProc(other, skillInUse, 0, true, EQEmu::invslot::slotRange); //try proc on hits and misses if(other && !other->HasDied()) - TrySpellProc(nullptr, (const EQEmu::ItemData*)nullptr, other, EQEmu::inventory::slotRange); + TrySpellProc(nullptr, (const EQEmu::ItemData*)nullptr, other, EQEmu::invslot::slotRange); if (HasSkillProcs() && other && !other->HasDied()) - TrySkillProc(other, skillInUse, 0, false, EQEmu::inventory::slotRange); + TrySkillProc(other, skillInUse, 0, false, EQEmu::invslot::slotRange); } void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 @@ -1229,19 +1229,19 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 return; } - int ammo_slot = EQEmu::inventory::slotRange; - const EQEmu::ItemInstance* RangeWeapon = m_inv[EQEmu::inventory::slotRange]; + int ammo_slot = EQEmu::invslot::slotRange; + const EQEmu::ItemInstance* RangeWeapon = m_inv[EQEmu::invslot::slotRange]; if (!RangeWeapon || !RangeWeapon->IsClassCommon()) { - Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(EQEmu::inventory::slotRange), EQEmu::inventory::slotRange); - Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing to throw!", GetItemIDAt(EQEmu::inventory::slotRange)); + Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(EQEmu::invslot::slotRange), EQEmu::invslot::slotRange); + Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing to throw!", GetItemIDAt(EQEmu::invslot::slotRange)); return; } const EQEmu::ItemData* item = RangeWeapon->GetItem(); if (item->ItemType != EQEmu::item::ItemTypeLargeThrowing && item->ItemType != EQEmu::item::ItemTypeSmallThrowing) { Log(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item %d is not a throwing weapon. type %d.", item->ItemType); - Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(EQEmu::inventory::slotRange)); + Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(EQEmu::invslot::slotRange)); return; } @@ -1249,11 +1249,11 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 if(RangeWeapon->GetCharges() == 1) { //first check ammo - const EQEmu::ItemInstance* AmmoItem = m_inv[EQEmu::inventory::slotAmmo]; + const EQEmu::ItemInstance* AmmoItem = m_inv[EQEmu::invslot::slotAmmo]; if(AmmoItem != nullptr && AmmoItem->GetID() == RangeWeapon->GetID()) { //more in the ammo slot, use it RangeWeapon = AmmoItem; - ammo_slot = EQEmu::inventory::slotAmmo; + ammo_slot = EQEmu::invslot::slotAmmo; Log(Logs::Detail, Logs::Combat, "Using ammo from ammo slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges()); } else { //look through our inventory for more @@ -1371,7 +1371,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon my_hit.skill = EQEmu::skills::SkillThrowing; my_hit.offense = offense(my_hit.skill); my_hit.tohit = GetTotalToHit(my_hit.skill, chance_mod); - my_hit.hand = EQEmu::inventory::slotRange; + my_hit.hand = EQEmu::invslot::slotRange; DoAttack(other, my_hit); TotalDmg = my_hit.damage_done; @@ -1390,7 +1390,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon if (ReuseTime) TrySkillProc(other, EQEmu::skills::SkillThrowing, ReuseTime); else - TrySkillProc(other, EQEmu::skills::SkillThrowing, 0, true, EQEmu::inventory::slotRange); + TrySkillProc(other, EQEmu::skills::SkillThrowing, 0, true, EQEmu::invslot::slotRange); } // end old shit @@ -1399,15 +1399,15 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon // Throwing item Proc if (ammo_lost) - TryWeaponProc(nullptr, ammo_lost, other, EQEmu::inventory::slotRange); + TryWeaponProc(nullptr, ammo_lost, other, EQEmu::invslot::slotRange); else if (RangeWeapon && other && !other->HasDied()) - TryWeaponProc(RangeWeapon, other, EQEmu::inventory::slotRange); + TryWeaponProc(RangeWeapon, other, EQEmu::invslot::slotRange); if (HasSkillProcs() && other && !other->HasDied()) { if (ReuseTime) TrySkillProc(other, EQEmu::skills::SkillThrowing, ReuseTime); else - TrySkillProc(other, EQEmu::skills::SkillThrowing, 0, false, EQEmu::inventory::slotRange); + TrySkillProc(other, EQEmu::skills::SkillThrowing, 0, false, EQEmu::invslot::slotRange); } } @@ -1540,16 +1540,19 @@ void NPC::DoClassAttacks(Mob *target) { if(ka_time){ int knightreuse = 1000; //lets give it a small cooldown actually. + switch(GetClass()){ case SHADOWKNIGHT: case SHADOWKNIGHTGM:{ - CastSpell(SPELL_NPC_HARM_TOUCH, target->GetID()); - knightreuse = HarmTouchReuseTime * 1000; + if (CastSpell(SPELL_NPC_HARM_TOUCH, target->GetID())) { + knightreuse = HarmTouchReuseTime * 1000; + } break; } case PALADIN: case PALADINGM:{ if(GetHPRatio() < 20) { - CastSpell(SPELL_LAY_ON_HANDS, GetID()); - knightreuse = LayOnHandsReuseTime * 1000; + if (CastSpell(SPELL_LAY_ON_HANDS, GetID())) { + knightreuse = LayOnHandsReuseTime * 1000; + } } else { knightreuse = 2000; //Check again in two seconds. } @@ -1766,7 +1769,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if (ca_target!=this) { DoAnim(animTailRake, 0, false); - if (GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::inventory::slotSecondary)) <= 0 && GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::inventory::slotShoulders)) <= 0) + if (GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::invslot::slotSecondary)) <= 0 && GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::invslot::slotShoulders)) <= 0) dmg = DMG_INVULNERABLE; ReuseTime = (BashReuseTime - 1) / HasteMod; @@ -1812,7 +1815,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte) if(ca_target!=this){ DoAnim(animKick, 0, false); - if (GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::inventory::slotFeet)) <= 0) + if (GetWeaponDamage(ca_target, GetInv().GetItem(EQEmu::invslot::slotFeet)) <= 0) dmg = DMG_INVULNERABLE; ReuseTime = KickReuseTime-1; @@ -2111,7 +2114,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQEmu::skills: if (skillinuse == EQEmu::skills::SkillBash) { if (IsClient()) { EQEmu::ItemInstance *item = - CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary); + CastToClient()->GetInv().GetItem(EQEmu::invslot::slotSecondary); if (item) { if (item->GetItem()->ItemType == EQEmu::item::ItemTypeShield) { hate += item->GetItem()->AC; @@ -2131,7 +2134,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQEmu::skills: my_hit.offense = offense(my_hit.skill); my_hit.tohit = GetTotalToHit(my_hit.skill, chance_mod); // slot range exclude ripe etc ... - my_hit.hand = CanRiposte ? EQEmu::inventory::slotRange : EQEmu::inventory::slotPrimary; + my_hit.hand = CanRiposte ? EQEmu::invslot::slotRange : EQEmu::invslot::slotPrimary; if (IsNPC()) my_hit.min_damage = CastToNPC()->GetMinDamage(); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 1cb376e98..bddaf6b5e 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -624,7 +624,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove snprintf(effect_desc, _EDLEN, "Flesh To Bone"); #endif if(IsClient()){ - EQEmu::ItemInstance* transI = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotCursor); + EQEmu::ItemInstance* transI = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotCursor); if (transI && transI->IsClassCommon() && transI->IsStackable()){ uint32 fcharges = transI->GetCharges(); //Does it sound like meat... maybe should check if it looks like meat too... @@ -634,7 +634,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove strstr(transI->GetItem()->Name, "Flesh") || strstr(transI->GetItem()->Name, "parts") || strstr(transI->GetItem()->Name, "Parts")){ - CastToClient()->DeleteItemInInventory(EQEmu::inventory::slotCursor, fcharges, true); + CastToClient()->DeleteItemInInventory(EQEmu::invslot::slotCursor, fcharges, true); CastToClient()->SummonItem(13073, fcharges); } else{ @@ -1176,7 +1176,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (SummonedItem) { c->PushItemOnCursor(*SummonedItem); - c->SendItemPacket(EQEmu::inventory::slotCursor, SummonedItem, ItemPacketLimbo); + c->SendItemPacket(EQEmu::invslot::slotCursor, SummonedItem, ItemPacketLimbo); safe_delete(SummonedItem); } SummonedItem = database.CreateItem(spell.base[i], charges); @@ -1730,7 +1730,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(IsClient()) // NPCs can't ride { - CastToClient()->SummonHorse(spell_id); + Client *client = CastToClient(); + + // Prevent Feigned players from summoning horses and riding away to freedom. + client->SetFeigned(false); + client->Stand(); + client->SummonHorse(spell_id); } @@ -2213,7 +2218,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove snprintf(effect_desc, _EDLEN, "Rampage"); #endif if(caster) - entity_list.AEAttack(caster, 30, EQEmu::inventory::slotPrimary, 0, true); // on live wars dont get a duration ramp, its a one shot deal + entity_list.AEAttack(caster, 30, EQEmu::invslot::slotPrimary, 0, true); // on live wars dont get a duration ramp, its a one shot deal break; } @@ -3015,7 +3020,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (SummonedItem) { Client *c=CastToClient(); c->PushItemOnCursor(*SummonedItem); - c->SendItemPacket(EQEmu::inventory::slotCursor, SummonedItem, ItemPacketLimbo); + c->SendItemPacket(EQEmu::invslot::slotCursor, SummonedItem, ItemPacketLimbo); safe_delete(SummonedItem); } @@ -5169,7 +5174,7 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) { const EQEmu::ItemData* TempItem = nullptr; - for (int x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::EQUIPMENT_END; x++) + for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) { if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS) continue; @@ -5189,7 +5194,7 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) { } } - for (int y = EQEmu::inventory::socketBegin; y < EQEmu::inventory::SocketCount; ++y) + for (int y = EQEmu::invaug::SOCKET_BEGIN; y <= EQEmu::invaug::SOCKET_END; ++y) { if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS) continue; @@ -5304,7 +5309,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) int16 focus_max_real = 0; //item focus - for (int x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::EQUIPMENT_END; x++) + for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) { TempItem = nullptr; EQEmu::ItemInstance* ins = GetInv().GetItem(x); @@ -5338,7 +5343,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) } } - for (int y = EQEmu::inventory::socketBegin; y < EQEmu::inventory::SocketCount; ++y) + for (int y = EQEmu::invaug::SOCKET_BEGIN; y <= EQEmu::invaug::SOCKET_END; ++y) { EQEmu::ItemInstance *aug = nullptr; aug = ins->GetAugment(y); @@ -5376,7 +5381,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) } //Tribute Focus - for (int x = EQEmu::legacy::TRIBUTE_BEGIN; x <= EQEmu::legacy::TRIBUTE_END; ++x) + for (int x = EQEmu::invslot::TRIBUTE_BEGIN; x <= EQEmu::invslot::TRIBUTE_END; ++x) { TempItem = nullptr; EQEmu::ItemInstance* ins = GetInv().GetItem(x); @@ -5576,7 +5581,7 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) { int16 focus_max_real = 0; //item focus - for (int i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++){ + for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++){ const EQEmu::ItemData *cur = database.GetItem(equipment[i]); if(!cur) diff --git a/zone/spells.cpp b/zone/spells.cpp index 1c17e80f4..8f8cfba33 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -281,7 +281,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, return(false); } } - if (itm && (itm->GetItem()->Click.Type == EQEmu::item::ItemEffectEquipClick) && !(item_slot <= EQEmu::inventory::slotAmmo || item_slot == EQEmu::inventory::slotPowerSource)){ + if (itm && (itm->GetItem()->Click.Type == EQEmu::item::ItemEffectEquipClick) && !(item_slot <= EQEmu::invslot::slotAmmo || item_slot == EQEmu::invslot::SLOT_POWER_SOURCE)){ if (CastToClient()->ClientVersion() < EQEmu::versions::ClientVersion::SoF) { // They are attempting to cast a must equip clicky without having it equipped Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID); @@ -1294,7 +1294,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if (inst == nullptr) break; - for (int r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) { + for (int r = EQEmu::invaug::SOCKET_BEGIN; r <= EQEmu::invaug::SOCKET_END; r++) { const EQEmu::ItemInstance* aug_i = inst->GetAugment(r); if (!aug_i) @@ -3895,6 +3895,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r spelltar->SetHateAmountOnEnt(this, std::max(newhate, 1)); } } else if (IsBeneficialSpell(spell_id) && !IsSummonPCSpell(spell_id)) { + if (this != spelltar && spelltar->IsClient() && IsClient()) + CastToClient()->UpdateRestTimer(spelltar->CastToClient()->GetRestTimer()); entity_list.AddHealAggro( spelltar, this, CheckHealAggroAmount(spell_id, spelltar, (spelltar->GetMaxHP() - spelltar->GetHP()))); diff --git a/zone/string_ids.h b/zone/string_ids.h index 7786d12dc..2c223ffbd 100644 --- a/zone/string_ids.h +++ b/zone/string_ids.h @@ -301,6 +301,7 @@ #define CORPSEDRAG_STOPALL 4065 //You stop dragging the corpses. #define CORPSEDRAG_STOP 4066 //You stop dragging the corpse. #define SOS_KEEPS_HIDDEN 4086 //Your Shroud of Stealth keeps you hidden from watchful eyes.␣␣ +#define DISARM_NO_TARGET 4583 //You can't use disarm on that. #define TARGET_TOO_CLOSE 4602 //You are too close to your target. Get farther away. #define WHOALL_NO_RESULTS 5029 //There are no players in EverQuest that match those who filters. #define TELL_QUEUED_MESSAGE 5045 //You told %1 '%T2. %3' @@ -322,6 +323,7 @@ #define FAILED_TAUNT 5811 //You have failed to taunt your target. #define PHYSICAL_RESIST_FAIL 5817 //Your target avoided your %1 ability. #define AA_NO_TARGET 5825 //You must first select a target for this ability! +#define MAX_ACTIVE_TASKS 6010 //Sorry %3, you already have the maximum number of active tasks. #define FORAGE_MASTERY 6012 //Your forage mastery has enabled you to find something else! #define GUILD_BANK_CANNOT_DEPOSIT 6097 // Cannot deposit this item. Containers must be empty, and only one of each LORE and no NO TRADE or TEMPORARY items may be deposited. #define GUILD_BANK_FULL 6098 // There is no more room in the Guild Bank. @@ -445,6 +447,9 @@ #define TRY_ATTACKING_SOMEONE 12696 //Try attacking someone other than yourself, it's more productive #define RANGED_TOO_CLOSE 12698 //Your target is too close to use a ranged weapon! #define BACKSTAB_WEAPON 12874 //You need a piercing weapon as your primary weapon in order to backstab +#define DISARMED 12889 //You have been disarmed! +#define DISARM_SUCCESS 12890 //You disarmed %1! +#define DISARM_FAILED 12891 //Your attempt to disarm failed. #define MORE_SKILLED_THAN_I 12931 //%1 tells you, 'You are more skilled than I! What could I possibly teach you?' #define SURNAME_EXISTS 12939 //You already have a surname. Operation failed. #define SURNAME_LEVEL 12940 //You can only submit a surname upon reaching the 20th level. Operation failed. diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 06e3b4c59..5a3ba7914 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -34,6 +34,7 @@ Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net) #include "client.h" #include "entity.h" #include "mob.h" +#include "string_ids.h" #include "queryserv.h" #include "quest_parser_collection.h" @@ -48,14 +49,6 @@ TaskManager::TaskManager() { TaskManager::~TaskManager() { for(int i=0; iActivityCount; j++) { - safe_delete_array(Tasks[i]->Activity[j].Text1); - safe_delete_array(Tasks[i]->Activity[j].Text2); - safe_delete_array(Tasks[i]->Activity[j].Text3); - } - safe_delete_array(Tasks[i]->Title); - safe_delete_array(Tasks[i]->Description); - safe_delete_array(Tasks[i]->Reward); safe_delete(Tasks[i]); } } @@ -98,15 +91,6 @@ bool TaskManager::LoadSingleTask(int TaskID) { // If this task already exists in memory, free all the dynamically allocated strings. if(Tasks[TaskID]) { - - for(int j=0; jActivityCount; j++) { - safe_delete_array(Tasks[TaskID]->Activity[j].Text1); - safe_delete_array(Tasks[TaskID]->Activity[j].Text2); - safe_delete_array(Tasks[TaskID]->Activity[j].Text3); - } - safe_delete_array(Tasks[TaskID]->Title); - safe_delete_array(Tasks[TaskID]->Description); - safe_delete_array(Tasks[TaskID]->Reward); safe_delete(Tasks[TaskID]); } @@ -119,314 +103,325 @@ void TaskManager::ReloadGoalLists() { Log(Logs::Detail, Logs::Tasks,"TaskManager::LoadTasks LoadLists failed"); } -bool TaskManager::LoadTasks(int singleTask) { - +bool TaskManager::LoadTasks(int singleTask) +{ // If TaskID !=0, then just load the task specified. Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] TaskManager::LoadTasks Called"); - std::string query; - if(singleTask == 0) { - if(!GoalListManager.LoadLists()) - Log(Logs::Detail, Logs::Tasks,"TaskManager::LoadTasks LoadLists failed"); + std::string query; + if (singleTask == 0) { + if (!GoalListManager.LoadLists()) + Log(Logs::Detail, Logs::Tasks, "TaskManager::LoadTasks LoadLists failed"); - if(!LoadTaskSets()) - Log(Logs::Detail, Logs::Tasks,"TaskManager::LoadTasks LoadTaskSets failed"); + if (!LoadTaskSets()) + Log(Logs::Detail, Logs::Tasks, "TaskManager::LoadTasks LoadTaskSets failed"); - query = StringFormat("SELECT `id`, `duration`, `title`, `description`, `reward`, " - "`rewardid`, `cashreward`, `xpreward`, `rewardmethod`, " - "`startzone`, `minlevel`, `maxlevel`, `repeatable` " - "FROM `tasks` WHERE `id` < %i", MAXTASKS); - } - else - query = StringFormat("SELECT `id`, `duration`, `title`, `description`, `reward`, " - "`rewardid`, `cashreward`, `xpreward`, `rewardmethod`, " - "`startzone`, `minlevel`, `maxlevel`, `repeatable` " - "FROM `tasks` WHERE `id` = %i",singleTask); + query = StringFormat("SELECT `id`, `type`, `duration`, `duration_code`, `title`, `description`, " + "`reward`, `rewardid`, `cashreward`, `xpreward`, `rewardmethod`, `faction_reward`," + "`minlevel`, `maxlevel`, `repeatable`, `completion_emote` FROM `tasks` WHERE `id` < %i", + MAXTASKS); + } else + query = StringFormat("SELECT `id`, `type`, `duration`, `duration_code`, `title`, `description`, " + "`reward`, `rewardid`, `cashreward`, `xpreward`, `rewardmethod`, `faction_reward`," + "`minlevel`, `maxlevel`, `repeatable`, `completion_emote` FROM `tasks` WHERE `id` = %i", + singleTask); - const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::LoadTasks: %s"; + const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::LoadTasks: %s"; - auto results = database.QueryDatabase(query); - if (!results.Success()) { - Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); return false; - } + } - for(auto row = results.begin(); row != results.end(); ++row) { - int taskID = atoi(row[0]); + for (auto row = results.begin(); row != results.end(); ++row) { + int taskID = atoi(row[0]); - if((taskID <= 0) || (taskID >= MAXTASKS)) { - // This shouldn't happen, as the SELECT is bounded by MAXTASKS - Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading tasks from database", taskID); + if ((taskID <= 0) || (taskID >= MAXTASKS)) { + // This shouldn't happen, as the SELECT is bounded by MAXTASKS + Log(Logs::General, Logs::Error, + "[TASKS]Task ID %i out of range while loading tasks from database", taskID); continue; - } + } Tasks[taskID] = new TaskInformation; - Tasks[taskID]->Duration = atoi(row[1]); - Tasks[taskID]->Title = new char[strlen(row[2]) + 1]; - strcpy(Tasks[taskID]->Title, row[2]); - Tasks[taskID]->Description = new char[strlen(row[3]) + 1]; - strcpy(Tasks[taskID]->Description, row[3]); - Tasks[taskID]->Reward = new char[strlen(row[4]) + 1]; - strcpy(Tasks[taskID]->Reward, row[4]); - Tasks[taskID]->RewardID = atoi(row[5]); - Tasks[taskID]->CashReward = atoi(row[6]); - Tasks[taskID]->XPReward = atoi(row[7]); - Tasks[taskID]->RewardMethod = (TaskMethodType)atoi(row[8]); - Tasks[taskID]->StartZone = atoi(row[9]); - Tasks[taskID]->MinLevel = atoi(row[10]); - Tasks[taskID]->MaxLevel = atoi(row[11]); - Tasks[taskID]->Repeatable = atoi(row[12]); + Tasks[taskID]->type = static_cast(atoi(row[1])); + Tasks[taskID]->Duration = atoi(row[2]); + Tasks[taskID]->dur_code = static_cast(atoi(row[3])); + Tasks[taskID]->Title = row[4]; + Tasks[taskID]->Description = row[5]; + Tasks[taskID]->Reward = row[6]; + Tasks[taskID]->RewardID = atoi(row[7]); + Tasks[taskID]->CashReward = atoi(row[8]); + Tasks[taskID]->XPReward = atoi(row[9]); + Tasks[taskID]->RewardMethod = (TaskMethodType)atoi(row[10]); + Tasks[taskID]->faction_reward = atoi(row[11]); + Tasks[taskID]->MinLevel = atoi(row[12]); + Tasks[taskID]->MaxLevel = atoi(row[13]); + Tasks[taskID]->Repeatable = atoi(row[14]); + Tasks[taskID]->completion_emote = row[15]; Tasks[taskID]->ActivityCount = 0; Tasks[taskID]->SequenceMode = ActivitiesSequential; Tasks[taskID]->LastStep = 0; - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] TaskID: %5i, Duration: %8i, StartZone: %3i Reward: %s MinLevel %i MaxLevel %i Repeatable: %s", - taskID, Tasks[taskID]->Duration, Tasks[taskID]->StartZone, Tasks[taskID]->Reward, - Tasks[taskID]->MinLevel, Tasks[taskID]->MaxLevel, - Tasks[taskID]->Repeatable ? "Yes" : "No"); - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Title: %s", Tasks[taskID]->Title); - } + Log(Logs::General, Logs::Tasks, + "[GLOBALLOAD] TaskID: %5i, Duration: %8i, Reward: %s MinLevel %i MaxLevel %i " + "Repeatable: %s", + taskID, Tasks[taskID]->Duration, Tasks[taskID]->Reward.c_str(), + Tasks[taskID]->MinLevel, Tasks[taskID]->MaxLevel, Tasks[taskID]->Repeatable ? "Yes" : "No"); + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Title: %s", Tasks[taskID]->Title.c_str()); + } - - if(singleTask==0) - query = StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, " - "`text1`, `text2`, `text3`, `goalid`, `goalmethod`, " - "`goalcount`, `delivertonpc`, `zoneid`, `optional` " - "FROM `activities` " - "WHERE `taskid` < %i AND `activityid` < %i " - "ORDER BY taskid, activityid ASC", MAXTASKS, MAXACTIVITIESPERTASK); + if (singleTask == 0) + query = + StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, `target_name`, `item_list`, " + "`skill_list`, `spell_list`, `description_override`, `goalid`, `goalmethod`, " + "`goalcount`, `delivertonpc`, `zones`, `optional` FROM `task_activities` WHERE `taskid` < " + "%i AND `activityid` < %i ORDER BY taskid, activityid ASC", + MAXTASKS, MAXACTIVITIESPERTASK); else - query = StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, " - "`text1`, `text2`, `text3`, `goalid`, `goalmethod`, " - "`goalcount`, `delivertonpc`, `zoneid`, `optional` " - "FROM `activities` " - "WHERE `taskid` = %i AND `activityid` < %i " - "ORDER BY taskid, activityid ASC", singleTask, MAXACTIVITIESPERTASK); - results = database.QueryDatabase(query); - if (!results.Success()) { - Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + query = + StringFormat("SELECT `taskid`, `step`, `activityid`, `activitytype`, `target_name`, `item_list`, " + "`skill_list`, `spell_list`, `description_override`, `goalid`, `goalmethod`, " + "`goalcount`, `delivertonpc`, `zones`, `optional` FROM `task_activities` WHERE `taskid` = " + "%i AND `activityid` < %i ORDER BY taskid, activityid ASC", + singleTask, MAXACTIVITIESPERTASK); + results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); return false; - } + } - for(auto row = results.begin(); row != results.end(); ++row) { - int taskID = atoi(row[0]); - int step = atoi(row[1]); + for (auto row = results.begin(); row != results.end(); ++row) { + int taskID = atoi(row[0]); + int step = atoi(row[1]); - int activityID = atoi(row[2]); + int activityID = atoi(row[2]); - if((taskID <= 0) || (taskID >= MAXTASKS) || (activityID < 0) || (activityID >= MAXACTIVITIESPERTASK)) { - // This shouldn't happen, as the SELECT is bounded by MAXTASKS - Log(Logs::General, Logs::Error, "[TASKS]Task or Activity ID (%i, %i) out of range while loading " - "activities from database", taskID, activityID); - continue; - } + if ((taskID <= 0) || (taskID >= MAXTASKS) || (activityID < 0) || (activityID >= MAXACTIVITIESPERTASK)) { + // This shouldn't happen, as the SELECT is bounded by MAXTASKS + Log(Logs::General, Logs::Error, + "[TASKS]Task or Activity ID (%i, %i) out of range while loading " + "activities from database", + taskID, activityID); + continue; + } - if(Tasks[taskID]==nullptr) { - Log(Logs::General, Logs::Error, "[TASKS]Activity for non-existent task (%i, %i) while loading activities from database", taskID, activityID); - continue; - } + if (Tasks[taskID] == nullptr) { + Log(Logs::General, Logs::Error, + "[TASKS]Activity for non-existent task (%i, %i) while loading activities from database", + taskID, activityID); + continue; + } - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].StepNumber = step; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].StepNumber = step; - if(step != 0) - Tasks[taskID]->SequenceMode = ActivitiesStepped; + if (step != 0) + Tasks[taskID]->SequenceMode = ActivitiesStepped; - if(step >Tasks[taskID]->LastStep) - Tasks[taskID]->LastStep = step; + if (step > Tasks[taskID]->LastStep) + Tasks[taskID]->LastStep = step; - // Task Activities MUST be numbered sequentially from 0. If not, log an error - // and set the task to nullptr. Subsequent activities for this task will raise - // ERR_NOTASK errors. - // Change to (activityID != (Tasks[taskID]->ActivityCount + 1)) to index from 1 - if(activityID != Tasks[taskID]->ActivityCount) { - Log(Logs::General, Logs::Error, "[TASKS]Activities for Task %i are not sequential starting at 0. Not loading task.", taskID, activityID); - Tasks[taskID] = nullptr; - continue; - } + // Task Activities MUST be numbered sequentially from 0. If not, log an error + // and set the task to nullptr. Subsequent activities for this task will raise + // ERR_NOTASK errors. + // Change to (activityID != (Tasks[taskID]->ActivityCount + 1)) to index from 1 + if (activityID != Tasks[taskID]->ActivityCount) { + Log(Logs::General, Logs::Error, + "[TASKS]Activities for Task %i are not sequential starting at 0. Not loading task.", taskID, + activityID); + Tasks[taskID] = nullptr; + continue; + } - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Type = atoi(row[3]); + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Type = atoi(row[3]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text1 = new char[strlen(row[4]) + 1]; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].target_name = row[4]; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].item_list = row[5]; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].skill_list = row[6]; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].skill_id = atoi(row[6]); // for older clients + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].spell_list = row[7]; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].spell_id = atoi(row[7]); // for older clients + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].desc_override = row[8]; - if(strlen(row[4])>0) - strcpy(Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text1, row[4]); - else - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text1[0]=0; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID = atoi(row[9]); + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod = (TaskMethodType)atoi(row[10]); + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount = atoi(row[11]); + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].DeliverToNPC = atoi(row[12]); + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].zones = row[13]; + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID = atoi(row[13]); // for older clients + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Optional = atoi(row[14]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text2 = new char[strlen(row[5]) + 1]; + Log(Logs::General, Logs::Tasks, + "[GLOBALLOAD] Activity Slot %2i: ID %i for Task %5i. Type: %3i, GoalID: %8i, " + "GoalMethod: %i, GoalCount: %3i, Zones:%s", + Tasks[taskID]->ActivityCount, activityID, taskID, + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Type, + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID, + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod, + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount, + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].zones.c_str()); - if(strlen(row[5])>0) - strcpy(Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text2, row[5]); - else - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text2[0]=0; + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] target_name: %s", + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].target_name.c_str()); + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] item_list: %s", + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].item_list.c_str()); + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] skill_list: %s", + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].skill_list.c_str()); + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] spell_list: %s", + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].spell_list.c_str()); + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] description_override: %s", + Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].desc_override.c_str()); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text3 = new char[strlen(row[6]) + 1]; - - if(strlen(row[6])>0) - strcpy(Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text3, row[6]); - else - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text3[0]=0; - - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID = atoi(row[7]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod = (TaskMethodType)atoi(row[8]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount = atoi(row[9]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].DeliverToNPC = atoi(row[10]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID = atoi(row[11]); - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Optional = atoi(row[12]); - - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Activity Slot %2i: ID %i for Task %5i. Type: %3i, GoalID: %8i, " - "GoalMethod: %i, GoalCount: %3i, ZoneID:%3i", - Tasks[taskID]->ActivityCount, activityID, taskID, - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Type, - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalID, - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalMethod, - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount, - Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID); - - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Text1: %s", Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text1); - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Text2: %s", Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text2); - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Text3: %s", Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Text3); - - Tasks[taskID]->ActivityCount++; + Tasks[taskID]->ActivityCount++; } return true; } -bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) { - - // I am saving the slot in the ActiveTasks table, because unless a Task is cancelled/completed, the client doesn't - // seem to like tasks moving slots between zoning and you can end up with 'bogus' activities if the task previously - // in that slot had more activities than the one now occupying it. Hopefully retaining the slot number for the - // duration of a session will overcome this. - // - if(!c || !state) - return false; +bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) +{ + // I am saving the slot in the ActiveTasks table, because unless a Task is cancelled/completed, the client + // doesn't seem to like tasks moving slots between zoning and you can end up with 'bogus' activities if the task + // previously in that slot had more activities than the one now occupying it. Hopefully retaining the slot + // number for the duration of a session will overcome this. + if (!c || !state) + return false; const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::SaveClientState %s"; int characterID = c->CharacterID(); - Log(Logs::Detail, Logs::Tasks,"TaskManager::SaveClientState for character ID %d", characterID); + Log(Logs::Detail, Logs::Tasks, "TaskManager::SaveClientState for character ID %d", characterID); - if(state->ActiveTaskCount > 0) { - for(int task=0; taskActiveTaskCount > 0 || state->ActiveTask.TaskID != TASKSLOTEMPTY) { // TODO: tasks + for (int task = 0; task < MAXACTIVEQUESTS + 1; task++) { int taskID = state->ActiveTasks[task].TaskID; - if(taskID==TASKSLOTEMPTY) - continue; + if (taskID == TASKSLOTEMPTY) + continue; - if(state->ActiveTasks[task].Updated) { + int slot = state->ActiveTasks[task].slot; - Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] TaskManager::SaveClientState for character ID %d, Updating TaskIndex %i TaskID %i", characterID, task, taskID); + if (state->ActiveTasks[task].Updated) { - std::string query = StringFormat("REPLACE INTO character_tasks (charid, taskid, slot, acceptedtime) " - "VALUES (%i, %i, %i, %i)", - characterID, taskID, task, state->ActiveTasks[task].AcceptedTime); - auto results = database.QueryDatabase(query); + Log(Logs::General, Logs::Tasks, + "[CLIENTSAVE] TaskManager::SaveClientState for character ID %d, Updating TaskIndex " + "%i TaskID %i", + characterID, slot, taskID); + + std::string query = StringFormat( + "REPLACE INTO character_tasks (charid, taskid, slot, type, acceptedtime) " + "VALUES (%i, %i, %i, %i, %i)", + characterID, taskID, slot, static_cast(Tasks[taskID]->type), + state->ActiveTasks[task].AcceptedTime); + auto results = database.QueryDatabase(query); if (!results.Success()) { Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); - } - else { + } else { state->ActiveTasks[task].Updated = false; } - } - std::string query = "REPLACE INTO character_activities (charid, taskid, activityid, donecount, completed) " - "VALUES "; + std::string query = + "REPLACE INTO character_activities (charid, taskid, activityid, donecount, completed) " + "VALUES "; - int updatedActivityCount = 0; - for(int activityIndex = 0; activityIndexActivityCount; ++activityIndex) { + int updatedActivityCount = 0; + for (int activityIndex = 0; activityIndex < Tasks[taskID]->ActivityCount; ++activityIndex) { - if(!state->ActiveTasks[task].Activity[activityIndex].Updated) - continue; + if (!state->ActiveTasks[task].Activity[activityIndex].Updated) + continue; - Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] TaskManager::SaveClientSate for character ID %d, Updating Activity %i, %i", - characterID, task, activityIndex); + Log(Logs::General, Logs::Tasks, + "[CLIENTSAVE] TaskManager::SaveClientSate for character ID %d, Updating Activity " + "%i, %i", + characterID, slot, activityIndex); - if(updatedActivityCount==0) - query += StringFormat("(%i, %i, %i, %i, %i)", - characterID, taskID, activityIndex, - state->ActiveTasks[task].Activity[activityIndex].DoneCount, - state->ActiveTasks[task].Activity[activityIndex].State == ActivityCompleted); - else - query += StringFormat(", (%i, %i, %i, %i, %i)", - characterID, taskID, activityIndex, - state->ActiveTasks[task].Activity[activityIndex].DoneCount, - state->ActiveTasks[task].Activity[activityIndex].State == ActivityCompleted); + if (updatedActivityCount == 0) + query += + StringFormat("(%i, %i, %i, %i, %i)", characterID, taskID, activityIndex, + state->ActiveTasks[task].Activity[activityIndex].DoneCount, + state->ActiveTasks[task].Activity[activityIndex].State == + ActivityCompleted); + else + query += + StringFormat(", (%i, %i, %i, %i, %i)", characterID, taskID, activityIndex, + state->ActiveTasks[task].Activity[activityIndex].DoneCount, + state->ActiveTasks[task].Activity[activityIndex].State == + ActivityCompleted); - updatedActivityCount++; + updatedActivityCount++; } - if(updatedActivityCount == 0) - continue; + if (updatedActivityCount == 0) + continue; - Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] Executing query %s", query.c_str()); - auto results = database.QueryDatabase(query); + Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] Executing query %s", query.c_str()); + auto results = database.QueryDatabase(query); - if(!results.Success()) { - Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); - continue; - } - - state->ActiveTasks[task].Updated=false; - for(int activityIndex=0; activityIndexActivityCount; ++activityIndex) - state->ActiveTasks[task].Activity[activityIndex].Updated=false; + if (!results.Success()) { + Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + continue; + } + state->ActiveTasks[task].Updated = false; + for (int activityIndex = 0; activityIndex < Tasks[taskID]->ActivityCount; ++activityIndex) + state->ActiveTasks[task].Activity[activityIndex].Updated = false; } } - if(!RuleB(TaskSystem, RecordCompletedTasks) || (state->CompletedTasks.size() <= (unsigned int)state->LastCompletedTaskLoaded)) { - state->LastCompletedTaskLoaded = state->CompletedTasks.size(); - return true; - } + if (!RuleB(TaskSystem, RecordCompletedTasks) || + (state->CompletedTasks.size() <= (unsigned int)state->LastCompletedTaskLoaded)) { + state->LastCompletedTaskLoaded = state->CompletedTasks.size(); + return true; + } - const char* completedTaskQuery = "REPLACE INTO completed_tasks (charid, completedtime, taskid, activityid) " - "VALUES (%i, %i, %i, %i)"; + const char *completedTaskQuery = "REPLACE INTO completed_tasks (charid, completedtime, taskid, activityid) " + "VALUES (%i, %i, %i, %i)"; - for(unsigned int i=state->LastCompletedTaskLoaded; iCompletedTasks.size(); i++) { + for (unsigned int i = state->LastCompletedTaskLoaded; i < state->CompletedTasks.size(); i++) { - Log(Logs::General, Logs::Tasks, "[CLIENTSAVE] TaskManager::SaveClientState Saving Completed Task at slot %i", i); - int taskID = state->CompletedTasks[i].TaskID; + Log(Logs::General, Logs::Tasks, + "[CLIENTSAVE] TaskManager::SaveClientState Saving Completed Task at slot %i", i); + int taskID = state->CompletedTasks[i].TaskID; - if((taskID <= 0) || (taskID >= MAXTASKS) || (Tasks[taskID] == nullptr)) - continue; + if ((taskID <= 0) || (taskID >= MAXTASKS) || (Tasks[taskID] == nullptr)) + continue; - // First we save a record with an ActivityID of -1. - // This indicates this task was completed at the given time. We infer that all - // none optional activities were completed. - // - std::string query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, -1); - auto results = database.QueryDatabase(query); - if(!results.Success()) { - Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); - continue; - } + // First we save a record with an ActivityID of -1. + // This indicates this task was completed at the given time. We infer that all + // none optional activities were completed. + // + std::string query = + StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, -1); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + continue; + } - // If the Rule to record non-optional task completion is not enabled, don't save it - if(!RuleB(TaskSystem, RecordCompletedOptionalActivities)) - continue; + // If the Rule to record non-optional task completion is not enabled, don't save it + if (!RuleB(TaskSystem, RecordCompletedOptionalActivities)) + continue; - // Insert one record for each completed optional task. + // Insert one record for each completed optional task. - for(int j=0; jActivityCount; j++) { - if(!Tasks[taskID]->Activity[j].Optional || !state->CompletedTasks[i].ActivityDone[j]) - continue; + for (int j = 0; j < Tasks[taskID]->ActivityCount; j++) { + if (!Tasks[taskID]->Activity[j].Optional || !state->CompletedTasks[i].ActivityDone[j]) + continue; - query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, j); - results = database.QueryDatabase(query); - if(!results.Success()) - Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, + taskID, j); + results = database.QueryDatabase(query); + if (!results.Success()) + Log(Logs::General, Logs::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + } + } - } - - } - - state->LastCompletedTaskLoaded = state->CompletedTasks.size(); + state->LastCompletedTaskLoaded = state->CompletedTasks.size(); return true; } - void Client::LoadClientTaskState() { if(RuleB(TaskSystem, EnableTaskSystem) && taskmanager) { @@ -453,10 +448,10 @@ void Client::RemoveClientTaskState() { } } -bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { - - if(!c || !state) - return false; +bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) +{ + if (!c || !state) + return false; int characterID = c->CharacterID(); @@ -464,182 +459,208 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState for character ID %d", characterID); - std::string query = StringFormat("SELECT `taskid`, `slot`, `acceptedtime` " - "FROM `character_tasks` " - "WHERE `charid` = %i ORDER BY acceptedtime", characterID); - auto results = database.QueryDatabase(query); - if (!results.Success()) { - Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", results.ErrorMessage().c_str()); + std::string query = StringFormat("SELECT `taskid`, `slot`,`type`, `acceptedtime` " + "FROM `character_tasks` " + "WHERE `charid` = %i ORDER BY acceptedtime", + characterID); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", + results.ErrorMessage().c_str()); return false; - } + } - for(auto row = results.begin(); row != results.end(); ++row) { - int taskID = atoi(row[0]); - int slot = atoi(row[1]); + for (auto row = results.begin(); row != results.end(); ++row) { + int taskID = atoi(row[0]); + int slot = atoi(row[1]); + TaskType type = static_cast(atoi(row[2])); - if((taskID<0) || (taskID>=MAXTASKS)) { - Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading character tasks from database", taskID); - continue; - } + if ((taskID < 0) || (taskID >= MAXTASKS)) { + Log(Logs::General, Logs::Error, + "[TASKS]Task ID %i out of range while loading character tasks from database", taskID); + continue; + } - if((slot<0) || (slot>=MAXACTIVETASKS)) { - Log(Logs::General, Logs::Error, "[TASKS] Slot %i out of range while loading character tasks from database", slot); - continue; - } + auto task_info = state->GetClientTaskInfo(type, slot); - if(state->ActiveTasks[slot].TaskID != TASKSLOTEMPTY) { - Log(Logs::General, Logs::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, taskID); - continue; - } + if (task_info == nullptr) { + Log(Logs::General, Logs::Error, + "[TASKS] Slot %i out of range while loading character tasks from database", slot); + continue; + } - int acceptedtime = atoi(row[2]); + if (task_info->TaskID != TASKSLOTEMPTY) { + Log(Logs::General, Logs::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, + taskID); + continue; + } - state->ActiveTasks[slot].TaskID = taskID; - state->ActiveTasks[slot].CurrentStep = -1; - state->ActiveTasks[slot].AcceptedTime = acceptedtime; - state->ActiveTasks[slot].Updated = false; + int acceptedtime = atoi(row[3]); - for(int i=0; iActiveTasks[slot].Activity[i].ActivityID = -1; + task_info->TaskID = taskID; + task_info->CurrentStep = -1; + task_info->AcceptedTime = acceptedtime; + task_info->Updated = false; - ++state->ActiveTaskCount; + for (int i = 0; i < MAXACTIVITIESPERTASK; i++) + task_info->Activity[i].ActivityID = -1; - Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, Accepted Time: %8X", characterID, taskID, acceptedtime); + if (type == TaskType::Quest) + ++state->ActiveTaskCount; + + Log(Logs::General, Logs::Tasks, + "[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, Accepted Time: %8X", characterID, + taskID, acceptedtime); } // Load Activities - Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] LoadClientState. Loading activities for character ID %d", characterID); + Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] LoadClientState. Loading activities for character ID %d", + characterID); - query = StringFormat("SELECT `taskid`, `activityid`, `donecount`, `completed` " - "FROM `character_activities` " - "WHERE `charid` = %i " - "ORDER BY `taskid` ASC, `activityid` ASC", characterID); - results = database.QueryDatabase(query); - if (!results.Success()){ - Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", results.ErrorMessage().c_str()); + query = StringFormat("SELECT `taskid`, `activityid`, `donecount`, `completed` " + "FROM `character_activities` " + "WHERE `charid` = %i " + "ORDER BY `taskid` ASC, `activityid` ASC", + characterID); + results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", + results.ErrorMessage().c_str()); return false; } - for (auto row = results.begin(); row != results.end(); ++row) { - int taskID = atoi(row[0]); - if((taskID<0) || (taskID>=MAXTASKS)) { - Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading character activities from database", taskID); - continue; - } + for (auto row = results.begin(); row != results.end(); ++row) { + int taskID = atoi(row[0]); + if ((taskID < 0) || (taskID >= MAXTASKS)) { + Log(Logs::General, Logs::Error, + "[TASKS]Task ID %i out of range while loading character activities from database", taskID); + continue; + } - int activityID = atoi(row[1]); - if((activityID<0) || (activityID>=MAXACTIVITIESPERTASK)) { - Log(Logs::General, Logs::Error, "[TASKS]Activity ID %i out of range while loading character activities from database", activityID); - continue; - } + int activityID = atoi(row[1]); + if ((activityID < 0) || (activityID >= MAXACTIVITIESPERTASK)) { + Log(Logs::General, Logs::Error, + "[TASKS]Activity ID %i out of range while loading character activities from database", + activityID); + continue; + } - // Find Active Task Slot - int activeTaskIndex = -1; + ClientTaskInformation *task_info = nullptr; - for(int i=0; iActiveTasks[i].TaskID == taskID) { - activeTaskIndex = i; - break; - } + if (state->ActiveTask.TaskID == taskID) + task_info = &state->ActiveTask; - if(activeTaskIndex == -1) { - Log(Logs::General, Logs::Error, "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID); - continue; - } + // wasn't task + if (task_info == nullptr) + for (int i = 0; i < MAXACTIVEQUESTS; i++) + if (state->ActiveQuests[i].TaskID == taskID) + task_info = &state->ActiveQuests[i]; - int doneCount = atoi(row[2]); - bool completed = atoi(row[3]); - state->ActiveTasks[activeTaskIndex].Activity[activityID].ActivityID = activityID; - state->ActiveTasks[activeTaskIndex].Activity[activityID].DoneCount = doneCount; - if(completed) - state->ActiveTasks[activeTaskIndex].Activity[activityID].State = ActivityCompleted; - else - state->ActiveTasks[activeTaskIndex].Activity[activityID].State = ActivityHidden; + if (task_info == nullptr) { + Log(Logs::General, Logs::Error, + "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID); + continue; + } - state->ActiveTasks[activeTaskIndex].Activity[activityID].Updated = false; + int doneCount = atoi(row[2]); + bool completed = atoi(row[3]); + task_info->Activity[activityID].ActivityID = activityID; + task_info->Activity[activityID].DoneCount = doneCount; + if (completed) + task_info->Activity[activityID].State = ActivityCompleted; + else + task_info->Activity[activityID].State = ActivityHidden; - Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, ActivityID: %i, DoneCount: %i, Completed: %i", characterID, taskID, activityID, doneCount, completed); + task_info->Activity[activityID].Updated = false; - } + Log(Logs::General, Logs::Tasks, + "[CLIENTLOAD] TaskManager::LoadClientState. Char: %i Task ID %i, ActivityID: %i, DoneCount: %i, " + "Completed: %i", + characterID, taskID, activityID, doneCount, completed); + } - if(RuleB(TaskSystem, RecordCompletedTasks)) { - query = StringFormat("SELECT `taskid`, `activityid`, `completedtime` " - "FROM `completed_tasks` " - "WHERE `charid` = %i ORDER BY completedtime, taskid, activityid", - characterID); - results = database.QueryDatabase(query); - if (!results.Success()) { - Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", results.ErrorMessage().c_str()); + if (RuleB(TaskSystem, RecordCompletedTasks)) { + query = StringFormat("SELECT `taskid`, `activityid`, `completedtime` " + "FROM `completed_tasks` " + "WHERE `charid` = %i ORDER BY completedtime, taskid, activityid", + characterID); + results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, + "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", + results.ErrorMessage().c_str()); return false; - } + } CompletedTaskInformation cti; - for(int i=0; i=MAXTASKS)) { - Log(Logs::General, Logs::Error, "[TASKS]Task ID %i out of range while loading completed tasks from database", taskID); - continue; - } + int taskID = atoi(row[0]); + if ((taskID <= 0) || (taskID >= MAXTASKS)) { + Log(Logs::General, Logs::Error, + "[TASKS]Task ID %i out of range while loading completed tasks from database", + taskID); + continue; + } - // An ActivityID of -1 means mark all the none optional activities in the - // task as complete. If the Rule to record optional activities is enabled, - // subsequent records for this task will flag any optional tasks that were - // completed. - int activityID = atoi(row[1]); - if((activityID<-1) || (activityID>=MAXACTIVITIESPERTASK)) { - Log(Logs::General, Logs::Error, "[TASKS]Activity ID %i out of range while loading completed tasks from database", activityID); - continue; - } + // An ActivityID of -1 means mark all the none optional activities in the + // task as complete. If the Rule to record optional activities is enabled, + // subsequent records for this task will flag any optional tasks that were + // completed. + int activityID = atoi(row[1]); + if ((activityID < -1) || (activityID >= MAXACTIVITIESPERTASK)) { + Log(Logs::General, Logs::Error, + "[TASKS]Activity ID %i out of range while loading completed tasks from database", + activityID); + continue; + } - int completedTime = atoi(row[2]); - if((previousTaskID != -1) && ((taskID != previousTaskID) || (completedTime != previousCompletedTime))) { - state->CompletedTasks.push_back(cti); - for(int i=0; iCompletedTasks.push_back(cti); + for (int i = 0; i < MAXACTIVITIESPERTASK; i++) + cti.ActivityDone[i] = false; + } - cti.TaskID = previousTaskID = taskID; - cti.CompletedTime = previousCompletedTime = completedTime; + cti.TaskID = previousTaskID = taskID; + cti.CompletedTime = previousCompletedTime = completedTime; - // If ActivityID is -1, Mark all the non-optional tasks as completed. - if(activityID < 0) { - TaskInformation* task = Tasks[taskID]; - if(task == nullptr) - continue; + // If ActivityID is -1, Mark all the non-optional tasks as completed. + if (activityID < 0) { + TaskInformation *task = Tasks[taskID]; + if (task == nullptr) + continue; - for(int i=0; iActivityCount; i++) - if(!task->Activity[i].Optional) - cti.ActivityDone[i] = true; - } - else - cti.ActivityDone[activityID] = true; + for (int i = 0; i < task->ActivityCount; i++) + if (!task->Activity[i].Optional) + cti.ActivityDone[i] = true; + } else + cti.ActivityDone[activityID] = true; + } - } - - if(previousTaskID != -1) - state->CompletedTasks.push_back(cti); - - state->LastCompletedTaskLoaded = state->CompletedTasks.size(); + if (previousTaskID != -1) + state->CompletedTasks.push_back(cti); + state->LastCompletedTaskLoaded = state->CompletedTasks.size(); } - query = StringFormat("SELECT `taskid` FROM character_enabledtasks " - "WHERE `charid` = %i AND `taskid` >0 AND `taskid` < %i " - "ORDER BY `taskid` ASC", - characterID, MAXTASKS); - results = database.QueryDatabase(query); + query = StringFormat("SELECT `taskid` FROM character_enabledtasks " + "WHERE `charid` = %i AND `taskid` >0 AND `taskid` < %i " + "ORDER BY `taskid` ASC", + characterID, MAXTASKS); + results = database.QueryDatabase(query); if (!results.Success()) { - Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", results.ErrorMessage().c_str()); - } - else { + Log(Logs::General, Logs::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", + results.ErrorMessage().c_str()); + } else { for (auto row = results.begin(); row != results.end(); ++row) { int taskID = atoi(row[0]); state->EnabledTasks.push_back(taskID); @@ -650,36 +671,45 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { // Check that there is an entry in the client task state for every activity in each task // This should only break if a ServerOP adds or deletes activites for a task that players already // have active, or due to a bug. - for(int i=0; iActiveTasks[i].TaskID; - if(taskID==TASKSLOTEMPTY) continue; - if(!Tasks[taskID]) { - c->Message(13, "Active Task Slot %i, references a task (%i), that does not exist. " - "Removing from memory. Contact a GM to resolve this.",i, taskID); - - Log(Logs::General, Logs::Error, "[TASKS]Character %i has task %i which does not exist.", characterID, taskID); - state->ActiveTasks[i].TaskID=TASKSLOTEMPTY; + if (taskID == TASKSLOTEMPTY) continue; + if (!Tasks[taskID]) { + c->Message(13, + "Active Task Slot %i, references a task (%i), that does not exist. " + "Removing from memory. Contact a GM to resolve this.", + i, taskID); + Log(Logs::General, Logs::Error, "[TASKS]Character %i has task %i which does not exist.", + characterID, taskID); + state->ActiveTasks[i].TaskID = TASKSLOTEMPTY; + continue; } - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Tasks[taskID]->ActivityCount; j++) { - if(state->ActiveTasks[i].Activity[j].ActivityID != j) { - c->Message(13, "Active Task %i, %s. Activity count does not match expected value." - "Removing from memory. Contact a GM to resolve this.", - taskID, Tasks[taskID]->Title); + if (state->ActiveTasks[i].Activity[j].ActivityID != j) { + c->Message(13, + "Active Task %i, %s. Activity count does not match expected value." + "Removing from memory. Contact a GM to resolve this.", + taskID, Tasks[taskID]->Title.c_str()); - Log(Logs::General, Logs::Error, "[TASKS]Fatal error in character %i task state. Activity %i for " - "Task %i either missing from client state or from task.", characterID, j, taskID); - state->ActiveTasks[i].TaskID=TASKSLOTEMPTY; + Log(Logs::General, Logs::Error, + "[TASKS]Fatal error in character %i task state. Activity %i for " + "Task %i either missing from client state or from task.", + characterID, j, taskID); + state->ActiveTasks[i].TaskID = TASKSLOTEMPTY; break; } } } - for(int i=0; iActiveTasks[i].TaskID != TASKSLOTEMPTY) - state->UnlockActivities(characterID, i); + if (state->ActiveTask.TaskID != TASKSLOTEMPTY) + state->UnlockActivities(characterID, state->ActiveTask); + // TODO: shared + for (int i = 0; i < MAXACTIVEQUESTS; i++) + if (state->ActiveQuests[i].TaskID != TASKSLOTEMPTY) + state->UnlockActivities(characterID, state->ActiveQuests[i]); Log(Logs::General, Logs::Tasks, "[CLIENTLOAD] LoadClientState for Character ID %d DONE!", characterID); return true; @@ -864,6 +894,27 @@ int ClientTaskState::CompletedTasksInSet(int TaskSetID) { return Count; } +bool ClientTaskState::HasSlotForTask(TaskInformation *task) +{ + if (task == nullptr) + return false; + + switch (task->type) { + case TaskType::Task: + return ActiveTask.TaskID == TASKSLOTEMPTY; + case TaskType::Shared: + return false; // todo + case TaskType::Quest: + for (int i = 0; i < MAXACTIVEQUESTS; ++i) + if (ActiveQuests[i].TaskID == TASKSLOTEMPTY) + return true; + case TaskType::E: + return false; // removed on live + } + + return false; +} + int TaskManager::FirstTaskInSet(int TaskSetID) { if((TaskSetID<=0) || (TaskSetID>=MAXTASKSETS)) return 0; @@ -935,77 +986,87 @@ int TaskManager::GetTaskMaxLevel(int TaskID) return -1; } -void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID) { - - unsigned int EnabledTaskIndex = 0; - unsigned int TaskSetIndex = 0; +void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID) +{ int TaskList[MAXCHOOSERENTRIES]; int TaskListIndex = 0; int PlayerLevel = c->GetLevel(); - Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSetSelector called for taskset %i. EnableTaskSize is %i", TaskSetID, - state->EnabledTasks.size()); - if((TaskSetID<=0) || (TaskSetID>=MAXTASKSETS)) return; + Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSetSelector called for taskset %i. EnableTaskSize is %i", + TaskSetID, state->EnabledTasks.size()); - if(!TaskSets[TaskSetID].empty()) { + if (TaskSetID <= 0 || TaskSetID >= MAXTASKSETS) + return; - // A TaskID of 0 in a TaskSet indicates that all Tasks in the set are enabled for all players. - - if(TaskSets[TaskSetID][0] == 0) { - - Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSets[%i][0] == 0. All Tasks in Set enabled.", TaskSetID); - auto Iterator = TaskSets[TaskSetID].begin(); - - while((Iterator != TaskSets[TaskSetID].end()) && (TaskListIndex < MAXCHOOSERENTRIES)) { - if(AppropriateLevel((*Iterator), PlayerLevel) && !state->IsTaskActive((*Iterator)) && - (IsTaskRepeatable((*Iterator)) || !state->IsTaskCompleted((*Iterator)))) - TaskList[TaskListIndex++] = (*Iterator); - - ++Iterator; - } - if(TaskListIndex > 0) - { - SendTaskSelector(c, mob, TaskListIndex, TaskList); - } - - return; - } + if (TaskSets[TaskSetID].empty()) { + mob->SayTo_StringID(c, CC_Yellow, MAX_ACTIVE_TASKS, c->GetName()); // I think this is suppose to be yellow + return; } + bool all_enabled = false; - while((EnabledTaskIndex < state->EnabledTasks.size()) && (TaskSetIndex < TaskSets[TaskSetID].size()) && - (TaskListIndex < MAXCHOOSERENTRIES)) { - - Log(Logs::General, Logs::Tasks, "[UPDATE] Comparing EnabledTasks[%i] (%i) with TaskSets[%i][%i] (%i)", - EnabledTaskIndex, state->EnabledTasks[EnabledTaskIndex], TaskSetID, TaskSetIndex, - TaskSets[TaskSetID][TaskSetIndex]); - - if((TaskSets[TaskSetID][TaskSetIndex] > 0) && - (state->EnabledTasks[EnabledTaskIndex] == TaskSets[TaskSetID][TaskSetIndex])) { - - if(AppropriateLevel(TaskSets[TaskSetID][TaskSetIndex], PlayerLevel) && - !state->IsTaskActive(TaskSets[TaskSetID][TaskSetIndex]) && - (IsTaskRepeatable(TaskSets[TaskSetID][TaskSetIndex]) || - !state->IsTaskCompleted(TaskSets[TaskSetID][TaskSetIndex]))) { - - TaskList[TaskListIndex++] = TaskSets[TaskSetID][TaskSetIndex]; - - EnabledTaskIndex++; - TaskSetIndex++; - continue; - } - } - - if(state->EnabledTasks[EnabledTaskIndex] < TaskSets[TaskSetID][TaskSetIndex]) - EnabledTaskIndex++; - else - TaskSetIndex++; + // A TaskID of 0 in a TaskSet indicates that all Tasks in the set are enabled for all players. + if (TaskSets[TaskSetID][0] == 0) { + Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSets[%i][0] == 0. All Tasks in Set enabled.", TaskSetID); + all_enabled = true; } - if(TaskListIndex == 0) return; + auto Iterator = TaskSets[TaskSetID].begin(); - SendTaskSelector(c, mob, TaskListIndex, TaskList); + if (all_enabled) + ++Iterator; // skip first when all enabled since it's useless data + while (Iterator != TaskSets[TaskSetID].end() && TaskListIndex < MAXCHOOSERENTRIES) { + auto task = *Iterator; + // verify level, we're not currently on it, repeatable status, if it's a (shared) task + // we aren't currently on another, and if it's enabled if not all_enabled + if ((all_enabled || state->IsTaskEnabled(task)) && AppropriateLevel(task, PlayerLevel) && + !state->IsTaskActive(task) && state->HasSlotForTask(Tasks[task]) && // this slot checking is a bit silly, but we allow mixing of task types ... + (IsTaskRepeatable(task) || !state->IsTaskCompleted(task))) + TaskList[TaskListIndex++] = task; + + ++Iterator; + } + + if (TaskListIndex > 0) { + SendTaskSelector(c, mob, TaskListIndex, TaskList); + } else { + mob->SayTo_StringID(c, CC_Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow + } + + return; +} + +// unlike the non-Quest version of this function, it does not check enabled, that is assumed the responsibility of the quest to handle +// we do however still want it to check the other stuff like level, active, room, etc +void TaskManager::TaskQuestSetSelector(Client *c, ClientTaskState *state, Mob *mob, int count, int *tasks) +{ + int TaskList[MAXCHOOSERENTRIES]; + int TaskListIndex = 0; + int PlayerLevel = c->GetLevel(); + + Log(Logs::General, Logs::Tasks, "[UPDATE] TaskQuestSetSelector called for array size %d", count); + + if (count <= 0) + return; + + for (int i = 0; i < count; ++i) { + auto task = tasks[i]; + // verify level, we're not currently on it, repeatable status, if it's a (shared) task + // we aren't currently on another, and if it's enabled if not all_enabled + if (AppropriateLevel(task, PlayerLevel) && + !state->IsTaskActive(task) && state->HasSlotForTask(Tasks[task]) && // this slot checking is a bit silly, but we allow mixing of task types ... + (IsTaskRepeatable(task) || !state->IsTaskCompleted(task))) + TaskList[TaskListIndex++] = task; + } + + if (TaskListIndex > 0) { + SendTaskSelector(c, mob, TaskListIndex, TaskList); + } else { + mob->SayTo_StringID(c, CC_Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow + } + + return; } void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *TaskList) { @@ -1017,221 +1078,166 @@ void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *Task } // Titanium OpCode: 0x5e7c Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSelector for %i Tasks", TaskCount); - char *Ptr; int PlayerLevel = c->GetLevel(); - AvailableTaskHeader_Struct* AvailableTaskHeader; - AvailableTaskData1_Struct* AvailableTaskData1; - AvailableTaskData2_Struct* AvailableTaskData2; - AvailableTaskTrailer_Struct* AvailableTaskTrailer; - // Check if any of the tasks exist - - - for(int i=0; iIsTaskActive(TaskList[i])) continue; - - if(!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) continue; + for (int i = 0; i < TaskCount; i++) { + if (!AppropriateLevel(TaskList[i], PlayerLevel)) + continue; + if (c->IsTaskActive(TaskList[i])) + continue; + if (!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) + continue; ValidTasks++; - - PacketLength = PacketLength + sizeof(AvailableTaskData1_Struct) + strlen(Tasks[TaskList[i]]->Title) + 1 + - strlen(Tasks[TaskList[i]]->Description) + 1 + sizeof(AvailableTaskData2_Struct) + 10 + - sizeof(AvailableTaskTrailer_Struct) + 5; } - if(ValidTasks == 0) return; + if (ValidTasks == 0) + return; - auto outapp = new EQApplicationPacket(OP_OpenNewTasksWindow, PacketLength); + SerializeBuffer buf(50 * ValidTasks); - AvailableTaskHeader = (AvailableTaskHeader_Struct*)outapp->pBuffer; - AvailableTaskHeader->TaskCount = ValidTasks; + buf.WriteUInt32(ValidTasks); + buf.WriteUInt32(2); // task type, live doesn't let you send more than one type, but we do? + buf.WriteUInt32(mob->GetID()); - // unknown1 is always 2 in the packets I have ssen. It may be a 'Task Type'. Given that the - // task system was apparently first introduced for LDoN missions, type 1 may be for missions. - // - AvailableTaskHeader->unknown1 = 2; - AvailableTaskHeader->TaskGiver = mob->GetID(); + for (int i = 0; i < TaskCount; i++) { + if (!AppropriateLevel(TaskList[i], PlayerLevel)) + continue; + if (c->IsTaskActive(TaskList[i])) + continue; + if (!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) + continue; - Ptr = (char *) AvailableTaskHeader + sizeof(AvailableTaskHeader_Struct); + buf.WriteUInt32(TaskList[i]); // TaskID + if (c->ClientVersion() != EQEmu::versions::ClientVersion::Titanium) + buf.WriteFloat(1.0f); // affects color, difficulty? + buf.WriteUInt32(Tasks[TaskList[i]]->Duration); + buf.WriteUInt32(static_cast(Tasks[TaskList[i]]->dur_code)); - for(int i=0; iTitle); // max 64 with null + buf.WriteString(Tasks[TaskList[i]]->Description); // max 4000 with null - if(!AppropriateLevel(TaskList[i], PlayerLevel)) continue; + if (c->ClientVersion() != EQEmu::versions::ClientVersion::Titanium) + buf.WriteUInt8(0); // Has reward set flag - if(c->IsTaskActive(TaskList[i])) continue; + buf.WriteUInt32(Tasks[TaskList[i]]->ActivityCount); - if(!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) continue; + for (int j = 0; j < Tasks[TaskList[i]]->ActivityCount; ++j) { + buf.WriteUInt32(j); // ActivityNumber + auto &activity = Tasks[TaskList[i]]->Activity[j]; + buf.WriteUInt32(activity.Type); + buf.WriteUInt32(0); // solo, group, raid? + buf.WriteString(activity.target_name); // max length 64, "target name" so like loot x foo from bar (this is bar) - AvailableTaskData1 = (AvailableTaskData1_Struct*)Ptr; + buf.WriteString(activity.item_list); // max length 64 in these clients - AvailableTaskData1->TaskID = TaskList[i]; + buf.WriteUInt32(activity.GoalCount); - AvailableTaskData1->TimeLimit = Tasks[TaskList[i]]->Duration; - - AvailableTaskData1->unknown2 = 0; - - Ptr = (char *)AvailableTaskData1 + sizeof(AvailableTaskData1_Struct); - - sprintf(Ptr, "%s", Tasks[TaskList[i]]->Title); - - Ptr = Ptr + strlen(Ptr) + 1; - - sprintf(Ptr, "%s", Tasks[TaskList[i]]->Description); - - Ptr = Ptr + strlen(Ptr) + 1; - - AvailableTaskData2 = (AvailableTaskData2_Struct*)Ptr; - - AvailableTaskData2->unknown1 = 1; - AvailableTaskData2->unknown2 = 0; - AvailableTaskData2->unknown3 = 1; - AvailableTaskData2->unknown4 = 0; - - Ptr = (char *)AvailableTaskData2 + sizeof(AvailableTaskData2_Struct); - - // FIXME: In live packets, these two strings appear to be the same as the Text1 and Text2 - // strings from the first activity in the task, however the task chooser/selector - // does not appear to make use of them. - sprintf(Ptr, "ABCD"); - Ptr = Ptr + strlen(Ptr) + 1; - sprintf(Ptr, "ABCD"); - Ptr = Ptr + strlen(Ptr) + 1; - - AvailableTaskTrailer = (AvailableTaskTrailer_Struct*)Ptr; - - // The name of this ItemCount field may be incorrect, but 1 works. - AvailableTaskTrailer->ItemCount = 1; - AvailableTaskTrailer->unknown1 = 0xFFFFFFFF; - AvailableTaskTrailer->unknown2 = 0xFFFFFFFF; - AvailableTaskTrailer->StartZone = Tasks[TaskList[i]]->StartZone; - - Ptr = (char *)AvailableTaskTrailer + sizeof(AvailableTaskTrailer_Struct); - - // In some packets, this next string looks like a short task summary, however it doesn't - // appear anywhere in the client window. - sprintf(Ptr, "ABCD"); - Ptr = Ptr + strlen(Ptr) + 1; + buf.WriteInt32(activity.skill_id); + buf.WriteInt32(activity.spell_id); + buf.WriteInt32(activity.ZoneID); + buf.WriteString(activity.desc_override); + } } + auto outapp = new EQApplicationPacket(OP_OpenNewTasksWindow, buf); c->QueuePacket(outapp); safe_delete(outapp); } -void TaskManager::SendTaskSelectorNew(Client *c, Mob *mob, int TaskCount, int *TaskList) { - +void TaskManager::SendTaskSelectorNew(Client *c, Mob *mob, int TaskCount, int *TaskList) +{ Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSelector for %i Tasks", TaskCount); int PlayerLevel = c->GetLevel(); // Check if any of the tasks exist - for(int i=0; iIsTaskActive(TaskList[i])) continue; - - if(!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) continue; + for (int i = 0; i < TaskCount; i++) { + if (!AppropriateLevel(TaskList[i], PlayerLevel)) + continue; + if (c->IsTaskActive(TaskList[i])) + continue; + if (!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) + continue; ValidTasks++; - - PacketLength += 21; // Task Data - strings - PacketLength += strlen(Tasks[TaskList[i]]->Title) + 1 + - strlen(Tasks[TaskList[i]]->Description) + 1; - - sprintf(StartZone, "%i", Tasks[TaskList[i]]->StartZone); - /* - PacketLength += strlen(Tasks[TaskList[i]]->Activity[ActivityID].Text1) + 1 + - strlen(Tasks[TaskList[i]]->Activity[ActivityID].Text2) + - strlen(Tasks[TaskList[i]]->Activity[ActivityID].Text3) + 1 + - strlen(itoa(Tasks[TaskList[i]]->Activity[ActivityID].ZoneID)) + 1 + - 3 + 3 + 5; // Other strings (Hard set for now) - */ - PacketLength += 11 + 11 + 11 + 3 + 3 + (strlen(StartZone) * 2) + 2; // Other strings (Hard set for now) - PacketLength += 28; // Activity Data - strings (Hard set for 1 activity per task for now) } - if(ValidTasks == 0) return; + if (ValidTasks == 0) + return; - auto outapp = new EQApplicationPacket(OP_OpenNewTasksWindow, PacketLength); + SerializeBuffer buf(50 * ValidTasks); - outapp->WriteUInt32(ValidTasks); // TaskCount - outapp->WriteUInt32(2); // Unknown2 - outapp->WriteUInt32(mob->GetID()); // TaskGiver + buf.WriteUInt32(ValidTasks); // TaskCount + buf.WriteUInt32(2); // Type, valid values: 0-3. 0 = Task, 1 = Shared Task, 2 = Quest, 3 = ??? -- should fix maybe some day, but we let more than 1 type through :P + // so I guess an NPC can only offer one type of quests or we can only open a selection with one type :P (so quest call can tell us I guess) + // this is also sent in OP_TaskDescription + buf.WriteUInt32(mob->GetID()); // TaskGiver - for(int i=0; iIsTaskActive(TaskList[i])) + continue; + if (!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) + continue; - if(!AppropriateLevel(TaskList[i], PlayerLevel)) continue; + buf.WriteUInt32(TaskList[i]); // TaskID + buf.WriteFloat(1.0f); // affects color, difficulty? + buf.WriteUInt32(Tasks[TaskList[i]]->Duration); + buf.WriteUInt32(static_cast(Tasks[TaskList[i]]->dur_code)); // 1 = Short, 2 = Medium, 3 = Long, anything else Unlimited - if(c->IsTaskActive(TaskList[i])) continue; + buf.WriteString(Tasks[TaskList[i]]->Title); // max 64 with null + buf.WriteString(Tasks[TaskList[i]]->Description); // max 4000 with null - if(!IsTaskRepeatable(TaskList[i]) && c->IsTaskCompleted(TaskList[i])) continue; + buf.WriteUInt8(0); // Has reward set flag + buf.WriteUInt32(Tasks[TaskList[i]]->ActivityCount); // ActivityCount - outapp->WriteUInt32(TaskList[i]); // TaskID - outapp->WriteFloat(1.0f); - outapp->WriteUInt32(Tasks[TaskList[i]]->Duration); - outapp->WriteUInt32(0); // Unknown7 + for (int j = 0; j < Tasks[TaskList[i]]->ActivityCount; ++j) { + buf.WriteUInt32(j); // ActivityNumber + auto &activity = Tasks[TaskList[i]]->Activity[j]; + buf.WriteUInt32(activity.Type); // ActivityType + buf.WriteUInt32(0); // solo, group, raid? + buf.WriteString(activity.target_name); // max length 64, "target name" so like loot x foo from bar (this is bar) - outapp->WriteString(Tasks[TaskList[i]]->Title); - outapp->WriteString(Tasks[TaskList[i]]->Description); + // this string is item names + buf.WriteLengthString(activity.item_list); - outapp->WriteUInt8(0); // Unknown10 - Empty string ? - outapp->WriteUInt32(1); // ActivityCount - Hard set to 1 for now + buf.WriteUInt32(activity.GoalCount); // GoalCount - // Activity stuff below - Will need to iterate through each task - // Currently hard set for testing + // this string is skill IDs? probably one of the "use on" tasks + buf.WriteLengthString(activity.skill_list); + // this string is spell IDs? probably one of the "use on" tasks + buf.WriteLengthString(activity.spell_list); - sprintf(StartZone, "%i", Tasks[TaskList[i]]->StartZone); - - outapp->WriteUInt32(0); // ActivityNumber - outapp->WriteUInt32(1); // ActivityType - outapp->WriteUInt32(0); // Unknown14 - outapp->WriteString("Text1 Test"); - outapp->WriteUInt32(11); // Text2Len - outapp->WriteString("Text2 Test"); - outapp->WriteUInt32(1); // GoalCount - outapp->WriteUInt32(3); // NumString1Len - outapp->WriteString("-1"); - outapp->WriteUInt32(3); // NumString2Len - outapp->WriteString("-1"); - //outapp->WriteString(itoa(Tasks[TaskList[i]]->Activity[ActivityID].ZoneID)); - outapp->WriteString(StartZone); // Zone number in ascii - outapp->WriteString("Text3 Test"); - outapp->WriteString(StartZone); // Zone number in ascii + //buf.WriteString(itoa(Tasks[TaskList[i]]->Activity[ActivityID].ZoneID)); + buf.WriteString(activity.zones); // Zone number in ascii max length 64, can be multiple with separated by ; + buf.WriteString(activity.desc_override); // max length 128 -- overrides the automatic descriptions + // this doesn't appear to be shown to the client at all and isn't the same as zones ... defaults to '0' though + buf.WriteString(activity.zones); // Zone number in ascii max length 64, probably can be separated by ; too, haven't found it used + } } + auto outapp = new EQApplicationPacket(OP_OpenNewTasksWindow, buf); + c->QueuePacket(outapp); safe_delete(outapp); @@ -1268,7 +1274,7 @@ void TaskManager::ExplainTask(Client*c, int TaskID) { } char Explanation[1000], *ptr; - c->Message(0, "Task %4i: Title: %s", TaskID, Tasks[TaskID]->Description); + c->Message(0, "Task %4i: Title: %s", TaskID, Tasks[TaskID]->Description.c_str()); c->Message(0, "%3i Activities", Tasks[TaskID]->ActivityCount); ptr = Explanation; for(int i=0; iActivityCount; i++) { @@ -1289,8 +1295,14 @@ ClientTaskState::ClientTaskState() { LastCompletedTaskLoaded = 0; CheckedTouchActivities = false; - for(int i=0; i=MAXACTIVETASKS)) return 0; + if((index<0) || (index>=MAXACTIVEQUESTS)) return 0; - return ActiveTasks[index].TaskID; + return ActiveQuests[index].TaskID; } static void DeleteCompletedTaskFromDatabase(int charID, int taskID) { @@ -1319,69 +1331,75 @@ static void DeleteCompletedTaskFromDatabase(int charID, int taskID) { Log(Logs::General, Logs::Tasks, "[UPDATE] Delete query %s", query.c_str()); } -bool ClientTaskState::UnlockActivities(int CharID, int TaskIndex) { - +bool ClientTaskState::UnlockActivities(int CharID, ClientTaskInformation &task_info) +{ bool AllActivitiesComplete = true; - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[TaskIndex].TaskID]; + TaskInformation* Task = taskmanager->Tasks[task_info.TaskID]; - if(Task==nullptr) return true; + if (Task == nullptr) + return true; // On loading the client state, all activities that are not completed, are // marked as hidden. For Sequential (non-stepped) mode, we mark the first // activity as active if not complete. Log(Logs::General, Logs::Tasks, "[UPDATE] CharID: %i Task: %i Sequence mode is %i", - CharID, ActiveTasks[TaskIndex].TaskID, Task->SequenceMode); - if(Task->SequenceMode == ActivitiesSequential) { + CharID, task_info.TaskID, Task->SequenceMode); - if(ActiveTasks[TaskIndex].Activity[0].State != ActivityCompleted) - ActiveTasks[TaskIndex].Activity[0].State = ActivityActive; + if (Task->SequenceMode == ActivitiesSequential) { + if (task_info.Activity[0].State != ActivityCompleted) + task_info.Activity[0].State = ActivityActive; // Enable the next Hidden task. - for(int i=0; iActivityCount; i++) { - if((ActiveTasks[TaskIndex].Activity[i].State == ActivityActive) && - (!Task->Activity[i].Optional)) { + for (int i = 0; i < Task->ActivityCount; i++) { + if ((task_info.Activity[i].State == ActivityActive) && + (!Task->Activity[i].Optional)) { AllActivitiesComplete = false; break; } - if(ActiveTasks[TaskIndex].Activity[i].State == ActivityHidden) { - ActiveTasks[TaskIndex].Activity[i].State = ActivityActive; + + if (task_info.Activity[i].State == ActivityHidden) { + task_info.Activity[i].State = ActivityActive; AllActivitiesComplete = false; break; } } - if(AllActivitiesComplete && RuleB(TaskSystem, RecordCompletedTasks)) { - if(RuleB(TasksSystem, KeepOneRecordPerCompletedTask)) { + + if (AllActivitiesComplete && RuleB(TaskSystem, RecordCompletedTasks)) { + if (RuleB(TasksSystem, KeepOneRecordPerCompletedTask)) { Log(Logs::General, Logs::Tasks, "[UPDATE] KeepOneRecord enabled"); auto Iterator = CompletedTasks.begin(); int ErasedElements = 0; - while(Iterator != CompletedTasks.end()) { + while (Iterator != CompletedTasks.end()) { int TaskID = (*Iterator).TaskID; - if(TaskID == ActiveTasks[TaskIndex].TaskID) { + if (TaskID == task_info.TaskID) { Iterator = CompletedTasks.erase(Iterator); ErasedElements++; - } - else + } else ++Iterator; } - Log(Logs::General, Logs::Tasks, "[UPDATE] Erased Element count is %i", ErasedElements); - if(ErasedElements) { - LastCompletedTaskLoaded -= ErasedElements; - DeleteCompletedTaskFromDatabase(CharID, ActiveTasks[TaskIndex].TaskID); - } + Log(Logs::General, Logs::Tasks, "[UPDATE] Erased Element count is %i", ErasedElements); + + if (ErasedElements) { + LastCompletedTaskLoaded -= ErasedElements; + DeleteCompletedTaskFromDatabase(CharID, task_info.TaskID); + } } CompletedTaskInformation cti; - cti.TaskID = ActiveTasks[TaskIndex].TaskID; + cti.TaskID = task_info.TaskID; cti.CompletedTime = time(nullptr); - for(int i=0; iActivityCount; i++) - cti.ActivityDone[i] = (ActiveTasks[TaskIndex].Activity[i].State == ActivityCompleted); + for (int i = 0; i < Task->ActivityCount; i++) + cti.ActivityDone[i] = (task_info.Activity[i].State == ActivityCompleted); CompletedTasks.push_back(cti); } - Log(Logs::General, Logs::Tasks, "[UPDATE] Returning sequential task, AllActivitiesComplete is %i", AllActivitiesComplete); + + Log(Logs::General, Logs::Tasks, "[UPDATE] Returning sequential task, AllActivitiesComplete is %i", + AllActivitiesComplete); + return AllActivitiesComplete; } @@ -1390,66 +1408,69 @@ bool ClientTaskState::UnlockActivities(int CharID, int TaskIndex) { bool CurrentStepComplete = true; - Log(Logs::General, Logs::Tasks, "[UPDATE] Current Step is %i, Last Step is %i", ActiveTasks[TaskIndex].CurrentStep, Task->LastStep); + Log(Logs::General, Logs::Tasks, "[UPDATE] Current Step is %i, Last Step is %i", task_info.CurrentStep, + Task->LastStep); // If CurrentStep is -1, this is the first call to this method since loading the // client state. Unlock all activities with a step number of 0 - if(ActiveTasks[TaskIndex].CurrentStep == -1) { - for(int i=0; iActivityCount; i++) { - if((Task->Activity[i].StepNumber == 0) && - (ActiveTasks[TaskIndex].Activity[i].State == ActivityHidden)) { - ActiveTasks[TaskIndex].Activity[i].State = ActivityActive; - //ActiveTasks[TaskIndex].Activity[i].Updated=true; + if (task_info.CurrentStep == -1) { + for (int i = 0; i < Task->ActivityCount; i++) { + if (Task->Activity[i].StepNumber == 0 && task_info.Activity[i].State == ActivityHidden) { + task_info.Activity[i].State = ActivityActive; + // task_info.Activity[i].Updated=true; } } - ActiveTasks[TaskIndex].CurrentStep = 0; + task_info.CurrentStep = 0; } - for(int Step=ActiveTasks[TaskIndex].CurrentStep; Step<=Task->LastStep; Step++) { - for(int Activity=0; ActivityActivityCount; Activity++) { - if(Task->Activity[Activity].StepNumber == (int)ActiveTasks[TaskIndex].CurrentStep) { - if((ActiveTasks[TaskIndex].Activity[Activity].State != ActivityCompleted) && - (!Task->Activity[Activity].Optional)) { + for (int Step = task_info.CurrentStep; Step <= Task->LastStep; Step++) { + for (int Activity = 0; Activity < Task->ActivityCount; Activity++) { + if (Task->Activity[Activity].StepNumber == (int)task_info.CurrentStep) { + if ((task_info.Activity[Activity].State != ActivityCompleted) && + (!Task->Activity[Activity].Optional)) { CurrentStepComplete = false; AllActivitiesComplete = false; break; } } } - if(!CurrentStepComplete) break; - ActiveTasks[TaskIndex].CurrentStep++; + if (!CurrentStepComplete) + break; + task_info.CurrentStep++; } - if(AllActivitiesComplete) { - if(RuleB(TaskSystem, RecordCompletedTasks)) { + if (AllActivitiesComplete) { + if (RuleB(TaskSystem, RecordCompletedTasks)) { // If we are only keeping one completed record per task, and the player has done // the same task again, erase the previous completed entry for this task. - if(RuleB(TasksSystem, KeepOneRecordPerCompletedTask)) { + if (RuleB(TasksSystem, KeepOneRecordPerCompletedTask)) { Log(Logs::General, Logs::Tasks, "[UPDATE] KeepOneRecord enabled"); auto Iterator = CompletedTasks.begin(); int ErasedElements = 0; - while(Iterator != CompletedTasks.end()) { + + while (Iterator != CompletedTasks.end()) { int TaskID = (*Iterator).TaskID; - if(TaskID == ActiveTasks[TaskIndex].TaskID) { + if (TaskID == task_info.TaskID) { Iterator = CompletedTasks.erase(Iterator); ErasedElements++; - } - else + } else ++Iterator; } - Log(Logs::General, Logs::Tasks, "[UPDATE] Erased Element count is %i", ErasedElements); - if(ErasedElements) { - LastCompletedTaskLoaded -= ErasedElements; - DeleteCompletedTaskFromDatabase(CharID, ActiveTasks[TaskIndex].TaskID); - } + Log(Logs::General, Logs::Tasks, "[UPDATE] Erased Element count is %i", ErasedElements); + + if (ErasedElements) { + LastCompletedTaskLoaded -= ErasedElements; + DeleteCompletedTaskFromDatabase(CharID, task_info.TaskID); + } } + CompletedTaskInformation cti; - cti.TaskID = ActiveTasks[TaskIndex].TaskID; + cti.TaskID = task_info.TaskID; cti.CompletedTime = time(nullptr); - for(int i=0; iActivityCount; i++) - cti.ActivityDone[i] = (ActiveTasks[TaskIndex].Activity[i].State == ActivityCompleted); + for (int i = 0; i < Task->ActivityCount; i++) + cti.ActivityDone[i] = (task_info.Activity[i].State == ActivityCompleted); CompletedTasks.push_back(cti); } @@ -1458,19 +1479,17 @@ bool ClientTaskState::UnlockActivities(int CharID, int TaskIndex) { // Mark all non-completed tasks in the current step as active // - for(int Activity=0; ActivityActivityCount; Activity++) { - if((Task->Activity[Activity].StepNumber == (int)ActiveTasks[TaskIndex].CurrentStep) && - (ActiveTasks[TaskIndex].Activity[Activity].State == ActivityHidden)) { - ActiveTasks[TaskIndex].Activity[Activity].State = ActivityActive; - ActiveTasks[TaskIndex].Activity[Activity].Updated=true; + for (int Activity = 0; Activity < Task->ActivityCount; Activity++) { + if ((Task->Activity[Activity].StepNumber == (int)task_info.CurrentStep) && + (task_info.Activity[Activity].State == ActivityHidden)) { + task_info.Activity[Activity].State = ActivityActive; + task_info.Activity[Activity].Updated = true; } } return false; - } - void ClientTaskState::UpdateTasksOnKill(Client *c, int NPCTypeID) { UpdateTasksByNPC(c, ActivityKill, NPCTypeID); @@ -1491,47 +1510,57 @@ bool ClientTaskState::UpdateTasksByNPC(Client *c, int ActivityType, int NPCTypeI // If the client has no tasks, there is nothing further to check. - if(!taskmanager || ActiveTaskCount == 0) return false; + if (!taskmanager || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) // could be better ... + return false; - for(int i=0; iTaskID == TASKSLOTEMPTY) + continue; // Check if there are any active kill activities for this task - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + auto Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) return false; + if (Task == nullptr) + return false; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; + if (cur_task->Activity[j].State != ActivityActive) + continue; // We are only interested in Kill activities - if(Task->Activity[j].Type != ActivityType) continue; + if (Task->Activity[j].Type != ActivityType) + continue; // Is there a zone restriction on the activity ? - if((Task->Activity[j].ZoneID >0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { - Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Task: %i, Activity %i, Activity type %i for NPC %i failed zone check", - c->GetName(), ActiveTasks[i].TaskID, j, ActivityType, NPCTypeID); + if ((Task->Activity[j].ZoneID > 0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { + Log(Logs::General, Logs::Tasks, + "[UPDATE] Char: %s Task: %i, Activity %i, Activity type %i for NPC %i failed zone " + "check", + c->GetName(), cur_task->TaskID, j, ActivityType, NPCTypeID); continue; } // Is the activity to kill this type of NPC ? - switch(Task->Activity[j].GoalMethod) { + switch (Task->Activity[j].GoalMethod) { - case METHODSINGLEID: - if(Task->Activity[j].GoalID != NPCTypeID) continue; - break; - - case METHODLIST: - if(!taskmanager->GoalListManager.IsInList(Task->Activity[j].GoalID, - NPCTypeID)) continue; - break; - - default: - // If METHODQUEST, don't update the activity here + case METHODSINGLEID: + if (Task->Activity[j].GoalID != NPCTypeID) continue; + break; + + case METHODLIST: + if (!taskmanager->GoalListManager.IsInList(Task->Activity[j].GoalID, NPCTypeID)) + continue; + break; + + default: + // If METHODQUEST, don't update the activity here + continue; } // We found an active task to kill this type of NPC, so increment the done count Log(Logs::General, Logs::Tasks, "[UPDATE] Calling increment done count ByNPC"); - IncrementDoneCount(c, Task, i, j); + IncrementDoneCount(c, Task, cur_task->slot, j); Ret = true; } } @@ -1544,26 +1573,32 @@ int ClientTaskState::ActiveSpeakTask(int NPCTypeID) { // This method is to be used from Perl quests only and returns the TaskID of the first // active task found which has an active SpeakWith activity for this NPC. - if(!taskmanager || ActiveTaskCount == 0) return 0; + if (!taskmanager || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) // could be better ... + return 0; - for(int i=0; iTaskID == TASKSLOTEMPTY) + continue; - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation* Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) continue; + if (Task == nullptr) + continue; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; - if(Task->Activity[j].Type != ActivitySpeakWith) continue; - // Is there a zone restriction on the activity ? - if((Task->Activity[j].ZoneID >0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { + if (cur_task->Activity[j].State != ActivityActive) + continue; + if (Task->Activity[j].Type != ActivitySpeakWith) + continue; + // Is there a zone restriction on the activity ? + if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) continue; - } // Is the activity to speak with this type of NPC ? - if((Task->Activity[j].GoalMethod == METHODQUEST) && - (Task->Activity[j].GoalID == NPCTypeID)) return ActiveTasks[i].TaskID; + if (Task->Activity[j].GoalMethod == METHODQUEST && Task->Activity[j].GoalID == NPCTypeID) + return cur_task->TaskID; } } return 0; @@ -1574,32 +1609,40 @@ int ClientTaskState::ActiveSpeakActivity(int NPCTypeID, int TaskID) { // This method is to be used from Perl quests only and returns the ActivityID of the first // active activity found in the specified task which is to SpeakWith this NPC. - if(!taskmanager || ActiveTaskCount == 0) return -1; - if((TaskID<=0) || (TaskID>=MAXTASKS)) return -1; + if (!taskmanager || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) // could be better ... + return -1; + if (TaskID <= 0 || TaskID >= MAXTASKS) + return -1; - for(int i=0; iTaskID != TaskID) + continue; - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation* Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) continue; + if (Task == nullptr) + continue; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; - if(Task->Activity[j].Type != ActivitySpeakWith) continue; - // Is there a zone restriction on the activity ? - if((Task->Activity[j].ZoneID >0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { + if (cur_task->Activity[j].State != ActivityActive) + continue; + if (Task->Activity[j].Type != ActivitySpeakWith) + continue; + // Is there a zone restriction on the activity ? + if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) continue; - } // Is the activity to speak with this type of NPC ? - if((Task->Activity[j].GoalMethod == METHODQUEST) && - (Task->Activity[j].GoalID == NPCTypeID)) return j; + if (Task->Activity[j].GoalMethod == METHODQUEST && Task->Activity[j].GoalID == NPCTypeID) + return j; } return 0; } return 0; } + void ClientTaskState::UpdateTasksForItem(Client *c, ActivityType Type, int ItemID, int Count) { // This method updates the client's task activities of the specified type which relate @@ -1611,24 +1654,31 @@ void ClientTaskState::UpdateTasksForItem(Client *c, ActivityType Type, int ItemI Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState::UpdateTasksForItem(%d,%d)", Type, ItemID); - if(ActiveTaskCount == 0) return; + if (!taskmanager || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) // could be better ... + return; - for(int i=0; iTaskID == TASKSLOTEMPTY) + continue; // Check if there are any active loot activities for this task - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation* Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) return; + if (Task == nullptr) + return; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; + if (cur_task->Activity[j].State != ActivityActive) + continue; // We are only interested in the ActivityType we were called with - if(Task->Activity[j].Type != (int)Type) continue; + if (Task->Activity[j].Type != (int)Type) + continue; // Is there a zone restriction on the activity ? - if((Task->Activity[j].ZoneID >0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { + if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) { Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Activity type %i for Item %i failed zone check", c->GetName(), Type, ItemID); continue; @@ -1651,125 +1701,144 @@ void ClientTaskState::UpdateTasksForItem(Client *c, ActivityType Type, int ItemI } // We found an active task related to this item, so increment the done count Log(Logs::General, Logs::Tasks, "[UPDATE] Calling increment done count ForItem"); - IncrementDoneCount(c, Task, i, j, Count); + IncrementDoneCount(c, Task, cur_task->slot, j, Count); } } return; } -void ClientTaskState::UpdateTasksOnExplore(Client *c, int ExploreID) { +void ClientTaskState::UpdateTasksOnExplore(Client *c, int ExploreID) +{ // If the client has no tasks, there is nothing further to check. Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState::UpdateTasksOnExplore(%i)", ExploreID); - if(ActiveTaskCount == 0) return; + if (!taskmanager || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) // could be better ... + return; - for(int i=0; iTaskID == TASKSLOTEMPTY) + continue; // Check if there are any active explore activities for this task - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation *Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) return; + if (Task == nullptr) + return; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; + if (cur_task->Activity[j].State != ActivityActive) + continue; // We are only interested in explore activities - if(Task->Activity[j].Type != ActivityExplore) continue; - if((Task->Activity[j].ZoneID >0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { - Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Explore exploreid %i failed zone check", - c->GetName(), ExploreID); + if (Task->Activity[j].Type != ActivityExplore) + continue; + if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) { + Log(Logs::General, Logs::Tasks, + "[UPDATE] Char: %s Explore exploreid %i failed zone check", c->GetName(), + ExploreID); continue; } // Is the activity to explore this area id ? - switch(Task->Activity[j].GoalMethod) { + switch (Task->Activity[j].GoalMethod) { - case METHODSINGLEID: - if(Task->Activity[j].GoalID != ExploreID) continue; - break; - - case METHODLIST: - if(!taskmanager->GoalListManager.IsInList(Task->Activity[j].GoalID, - ExploreID)) continue; - break; - - default: - // If METHODQUEST, don't update the activity here + case METHODSINGLEID: + if (Task->Activity[j].GoalID != ExploreID) continue; + break; + + case METHODLIST: + if (!taskmanager->GoalListManager.IsInList(Task->Activity[j].GoalID, ExploreID)) + continue; + break; + + default: + // If METHODQUEST, don't update the activity here + continue; } // We found an active task to explore this area, so set done count to goal count // (Only a goal count of 1 makes sense for explore activities?) Log(Logs::General, Logs::Tasks, "[UPDATE] Increment on explore"); - IncrementDoneCount(c, Task, i, j, - Task->Activity[j].GoalCount - ActiveTasks[i].Activity[j].DoneCount); - + IncrementDoneCount(c, Task, cur_task->slot, j, + Task->Activity[j].GoalCount - cur_task->Activity[j].DoneCount); } } return; } -bool ClientTaskState::UpdateTasksOnDeliver(Client *c, std::list& Items, int Cash, int NPCTypeID) { - +bool ClientTaskState::UpdateTasksOnDeliver(Client *c, std::list &Items, int Cash, int NPCTypeID) +{ bool Ret = false; Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState::UpdateTasksForOnDeliver(%d)", NPCTypeID); - if(ActiveTaskCount == 0) return false; + if (!taskmanager || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) // could be better ... + return false; - for(int i=0; iTaskID == TASKSLOTEMPTY) + continue; // Check if there are any active deliver activities for this task - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation *Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) return false; + if (Task == nullptr) + return false; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; + if (cur_task->Activity[j].State != ActivityActive) + continue; // We are only interested in Deliver activities - if((Task->Activity[j].Type != ActivityDeliver) && - (Task->Activity[j].Type != ActivityGiveCash)) continue; + if (Task->Activity[j].Type != ActivityDeliver && Task->Activity[j].Type != ActivityGiveCash) + continue; // Is there a zone restriction on the activity ? - if((Task->Activity[j].ZoneID >0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) { - Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Deliver activity failed zone check (current zone %i, need zone %i", - c->GetName(), zone->GetZoneID(), Task->Activity[j].ZoneID); + if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) { + Log(Logs::General, Logs::Tasks, + "[UPDATE] Char: %s Deliver activity failed zone check (current zone %i, need zone " + "%i", + c->GetName(), zone->GetZoneID(), Task->Activity[j].ZoneID); continue; } // Is the activity to deliver to this NPCTypeID ? - if(Task->Activity[j].DeliverToNPC != NPCTypeID) continue; + if (Task->Activity[j].DeliverToNPC != NPCTypeID) + continue; // Is the activity related to these items ? // - if((Task->Activity[j].Type == ActivityGiveCash) && Cash) { + if ((Task->Activity[j].Type == ActivityGiveCash) && Cash) { Log(Logs::General, Logs::Tasks, "[UPDATE] Increment on GiveCash"); IncrementDoneCount(c, Task, i, j, Cash); Ret = true; - } - else { - for(auto& k : Items) { - switch(Task->Activity[j].GoalMethod) { + } else { + for (auto &k : Items) { + switch (Task->Activity[j].GoalMethod) { - case METHODSINGLEID: - if(Task->Activity[j].GoalID != k->GetID()) continue; - break; - - case METHODLIST: - if (!taskmanager->GoalListManager.IsInList(Task->Activity[j].GoalID, k->GetID())) - continue; - break; - - default: - // If METHODQUEST, don't update the activity here + case METHODSINGLEID: + if (Task->Activity[j].GoalID != k->GetID()) continue; + break; + + case METHODLIST: + if (!taskmanager->GoalListManager.IsInList(Task->Activity[j].GoalID, + k->GetID())) + continue; + break; + + default: + // If METHODQUEST, don't update the activity here + continue; } // We found an active task related to this item, so increment the done count Log(Logs::General, Logs::Tasks, "[UPDATE] Increment on GiveItem"); - IncrementDoneCount(c, Task, i, j, k->GetCharges() <= 0 ? 1 : k->GetCharges()); + IncrementDoneCount(c, Task, cur_task->slot, j, k->GetCharges() <= 0 ? 1 : k->GetCharges()); Ret = true; } } @@ -1779,89 +1848,104 @@ bool ClientTaskState::UpdateTasksOnDeliver(Client *c, std::listTaskID == TASKSLOTEMPTY) + continue; // Check if there are any active explore activities for this task - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation *Task = taskmanager->Tasks[cur_task->TaskID]; - if(Task == nullptr) return; + if (Task == nullptr) + return; - for(int j=0; jActivityCount; j++) { + for (int j = 0; j < Task->ActivityCount; j++) { // We are not interested in completed or hidden activities - if(ActiveTasks[i].Activity[j].State != ActivityActive) continue; + if (cur_task->Activity[j].State != ActivityActive) + continue; // We are only interested in touch activities - if(Task->Activity[j].Type != ActivityTouch) continue; - if(Task->Activity[j].GoalMethod != METHODSINGLEID) continue; - if(Task->Activity[j].ZoneID != ZoneID) { + if (Task->Activity[j].Type != ActivityTouch) + continue; + if (Task->Activity[j].GoalMethod != METHODSINGLEID) + continue; + if (Task->Activity[j].ZoneID != ZoneID) { Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Touch activity failed zone check", - c->GetName()); + c->GetName()); continue; } // We found an active task to zone into this zone, so set done count to goal count // (Only a goal count of 1 makes sense for touch activities?) Log(Logs::General, Logs::Tasks, "[UPDATE] Increment on Touch"); - IncrementDoneCount(c, Task, i, j, - Task->Activity[j].GoalCount - ActiveTasks[i].Activity[j].DoneCount); + IncrementDoneCount(c, Task, cur_task->slot, j, + Task->Activity[j].GoalCount - cur_task->Activity[j].DoneCount); } } return; } -void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int TaskIndex, int ActivityID, int Count, bool ignore_quest_update) { +void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count, + bool ignore_quest_update) +{ Log(Logs::General, Logs::Tasks, "[UPDATE] IncrementDoneCount"); - ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount += Count; + auto info = GetClientTaskInfo(Task->type, TaskIndex); - if(ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount > Task->Activity[ActivityID].GoalCount) - ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount = Task->Activity[ActivityID].GoalCount; + if (info == nullptr) + return; + + info->Activity[ActivityID].DoneCount += Count; + + if(info->Activity[ActivityID].DoneCount > Task->Activity[ActivityID].GoalCount) + info->Activity[ActivityID].DoneCount = Task->Activity[ActivityID].GoalCount; if (!ignore_quest_update){ char buf[24]; - snprintf(buf, 23, "%d %d %d", ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].TaskID); + snprintf(buf, 23, "%d %d %d", info->Activity[ActivityID].DoneCount, info->Activity[ActivityID].ActivityID, info->TaskID); buf[23] = '\0'; parse->EventPlayer(EVENT_TASK_UPDATE, c, buf, 0); } - ActiveTasks[TaskIndex].Activity[ActivityID].Updated=true; + info->Activity[ActivityID].Updated=true; // Have we reached the goal count for this activity ? - if(ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount >= Task->Activity[ActivityID].GoalCount) { + if(info->Activity[ActivityID].DoneCount >= Task->Activity[ActivityID].GoalCount) { Log(Logs::General, Logs::Tasks, "[UPDATE] Done (%i) = Goal (%i) for Activity %i", - ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, + info->Activity[ActivityID].DoneCount, Task->Activity[ActivityID].GoalCount, ActivityID); // Flag the activity as complete - ActiveTasks[TaskIndex].Activity[ActivityID].State = ActivityCompleted; + info->Activity[ActivityID].State = ActivityCompleted; // Unlock subsequent activities for this task - bool TaskComplete = UnlockActivities(c->CharacterID(), TaskIndex); + bool TaskComplete = UnlockActivities(c->CharacterID(), *info); Log(Logs::General, Logs::Tasks, "[UPDATE] TaskCompleted is %i", TaskComplete); // and by the 'Task Stage Completed' message - c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, ActivityID, TaskIndex); + c->SendTaskActivityComplete(info->TaskID, ActivityID, TaskIndex, Task->type); // Send the updated task/activity list to the client - taskmanager->SendSingleActiveTaskToClient(c, TaskIndex, TaskComplete, false); + taskmanager->SendSingleActiveTaskToClient(c, *info, TaskComplete, false); // Inform the client the task has been updated, both by a chat message - c->Message(0, "Your task '%s' has been updated.", Task->Title); + c->Message(0, "Your task '%s' has been updated.", Task->Title.c_str()); if(Task->Activity[ActivityID].GoalMethod != METHODQUEST) { if (!ignore_quest_update){ char buf[24]; - snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID); + snprintf(buf, 23, "%d %d", info->TaskID, info->Activity[ActivityID].ActivityID); buf[23] = '\0'; parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0); } /* QS: PlayerLogTaskUpdates :: Update */ if (RuleB(QueryServ, PlayerLogTaskUpdates)){ - std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); + std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", info->TaskID, info->Activity[ActivityID].ActivityID, info->Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc); } } @@ -1871,21 +1955,21 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T // client. This is the same sequence the packets are sent on live. if(TaskComplete) { char buf[24]; - snprintf(buf, 23, "%d %d %d", ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].TaskID); + snprintf(buf, 23, "%d %d %d", info->Activity[ActivityID].DoneCount, info->Activity[ActivityID].ActivityID, info->TaskID); buf[23] = '\0'; parse->EventPlayer(EVENT_TASK_COMPLETE, c, buf, 0); /* QS: PlayerLogTaskUpdates :: Complete */ if (RuleB(QueryServ, PlayerLogTaskUpdates)){ - std::string event_desc = StringFormat("Task Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); + std::string event_desc = StringFormat("Task Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", info->TaskID, info->Activity[ActivityID].ActivityID, info->Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc); } taskmanager->SendCompletedTasksToClient(c, this); - c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, 0, TaskIndex, false); + c->SendTaskActivityComplete(info->TaskID, 0, TaskIndex, Task->type, 0); taskmanager->SaveClientState(c, this); //c->SendTaskComplete(TaskIndex); - c->CancelTask(TaskIndex); + c->CancelTask(TaskIndex, Task->type); //if(Task->RewardMethod != METHODQUEST) RewardTask(c, Task); // If Experience and/or cash rewards are set, reward them from the task even if RewardMethod is METHODQUEST RewardTask(c, Task); @@ -1893,11 +1977,11 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T } - } - else + } else { // Send an update packet for this single activity - taskmanager->SendTaskActivityLong(c, ActiveTasks[TaskIndex].TaskID, ActivityID, - TaskIndex, Task->Activity[ActivityID].Optional); + taskmanager->SendTaskActivityLong(c, info->TaskID, ActivityID, TaskIndex, + Task->Activity[ActivityID].Optional); + } } void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { @@ -1936,6 +2020,14 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { break; } } + + if (!Task->completion_emote.empty()) + c->SendColoredText(CC_Yellow, Task->completion_emote); // unsure if they use this packet or color, should work + + // just use normal NPC faction ID stuff + if (Task->faction_reward) + c->SetFactionLevel(c->CharacterID(), Task->faction_reward, c->GetBaseClass(), c->GetBaseRace(), c->GetDeity()); + if(Task->CashReward) { int Plat, Gold, Silver, Copper; @@ -2006,189 +2098,280 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { c->SendSound(); } -bool ClientTaskState::IsTaskActive(int TaskID) { +bool ClientTaskState::IsTaskActive(int TaskID) +{ + if (ActiveTask.TaskID == TaskID) + return true; - if((ActiveTaskCount == 0) || (TaskID == 0)) return false; - - for(int i=0; iSendTaskFailed(ActiveTasks[i].TaskID, i); - // Remove the task from the client - c->CancelTask(i); - return; - } + if (ActiveTask.TaskID == TaskID) { + c->SendTaskFailed(TaskID, 0, TaskType::Task); + // Remove the task from the client + c->CancelTask(0, TaskType::Task); + return; } + // TODO: shared tasks + + if (ActiveTaskCount == 0) + return; + + for (int i = 0; i < MAXACTIVEQUESTS; i++) { + if (ActiveQuests[i].TaskID == TaskID) { + c->SendTaskFailed(ActiveQuests[i].TaskID, i, TaskType::Quest); + // Remove the task from the client + c->CancelTask(i, TaskType::Quest); + return; + } + } } -bool ClientTaskState::IsTaskActivityActive(int TaskID, int ActivityID) { +// TODO: Shared tasks +bool ClientTaskState::IsTaskActivityActive(int TaskID, int ActivityID) +{ Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState IsTaskActivityActive(%i, %i).", TaskID, ActivityID); // Quick sanity check - if(ActivityID<0) return false; - if(ActiveTaskCount == 0) return false; + if (ActivityID < 0) + return false; + if (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY) + return false; int ActiveTaskIndex = -1; + auto type = TaskType::Task; - for(int i=0; iTasks[ActiveTasks[ActiveTaskIndex].TaskID]; + auto info = GetClientTaskInfo(type, ActiveTaskIndex); + + if (info == nullptr) + return false; + + TaskInformation *Task = taskmanager->Tasks[info->TaskID]; // The task is invalid - if(Task==nullptr) return false; + if (Task == nullptr) + return false; // The ActivityID is out of range - if(ActivityID >= Task->ActivityCount) return false; + if (ActivityID >= Task->ActivityCount) + return false; - Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState IsTaskActivityActive(%i, %i). State is %i ", TaskID, ActivityID, - ActiveTasks[ActiveTaskIndex].Activity[ActivityID].State); - - - return (ActiveTasks[ActiveTaskIndex].Activity[ActivityID].State == ActivityActive); + Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState IsTaskActivityActive(%i, %i). State is %i ", TaskID, + ActivityID, info->Activity[ActivityID].State); + return (info->Activity[ActivityID].State == ActivityActive); } void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count, bool ignore_quest_update /*= false*/) { - Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState UpdateTaskActivity(%i, %i, %i).", TaskID, ActivityID, Count); + Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState UpdateTaskActivity(%i, %i, %i).", TaskID, ActivityID, + Count); // Quick sanity check - if((ActivityID<0) || (ActiveTaskCount==0)) return; + if (ActivityID < 0 || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) + return; int ActiveTaskIndex = -1; + auto type = TaskType::Task; - for (int i = 0; i < MAXACTIVETASKS; i++) { - if (ActiveTasks[i].TaskID == TaskID) { - ActiveTaskIndex = i; - break; + if (ActiveTask.TaskID == TaskID) + ActiveTaskIndex = 0; + + if (ActiveTaskIndex == -1) { + for (int i = 0; i < MAXACTIVEQUESTS; i++) { + if (ActiveQuests[i].TaskID == TaskID) { + ActiveTaskIndex = i; + type = TaskType::Quest; + break; + } } } // The client does not have this task - if(ActiveTaskIndex == -1) return; + if (ActiveTaskIndex == -1) + return; - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[ActiveTaskIndex].TaskID]; + auto info = GetClientTaskInfo(type, ActiveTaskIndex); + + if (info == nullptr) + return; + + TaskInformation *Task = taskmanager->Tasks[info->TaskID]; // The task is invalid - if(Task==nullptr) return; + if (Task == nullptr) + return; // The ActivityID is out of range - if(ActivityID >= Task->ActivityCount) return; + if (ActivityID >= Task->ActivityCount) + return; // The Activity is not currently active - if(ActiveTasks[ActiveTaskIndex].Activity[ActivityID].State != ActivityActive) return; + if (info->Activity[ActivityID].State != ActivityActive) + return; Log(Logs::General, Logs::Tasks, "[UPDATE] Increment done count on UpdateTaskActivity"); IncrementDoneCount(c, Task, ActiveTaskIndex, ActivityID, Count, ignore_quest_update); - } -void ClientTaskState::ResetTaskActivity(Client *c, int TaskID, int ActivityID) { - +void ClientTaskState::ResetTaskActivity(Client *c, int TaskID, int ActivityID) +{ Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState UpdateTaskActivity(%i, %i, 0).", TaskID, ActivityID); // Quick sanity check - if((ActivityID<0) || (ActiveTaskCount==0)) return; + if (ActivityID < 0 || (ActiveTaskCount == 0 && ActiveTask.TaskID == TASKSLOTEMPTY)) + return; int ActiveTaskIndex = -1; + auto type = TaskType::Task; - for(int i=0; iTasks[ActiveTasks[ActiveTaskIndex].TaskID]; + auto info = GetClientTaskInfo(type, ActiveTaskIndex); + + if (info == nullptr) + return; + + TaskInformation *Task = taskmanager->Tasks[info->TaskID]; // The task is invalid - if(Task==nullptr) return; + if (Task == nullptr) + return; // The ActivityID is out of range - if(ActivityID >= Task->ActivityCount) return; + if (ActivityID >= Task->ActivityCount) + return; // The Activity is not currently active - if(ActiveTasks[ActiveTaskIndex].Activity[ActivityID].State != ActivityActive) return; + if (info->Activity[ActivityID].State != ActivityActive) + return; Log(Logs::General, Logs::Tasks, "[UPDATE] ResetTaskActivityCount"); - ActiveTasks[ActiveTaskIndex].Activity[ActivityID].DoneCount = 0; + info->Activity[ActivityID].DoneCount = 0; - ActiveTasks[ActiveTaskIndex].Activity[ActivityID].Updated=true; + info->Activity[ActivityID].Updated = true; // Send an update packet for this single activity - taskmanager->SendTaskActivityLong(c, ActiveTasks[ActiveTaskIndex].TaskID, ActivityID, - ActiveTaskIndex, Task->Activity[ActivityID].Optional); + taskmanager->SendTaskActivityLong(c, info->TaskID, ActivityID, ActiveTaskIndex, + Task->Activity[ActivityID].Optional); } -void ClientTaskState::ShowClientTasks(Client *c) { - +void ClientTaskState::ShowClientTasks(Client *c) +{ c->Message(0, "Task Information:"); - //for(int i=0; iMessage(0, "Task: %i %s", ActiveTasks[i].TaskID, taskmanager->Tasks[ActiveTasks[i].TaskID]->Title); - c->Message(0, " Description: [%s]\n", taskmanager->Tasks[ActiveTasks[i].TaskID]->Description); - for(int j=0; jGetActivityCount(ActiveTasks[i].TaskID); j++) { + if (ActiveTask.TaskID != TASKSLOTEMPTY) { + c->Message(0, "Task: %i %s", ActiveTask.TaskID, taskmanager->Tasks[ActiveTask.TaskID]->Title.c_str()); + c->Message(0, " Description: [%s]\n", taskmanager->Tasks[ActiveTask.TaskID]->Description.c_str()); + for (int j = 0; j < taskmanager->GetActivityCount(ActiveTask.TaskID); j++) { c->Message(0, " Activity: %2d, DoneCount: %2d, Status: %d (0=Hidden, 1=Active, 2=Complete)", - ActiveTasks[i].Activity[j].ActivityID, - ActiveTasks[i].Activity[j].DoneCount, - ActiveTasks[i].Activity[j].State); + ActiveTask.Activity[j].ActivityID, ActiveTask.Activity[j].DoneCount, + ActiveTask.Activity[j].State); } } + for (int i = 0; i < MAXACTIVEQUESTS; i++) { + if (ActiveQuests[i].TaskID == TASKSLOTEMPTY) + continue; + + c->Message(0, "Quest: %i %s", ActiveQuests[i].TaskID, + taskmanager->Tasks[ActiveQuests[i].TaskID]->Title.c_str()); + c->Message(0, " Description: [%s]\n", taskmanager->Tasks[ActiveQuests[i].TaskID]->Description.c_str()); + for (int j = 0; j < taskmanager->GetActivityCount(ActiveQuests[i].TaskID); j++) { + c->Message(0, " Activity: %2d, DoneCount: %2d, Status: %d (0=Hidden, 1=Active, 2=Complete)", + ActiveQuests[i].Activity[j].ActivityID, ActiveQuests[i].Activity[j].DoneCount, + ActiveQuests[i].Activity[j].State); + } + } } -int ClientTaskState::TaskTimeLeft(int TaskID) { +// TODO: Shared Task +int ClientTaskState::TaskTimeLeft(int TaskID) +{ + if (ActiveTask.TaskID == TaskID) { + int Now = time(nullptr); - if(ActiveTaskCount == 0) return -1; + TaskInformation *Task = taskmanager->Tasks[TaskID]; - for(int i=0; iDuration) + return -1; + + int TimeLeft = (ActiveTask.AcceptedTime + Task->Duration - Now); + + return (TimeLeft > 0 ? TimeLeft : 0); + } + + if (ActiveTaskCount == 0) + return -1; + + for (int i = 0; i < MAXACTIVEQUESTS; i++) { + + if (ActiveQuests[i].TaskID != TaskID) + continue; int Now = time(nullptr); - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[i].TaskID]; + TaskInformation *Task = taskmanager->Tasks[ActiveQuests[i].TaskID]; - if(Task == nullptr) return -1; + if (Task == nullptr) + return -1; - if(!Task->Duration) return -1; + if (!Task->Duration) + return -1; - int TimeLeft = (ActiveTasks[i].AcceptedTime + Task->Duration - Now); + int TimeLeft = (ActiveQuests[i].AcceptedTime + Task->Duration - Now); // If Timeleft is negative, return 0, else return the number of seconds left - return (TimeLeft>0 ? TimeLeft : 0); + return (TimeLeft > 0 ? TimeLeft : 0); } return -1; @@ -2221,44 +2404,63 @@ bool TaskManager::IsTaskRepeatable(int TaskID) { return Task->Repeatable; } -bool ClientTaskState::TaskOutOfTime(int Index) { - +bool ClientTaskState::TaskOutOfTime(TaskType type, int Index) +{ // Returns true if the Task in the specified slot has a time limit that has been exceeded. + auto info = GetClientTaskInfo(type, Index); - if((Index < 0) || (Index>=MAXACTIVETASKS)) return false; + if (info == nullptr) + return false; - if((ActiveTasks[Index].TaskID <= 0) || (ActiveTasks[Index].TaskID >= MAXTASKS)) return false; + // make sure the TaskID is at least maybe in our array + if (info->TaskID <= 0 || info->TaskID >= MAXTASKS) + return false; int Now = time(nullptr); - TaskInformation* Task = taskmanager->Tasks[ActiveTasks[Index].TaskID]; + TaskInformation *Task = taskmanager->Tasks[info->TaskID]; - if(Task == nullptr) return false; - - return (Task->Duration && (ActiveTasks[Index].AcceptedTime + Task->Duration <= Now)); + if (Task == nullptr) + return false; + return (Task->Duration && (info->AcceptedTime + Task->Duration <= Now)); } -void ClientTaskState::TaskPeriodicChecks(Client *c) { +void ClientTaskState::TaskPeriodicChecks(Client *c) +{ + if (ActiveTask.TaskID != TASKSLOTEMPTY) { + if (TaskOutOfTime(TaskType::Task, 0)) { + // Send Red Task Failed Message + c->SendTaskFailed(ActiveTask.TaskID, 0, TaskType::Task); + // Remove the task from the client + c->CancelTask(0, TaskType::Task); + // It is a conscious decision to only fail one task per call to this method, + // otherwise the player will not see all the failed messages where multiple + // tasks fail at the same time. + return; + } + } - if(ActiveTaskCount == 0) return; + // TODO: shared tasks -- although that will probably be manager in world checking and telling zones to fail us + + if (ActiveTaskCount == 0) + return; // Check for tasks that have failed because they have not been completed in the specified time // - for(int i=0; iSendTaskFailed(ActiveTasks[i].TaskID, i); + c->SendTaskFailed(ActiveQuests[i].TaskID, i, TaskType::Quest); // Remove the task from the client - c->CancelTask(i); + c->CancelTask(i, TaskType::Quest); // It is a conscious decision to only fail one task per call to this method, // otherwise the player will not see all the failed messages where multiple // tasks fail at the same time. break; - } } @@ -2266,13 +2468,12 @@ void ClientTaskState::TaskPeriodicChecks(Client *c) { // This is done in this method because it gives an extra few seconds for the client screen to display // the zone before we send the 'Task Activity Completed' message. // - if(!CheckedTouchActivities) { + if (!CheckedTouchActivities) { UpdateTasksOnTouch(c, zone->GetZoneID()); CheckedTouchActivities = true; } } - #if 0 void Client::SendTaskComplete(int TaskIndex) { @@ -2338,10 +2539,10 @@ void ClientTaskState::SendTaskHistory(Client *c, int TaskIndex) { if(CompletedTasks[AdjustedTaskIndex].ActivityDone[i]) { CompletedActivityCount++; PacketLength = PacketLength + sizeof(TaskHistoryReplyData1_Struct) + - strlen(Task->Activity[i].Text1) + 1 + - strlen(Task->Activity[i].Text2) + 1 + + Task->Activity[i].target_name.size() + 1 + + Task->Activity[i].item_list.size() + 1 + sizeof(TaskHistoryReplyData2_Struct) + - strlen(Task->Activity[i].Text3) + 1; + Task->Activity[i].desc_override.size() + 1; } } @@ -2361,8 +2562,8 @@ void ClientTaskState::SendTaskHistory(Client *c, int TaskIndex) { thd1 = (TaskHistoryReplyData1_Struct*)Ptr; thd1->ActivityType = Task->Activity[i].Type; Ptr = (char *)thd1 + sizeof(TaskHistoryReplyData1_Struct); - VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].Text1); - VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].Text2); + VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].target_name.c_str()); + VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].item_list.c_str()); thd2 = (TaskHistoryReplyData2_Struct*)Ptr; thd2->GoalCount = Task->Activity[i].GoalCount; thd2->unknown04 = 0xffffffff; @@ -2370,7 +2571,7 @@ void ClientTaskState::SendTaskHistory(Client *c, int TaskIndex) { thd2->ZoneID = Task->Activity[i].ZoneID; thd2->unknown16 = 0x00000000; Ptr = (char *)thd2 + sizeof(TaskHistoryReplyData2_Struct); - VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].Text3); + VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].desc_override.c_str()); } } @@ -2382,8 +2583,8 @@ void ClientTaskState::SendTaskHistory(Client *c, int TaskIndex) { } -void Client::SendTaskActivityComplete(int TaskID, int ActivityID, int TaskIndex, int TaskIncomplete) { - +void Client::SendTaskActivityComplete(int TaskID, int ActivityID, int TaskIndex, TaskType type, int TaskIncomplete) +{ // 0x54eb TaskActivityComplete_Struct* tac; @@ -2392,15 +2593,12 @@ void Client::SendTaskActivityComplete(int TaskID, int ActivityID, int TaskIndex, tac = (TaskActivityComplete_Struct*)outapp->pBuffer; - //tac->unknown1 = 0x00000000; tac->TaskIndex = TaskIndex; - tac->unknown2 = 0x00000002; - //tac->unknown3 = 0x00000000; - tac->unknown3 = TaskID; // Correct ? + tac->TaskType = static_cast(type); + tac->TaskID = TaskID; tac->ActivityID = ActivityID; - tac->unknown4 = 0x00000001; - //tac->unknown5 = 0x00000001; - tac->unknown5 = TaskIncomplete; + tac->task_completed = 0x00000001; + tac->stage_complete = TaskIncomplete; QueuePacket(outapp); @@ -2408,8 +2606,8 @@ void Client::SendTaskActivityComplete(int TaskID, int ActivityID, int TaskIndex, } -void Client::SendTaskFailed(int TaskID, int TaskIndex) { - +void Client::SendTaskFailed(int TaskID, int TaskIndex, TaskType type) +{ // 0x54eb char buf[24]; snprintf(buf, 23, "%d", TaskID); @@ -2422,15 +2620,12 @@ void Client::SendTaskFailed(int TaskID, int TaskIndex) { tac = (TaskActivityComplete_Struct*)outapp->pBuffer; - //tac->unknown1 = 0x00000000; tac->TaskIndex = TaskIndex; - tac->unknown2 = 0x00000002; - //tac->unknown3 = 0x00000000; - tac->unknown3 = TaskID; // Correct ? + tac->TaskType = static_cast(type); + tac->TaskID = TaskID; tac->ActivityID = 0; - tac->unknown4 = 0x00000000; //Fail - //tac->unknown5 = 0x00000001; - tac->unknown5 = 0; // 0 for task complete or failed. + tac->task_completed = 0; //Fail + tac->stage_complete = 0; // 0 for task complete or failed. Log(Logs::General, Logs::Tasks, "[UPDATE] TaskFailed"); @@ -2465,7 +2660,7 @@ void TaskManager::SendCompletedTasksToClient(Client *c, ClientTaskState *State) for(int i = FirstTaskToSend; iCompletedTasks[i].TaskID; if(Tasks[TaskID] == nullptr) continue; - PacketLength = PacketLength + 8 + strlen(Tasks[TaskID]->Title) + 1; + PacketLength = PacketLength + 8 + Tasks[TaskID]->Title.size() + 1; } auto outapp = new EQApplicationPacket(OP_CompletedTasks, PacketLength); @@ -2482,7 +2677,7 @@ void TaskManager::SendCompletedTasksToClient(Client *c, ClientTaskState *State) *(uint32 *)buf = TaskID; buf = buf + 4; - sprintf(buf, "%s", Tasks[TaskID]->Title); + sprintf(buf, "%s", Tasks[TaskID]->Title.c_str()); buf = buf + strlen(buf) + 1; //*(uint32 *)buf = (*iterator).CompletedTime; *(uint32 *)buf = State->CompletedTasks[i].CompletedTime; @@ -2507,7 +2702,7 @@ void TaskManager::SendTaskActivityShort(Client *c, int TaskID, int ActivityID, i { auto outapp = new EQApplicationPacket(OP_TaskActivity, 25); outapp->WriteUInt32(ClientTaskIndex); - outapp->WriteUInt32(2); + outapp->WriteUInt32(static_cast(Tasks[TaskID]->type)); outapp->WriteUInt32(TaskID); outapp->WriteUInt32(ActivityID); outapp->WriteUInt32(0); @@ -2523,7 +2718,7 @@ void TaskManager::SendTaskActivityShort(Client *c, int TaskID, int ActivityID, i tass = (TaskActivityShort_Struct*)outapp->pBuffer; tass->TaskSequenceNumber = ClientTaskIndex; - tass->unknown2 = 0x00000002; + tass->unknown2 = static_cast(Tasks[TaskID]->type); tass->TaskID = TaskID; tass->ActivityID = ActivityID; tass->unknown3 = 0x000000; @@ -2545,78 +2740,52 @@ void TaskManager::SendTaskActivityLong(Client *c, int TaskID, int ActivityID, in return; } - char *Ptr; + SerializeBuffer buf(100); - TaskActivityHeader_Struct* tah; - TaskActivityData1_Struct* tad1; - TaskActivityTrailer_Struct* tat; + buf.WriteUInt32(ClientTaskIndex); + buf.WriteUInt32(static_cast(Tasks[TaskID]->type)); + buf.WriteUInt32(TaskID); + buf.WriteUInt32(ActivityID); + buf.WriteUInt32(0); // unknown3 - long PacketLength = sizeof(TaskActivityHeader_Struct) + +sizeof(TaskActivityData1_Struct) + sizeof(TaskActivityTrailer_Struct); - PacketLength = PacketLength + strlen(Tasks[TaskID]->Activity[ActivityID].Text1) + 1 + - strlen(Tasks[TaskID]->Activity[ActivityID].Text2) + 1 + - strlen(Tasks[TaskID]->Activity[ActivityID].Text3) + 1; - - auto outapp = new EQApplicationPacket(OP_TaskActivity, PacketLength); - - tah = (TaskActivityHeader_Struct*)outapp->pBuffer; - - tah->TaskSequenceNumber = ClientTaskIndex; - tah->unknown2 = 0x00000002; - tah->TaskID = TaskID; - tah->ActivityID = ActivityID; - tah->unknown3 = 0x00000000; - - // We send our 'internal' types as ActivityUse1. text3 should be set to the activity description, so it makes + // We send our 'internal' types as ActivityCastOn. text3 should be set to the activity description, so it makes // no difference to the client. All activity updates will be done based on our interal activity types. if((Tasks[TaskID]->Activity[ActivityID].Type > 0) && Tasks[TaskID]->Activity[ActivityID].Type < 100) - tah->ActivityType = Tasks[TaskID]->Activity[ActivityID].Type; + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].Type); else - tah->ActivityType = ActivityUse1; + buf.WriteUInt32(ActivityCastOn); // w/e! - tah->Optional = Optional; - tah->unknown5 = 0x00000000; - // One of these unknown fields maybe related to the 'Use On' activity types - Ptr = (char *) tah + sizeof(TaskActivityHeader_Struct); - sprintf(Ptr, "%s", Tasks[TaskID]->Activity[ActivityID].Text1); - Ptr = Ptr + strlen(Ptr) + 1; + buf.WriteUInt32(Optional); + buf.WriteUInt32(0); // solo, group, raid - sprintf(Ptr, "%s", Tasks[TaskID]->Activity[ActivityID].Text2); - Ptr = Ptr + strlen(Ptr) + 1; - - tad1 = (TaskActivityData1_Struct*)Ptr; - tat = (TaskActivityTrailer_Struct*)Ptr; + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].target_name); // target name string + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].item_list); // item name list if(Tasks[TaskID]->Activity[ActivityID].Type != ActivityGiveCash) - tad1->GoalCount = Tasks[TaskID]->Activity[ActivityID].GoalCount; + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].GoalCount); else // For our internal type GiveCash, where the goal count has the amount of cash that must be given, // we don't want the donecount and goalcount fields cluttered up with potentially large numbers, so we just // send a goalcount of 1, and a bit further down, a donecount of 1 if the activity is complete, 0 otherwise. // The text3 field should decribe the exact activity goal, e.g. give 3500gp to Hasten Bootstrutter. - tad1->GoalCount = 1; + buf.WriteUInt32(1); - tad1->unknown1 = 0xffffffff; - if(!TaskComplete) tad1->unknown2 = 0xffffffff; - else - tad1->unknown2 = 0xcaffffff; + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].skill_id); + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].spell_id); + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].ZoneID); + buf.WriteUInt32(0); - tad1->ZoneID = Tasks[TaskID]->Activity[ActivityID].ZoneID; - tad1->unknown3 = 0x00000000; - - Ptr = (char *) tad1 + sizeof(TaskActivityData1_Struct); - sprintf(Ptr, "%s", Tasks[TaskID]->Activity[ActivityID].Text3); - Ptr = Ptr + strlen(Ptr) + 1; - - tat = (TaskActivityTrailer_Struct*)Ptr; + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].desc_override); if(Tasks[TaskID]->Activity[ActivityID].Type != ActivityGiveCash) - tat->DoneCount = c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID); + buf.WriteUInt32(c->GetTaskActivityDoneCount(Tasks[TaskID]->type, ClientTaskIndex, ActivityID)); else // For internal activity types, DoneCount is either 1 if the activity is complete, 0 otherwise. - tat->DoneCount = (c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID) >= Tasks[TaskID]->Activity[ActivityID].GoalCount); + buf.WriteUInt32((c->GetTaskActivityDoneCount(Tasks[TaskID]->type, ClientTaskIndex, ActivityID) >= Tasks[TaskID]->Activity[ActivityID].GoalCount)); - tat->unknown1 = 0x00000001; + buf.WriteUInt32(1); // unknown + auto outapp = new EQApplicationPacket(OP_TaskActivity, buf); c->QueuePacket(outapp); safe_delete(outapp); @@ -2624,173 +2793,152 @@ void TaskManager::SendTaskActivityLong(Client *c, int TaskID, int ActivityID, in } // Used only by RoF+ Clients -void TaskManager::SendTaskActivityNew(Client *c, int TaskID, int ActivityID, int ClientTaskIndex, bool Optional, bool TaskComplete) { +void TaskManager::SendTaskActivityNew(Client *c, int TaskID, int ActivityID, int ClientTaskIndex, bool Optional, bool TaskComplete) +{ + SerializeBuffer buf(100); - uint32 String2Len = 3; - if(TaskComplete) - String2Len = 4; + buf.WriteUInt32(ClientTaskIndex); // TaskSequenceNumber + buf.WriteUInt32(static_cast(Tasks[TaskID]->type)); // task type + buf.WriteUInt32(TaskID); + buf.WriteUInt32(ActivityID); + buf.WriteUInt32(0); // unknown3 - long PacketLength = 29 + 4 + 8 + 4 + 4 + 5; - PacketLength = PacketLength + strlen(Tasks[TaskID]->Activity[ActivityID].Text1) + 1 + - strlen(Tasks[TaskID]->Activity[ActivityID].Text2) + 1 + - strlen(Tasks[TaskID]->Activity[ActivityID].Text3) + 1 + - ((strlen(itoa(Tasks[TaskID]->Activity[ActivityID].ZoneID)) + 1) * 2) + - 3 + String2Len; - - auto outapp = new EQApplicationPacket(OP_TaskActivity, PacketLength); - - outapp->WriteUInt32(ClientTaskIndex); // TaskSequenceNumber - outapp->WriteUInt32(2); // unknown2 - outapp->WriteUInt32(TaskID); - outapp->WriteUInt32(ActivityID); - outapp->WriteUInt32(0); // unknown3 - - // We send our 'internal' types as ActivityUse1. text3 should be set to the activity description, so it makes + // We send our 'internal' types as ActivityCastOn. text3 should be set to the activity description, so it makes // no difference to the client. All activity updates will be done based on our interal activity types. if((Tasks[TaskID]->Activity[ActivityID].Type > 0) && Tasks[TaskID]->Activity[ActivityID].Type < 100) - outapp->WriteUInt32(Tasks[TaskID]->Activity[ActivityID].Type); + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].Type); else - outapp->WriteUInt32(ActivityUse1); + buf.WriteUInt32(ActivityCastOn); // w/e! - outapp->WriteUInt32(Optional); - outapp->WriteUInt8(0); // unknown5 + buf.WriteUInt8(Optional); + buf.WriteUInt32(0); // solo, group, raid // One of these unknown fields maybe related to the 'Use On' activity types - outapp->WriteString(Tasks[TaskID]->Activity[ActivityID].Text1); + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].target_name); // target name string - outapp->WriteUInt32((strlen(Tasks[TaskID]->Activity[ActivityID].Text2) + 1)); // String Length - Add in null terminator - outapp->WriteString(Tasks[TaskID]->Activity[ActivityID].Text2); + buf.WriteLengthString(Tasks[TaskID]->Activity[ActivityID].item_list); // item name list // Goal Count if(Tasks[TaskID]->Activity[ActivityID].Type != ActivityGiveCash) - outapp->WriteUInt32(Tasks[TaskID]->Activity[ActivityID].GoalCount); + buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].GoalCount); else - outapp->WriteUInt32(1); // GoalCount + buf.WriteUInt32(1); // GoalCount - outapp->WriteUInt32(3); // String Length - Add in null terminator - outapp->WriteString("-1"); + // skill ID list ; separated + buf.WriteLengthString(Tasks[TaskID]->Activity[ActivityID].skill_list); - if(!TaskComplete) { - outapp->WriteUInt32(3); // String Length - Add in null terminator - outapp->WriteString("-1"); - } - else - { - outapp->WriteUInt32(4); // String Length - Add in null terminator - outapp->WriteString("-54"); - } + // spelll ID list ; separated -- unsure wtf we're doing here + buf.WriteLengthString(Tasks[TaskID]->Activity[ActivityID].spell_list); - outapp->WriteString(itoa(Tasks[TaskID]->Activity[ActivityID].ZoneID)); - outapp->WriteUInt32(0); // unknown7 + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].zones); + buf.WriteUInt32(0); // unknown7 - outapp->WriteString(Tasks[TaskID]->Activity[ActivityID].Text3); + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].desc_override); // description override if(Tasks[TaskID]->Activity[ActivityID].Type != ActivityGiveCash) - outapp->WriteUInt32(c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID)); // DoneCount + buf.WriteUInt32(c->GetTaskActivityDoneCount(Tasks[TaskID]->type, ClientTaskIndex, ActivityID)); // DoneCount else // For internal activity types, DoneCount is either 1 if the activity is complete, 0 otherwise. - outapp->WriteUInt32((c->GetTaskActivityDoneCount(ClientTaskIndex, ActivityID) >= Tasks[TaskID]->Activity[ActivityID].GoalCount)); + buf.WriteUInt32((c->GetTaskActivityDoneCount(Tasks[TaskID]->type, ClientTaskIndex, ActivityID) >= Tasks[TaskID]->Activity[ActivityID].GoalCount)); - outapp->WriteUInt8(1); // unknown9 + buf.WriteUInt8(1); // unknown9 - outapp->WriteString(itoa(Tasks[TaskID]->Activity[ActivityID].ZoneID)); + buf.WriteString(Tasks[TaskID]->Activity[ActivityID].zones); + auto outapp = new EQApplicationPacket(OP_TaskActivity, buf); c->QueuePacket(outapp); safe_delete(outapp); } -void TaskManager::SendActiveTasksToClient(Client *c, bool TaskComplete) { +void TaskManager::SendActiveTasksToClient(Client *c, bool TaskComplete) +{ + auto state = c->GetTaskState(); + if (!state) + return; - //for(int TaskIndex=0; TaskIndexGetActiveTaskCount(); TaskIndex++) { - for(int TaskIndex=0; TaskIndexGetActiveTaskID(TaskIndex); - if((TaskID==0) || (Tasks[TaskID] ==0)) continue; - int StartTime = c->GetTaskStartTime(TaskIndex); + for (int TaskIndex = 0; TaskIndex < MAXACTIVEQUESTS + 1; TaskIndex++) { + int TaskID = state->ActiveTasks[TaskIndex].TaskID; + if ((TaskID == 0) || (Tasks[TaskID] == 0)) + continue; + int StartTime = state->ActiveTasks[TaskIndex].AcceptedTime; - SendActiveTaskDescription(c, TaskID, TaskIndex, StartTime, Tasks[TaskID]->Duration, false); - Log(Logs::General, Logs::Tasks, "[UPDATE] SendActiveTasksToClient: Task %i, Activities: %i", TaskID, GetActivityCount(TaskID)); + SendActiveTaskDescription(c, TaskID, state->ActiveTasks[TaskIndex], StartTime, Tasks[TaskID]->Duration, + false); + Log(Logs::General, Logs::Tasks, "[UPDATE] SendActiveTasksToClient: Task %i, Activities: %i", TaskID, + GetActivityCount(TaskID)); int Sequence = 0; - for(int Activity=0; ActivityGetTaskActivityState(TaskIndex, Activity) != ActivityHidden) { - Log(Logs::General, Logs::Tasks, "[UPDATE] Long: %i, %i, %i Complete=%i", TaskID, Activity, TaskIndex, TaskComplete); - if(Activity==GetActivityCount(TaskID)-1) - SendTaskActivityLong(c, TaskID, Activity, TaskIndex, - Tasks[TaskID]->Activity[Activity].Optional, - TaskComplete); + int fixed_index = Tasks[TaskID]->type == TaskType::Task ? 0 : TaskIndex - 1; // hmmm fuck + for (int Activity = 0; Activity < GetActivityCount(TaskID); Activity++) { + if (c->GetTaskActivityState(Tasks[TaskID]->type, fixed_index, Activity) != ActivityHidden) { + Log(Logs::General, Logs::Tasks, "[UPDATE] Long: %i, %i, %i Complete=%i", TaskID, + Activity, fixed_index, TaskComplete); + if (Activity == GetActivityCount(TaskID) - 1) + SendTaskActivityLong(c, TaskID, Activity, fixed_index, + Tasks[TaskID]->Activity[Activity].Optional, TaskComplete); else - SendTaskActivityLong(c, TaskID, Activity, TaskIndex, - Tasks[TaskID]->Activity[Activity].Optional, 0); - } - else { - Log(Logs::General, Logs::Tasks, "[UPDATE] Short: %i, %i, %i", TaskID, Activity, TaskIndex); - SendTaskActivityShort(c, TaskID, Activity, TaskIndex); + SendTaskActivityLong(c, TaskID, Activity, fixed_index, + Tasks[TaskID]->Activity[Activity].Optional, 0); + } else { + Log(Logs::General, Logs::Tasks, "[UPDATE] Short: %i, %i, %i", TaskID, Activity, + fixed_index); + SendTaskActivityShort(c, TaskID, Activity, fixed_index); } Sequence++; } - - } } +void TaskManager::SendSingleActiveTaskToClient(Client *c, ClientTaskInformation &task_info, bool TaskComplete, + bool BringUpTaskJournal) +{ + int TaskID = task_info.TaskID; -void TaskManager::SendSingleActiveTaskToClient(Client *c, int TaskIndex, bool TaskComplete, bool BringUpTaskJournal) { + if (TaskID == 0 || Tasks[TaskID] == nullptr) + return; - if((TaskIndex < 0) || (TaskIndex >= MAXACTIVETASKS)) return; - - int TaskID = c->GetActiveTaskID(TaskIndex); - - if((TaskID==0) || (Tasks[TaskID] ==0)) return; - - int StartTime = c->GetTaskStartTime(TaskIndex); - SendActiveTaskDescription(c, TaskID, TaskIndex, StartTime, Tasks[TaskID]->Duration, BringUpTaskJournal); + int StartTime = task_info.AcceptedTime; + SendActiveTaskDescription(c, TaskID, task_info, StartTime, Tasks[TaskID]->Duration, BringUpTaskJournal); Log(Logs::General, Logs::Tasks, "[UPDATE] SendSingleActiveTasksToClient: Task %i, Activities: %i", TaskID, GetActivityCount(TaskID)); - int Sequence = 0; - - for(int Activity=0; ActivityGetTaskActivityState(TaskIndex, Activity) != ActivityHidden) { - Log(Logs::General, Logs::Tasks, "[UPDATE] Long: %i, %i, %i Complete=%i", TaskID, Activity, TaskIndex, TaskComplete); - if(Activity==GetActivityCount(TaskID)-1) - SendTaskActivityLong(c, TaskID, Activity, TaskIndex, + for (int Activity = 0; Activity < GetActivityCount(TaskID); Activity++) { + if(task_info.Activity[Activity].State != ActivityHidden) { + Log(Logs::General, Logs::Tasks, "[UPDATE] Long: %i, %i Complete=%i", TaskID, Activity, TaskComplete); + if (Activity == GetActivityCount(TaskID) - 1) + SendTaskActivityLong(c, TaskID, Activity, task_info.slot, Tasks[TaskID]->Activity[Activity].Optional, TaskComplete); else - SendTaskActivityLong(c, TaskID, Activity, TaskIndex, + SendTaskActivityLong(c, TaskID, Activity, task_info.slot, Tasks[TaskID]->Activity[Activity].Optional, 0); + } else { + Log(Logs::General, Logs::Tasks, "[UPDATE] Short: %i, %i", TaskID, Activity); + SendTaskActivityShort(c, TaskID, Activity, task_info.slot); } - else { - Log(Logs::General, Logs::Tasks, "[UPDATE] Short: %i, %i, %i", TaskID, Activity, TaskIndex); - SendTaskActivityShort(c, TaskID, Activity, TaskIndex); - } - Sequence++; } } -void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal) +void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, ClientTaskInformation &task_info, int StartTime, int Duration, bool BringUpTaskJournal) { if ((TaskID < 1) || (TaskID >= MAXTASKS) || !Tasks[TaskID]) return; - int PacketLength = sizeof(TaskDescriptionHeader_Struct) + strlen(Tasks[TaskID]->Title) + 1 - + sizeof(TaskDescriptionData1_Struct) + strlen(Tasks[TaskID]->Description) + 1 + int PacketLength = sizeof(TaskDescriptionHeader_Struct) + Tasks[TaskID]->Title.length() + 1 + + sizeof(TaskDescriptionData1_Struct) + Tasks[TaskID]->Description.length() + 1 + sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct); - std::string reward_text; - int ItemID = 0; - // If there is an item make the Reward text into a link to the item (only the first item if a list // is specified). I have been unable to get multiple item links to work. // - if(Tasks[TaskID]->RewardID) { + if(Tasks[TaskID]->RewardID && Tasks[TaskID]->item_link.empty()) { + int ItemID = 0; // If the reward is a list of items, and the first entry on the list is valid - if(Tasks[TaskID]->RewardMethod==METHODSINGLEID) { + if (Tasks[TaskID]->RewardMethod == METHODSINGLEID) { ItemID = Tasks[TaskID]->RewardID; - } - else if(Tasks[TaskID]->RewardMethod==METHODLIST) { + } else if (Tasks[TaskID]->RewardMethod == METHODLIST) { ItemID = GoalListManager.GetFirstEntry(Tasks[TaskID]->RewardID); - if(ItemID < 0) + if (ItemID < 0) ItemID = 0; } @@ -2801,20 +2949,11 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN linker.SetLinkType(EQEmu::saylink::SayLinkItemData); linker.SetItemData(reward_item); linker.SetTaskUse(); - if (strlen(Tasks[TaskID]->Reward) != 0) - linker.SetProxyText(Tasks[TaskID]->Reward); - - reward_text.append(linker.GenerateLink()); - } - else { - reward_text.append(Tasks[TaskID]->Reward); + Tasks[TaskID]->item_link = linker.GenerateLink(); } + } - } - else { - reward_text.append(Tasks[TaskID]->Reward); - } - PacketLength += reward_text.length() + 1; + PacketLength += Tasks[TaskID]->Reward.length() + 1 + Tasks[TaskID]->item_link.length() + 1; char *Ptr; TaskDescriptionHeader_Struct* tdh; @@ -2826,83 +2965,122 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN tdh = (TaskDescriptionHeader_Struct*)outapp->pBuffer; - tdh->SequenceNumber = SequenceNumber; + tdh->SequenceNumber = task_info.slot; tdh->TaskID = TaskID; - - if(BringUpTaskJournal) - tdh->unknown2 = 0x00000201; - else - tdh->unknown2 = 0x00000200; - //tdh->unknown2 = 0x00000100; // This makes the Task Description have an S instead of Q, but the description doesn't show - - tdh->unknown3 = 0x00000000; - tdh->unknown4 = 0x00; + tdh->open_window = BringUpTaskJournal; + tdh->task_type = static_cast(Tasks[TaskID]->type); + tdh->reward_type = 0; // TODO: 4 says Radiant Crystals else Ebon Crystals when shared task Ptr = (char *) tdh + sizeof(TaskDescriptionHeader_Struct); - sprintf(Ptr, "%s", Tasks[TaskID]->Title); - Ptr = Ptr + strlen(Ptr) + 1; + sprintf(Ptr, "%s", Tasks[TaskID]->Title.c_str()); + Ptr += Tasks[TaskID]->Title.length() + 1; tdd1 = (TaskDescriptionData1_Struct*)Ptr; tdd1->Duration = Duration; - tdd1->unknown2 = 0x00000000; + tdd1->dur_code = static_cast(Tasks[TaskID]->dur_code); tdd1->StartTime = StartTime; Ptr = (char *) tdd1 + sizeof(TaskDescriptionData1_Struct); - sprintf(Ptr, "%s", Tasks[TaskID]->Description); - Ptr = Ptr + strlen(Ptr) + 1; + sprintf(Ptr, "%s", Tasks[TaskID]->Description.c_str()); + Ptr += Tasks[TaskID]->Description.length() + 1; tdd2 = (TaskDescriptionData2_Struct*)Ptr; - // This next field may not be a reward count. It is always 1 in the packets I have seen. Setting it to 2 and trying - // to include multiple item links has so far proven futile. Setting it to 0 ends the packet after the next byte. - tdd2->RewardCount = 1; + // we have this reward stuff! + // if we ever don't hardcode this, TaskDescriptionTrailer_Struct will need to be fixed since + // "has_reward_selection" is after this bool! Smaller packet when this is 0 + tdd2->has_rewards = 1; - if(Tasks[TaskID]->XPReward) - tdd2->unknown1 = 0x00000100; - else - tdd2->unknown1 = 0x00000000; + tdd2->coin_reward = Tasks[TaskID]->CashReward; + tdd2->xp_reward = Tasks[TaskID]->XPReward ? 1 : 0; // just booled + tdd2->faction_reward = Tasks[TaskID]->faction_reward ? 1 : 0; // faction booled - tdd2->unknown2 = 0x00000000; - tdd2->unknown3 = 0x0000; Ptr = (char *) tdd2 + sizeof(TaskDescriptionData2_Struct); - sprintf(Ptr, "%s", reward_text.c_str()); - Ptr = Ptr + strlen(Ptr) + 1; + // we actually have 2 strings here. One is max length 96 and not parsed for item links + // We actually skipped past that string incorrectly before, so TODO: fix item link string + sprintf(Ptr, "%s", Tasks[TaskID]->Reward.c_str()); + Ptr += Tasks[TaskID]->Reward.length() + 1; + + // second string is parsed for item links + sprintf(Ptr, "%s", Tasks[TaskID]->item_link.c_str()); + Ptr += Tasks[TaskID]->item_link.length() + 1; tdt = (TaskDescriptionTrailer_Struct*)Ptr; - tdt->Points = 0x00000000; // Points Count - + tdt->Points = 0x00000000; // Points Count TODO: this does have a visible affect on the client ... + tdt->has_reward_selection = 0; // TODO: new rewards window c->QueuePacket(outapp); safe_delete(outapp); +} + +bool ClientTaskState::IsTaskActivityCompleted(TaskType type, int index, int ActivityID) +{ + switch (type) { + case TaskType::Task: + if (index != 0) + return false; + return ActiveTask.Activity[ActivityID].State == ActivityCompleted; + case TaskType::Shared: + return false; // TODO: shared tasks + case TaskType::Quest: + if (index < MAXACTIVEQUESTS) + return ActiveQuests[index].Activity[ActivityID].State == ActivityCompleted; + default: + return false; + } } -bool ClientTaskState::IsTaskActivityCompleted(int index, int ActivityID) { - - return (ActiveTasks[index].Activity[ActivityID].State == ActivityCompleted); +// should we be defaulting to hidden? +ActivityState ClientTaskState::GetTaskActivityState(TaskType type, int index, int ActivityID) +{ + switch (type) { + case TaskType::Task: + if (index != 0) + return ActivityHidden; + return ActiveTask.Activity[ActivityID].State; + case TaskType::Shared: + return ActivityHidden; // TODO: shared tasks + case TaskType::Quest: + if (index < MAXACTIVEQUESTS) + return ActiveQuests[index].Activity[ActivityID].State; + default: + return ActivityHidden; + } } -ActivityState ClientTaskState::GetTaskActivityState(int index, int ActivityID) { - - - return ActiveTasks[index].Activity[ActivityID].State; +int ClientTaskState::GetTaskActivityDoneCount(TaskType type, int index, int ActivityID) +{ + switch (type) { + case TaskType::Task: + if (index != 0) + return 0; + return ActiveTask.Activity[ActivityID].DoneCount; + case TaskType::Shared: + return 0; // TODO: shared tasks + case TaskType::Quest: + if (index < MAXACTIVEQUESTS) + return ActiveQuests[index].Activity[ActivityID].DoneCount; + default: + return 0; + } } -int ClientTaskState::GetTaskActivityDoneCount(int index, int ActivityID) { +int ClientTaskState::GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID) +{ + if (ActiveTask.TaskID == TaskID) + return ActiveTask.Activity[ActivityID].DoneCount; - return ActiveTasks[index].Activity[ActivityID].DoneCount; + // TODO: shared tasks -} - -int ClientTaskState::GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID){ int ActiveTaskIndex = -1; - for(int i=0; ipBuffer; cts->SequenceNumber = SequenceNumber; - cts->unknown4 = 0x00000002; + cts->type = static_cast(type); Log(Logs::General, Logs::Tasks, "[UPDATE] CancelTask"); @@ -2953,121 +3142,184 @@ void ClientTaskState::CancelTask(Client *c, int SequenceNumber, bool RemoveFromD safe_delete(outapp); if(RemoveFromDB) - RemoveTask(c, SequenceNumber); + RemoveTask(c, SequenceNumber, type); } -void ClientTaskState::RemoveTask(Client *c, int sequenceNumber) { - +void ClientTaskState::RemoveTask(Client *c, int sequenceNumber, TaskType type) +{ int characterID = c->CharacterID(); - Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState Cancel Task %i ", sequenceNumber); + Log(Logs::General, Logs::Tasks, "[UPDATE] ClientTaskState Cancel Task %i ", sequenceNumber); - std::string query = StringFormat("DELETE FROM character_activities WHERE charid=%i AND taskid = %i", - characterID, ActiveTasks[sequenceNumber].TaskID); - auto results = database.QueryDatabase(query); - if(!results.Success()) { - Log(Logs::General, Logs::Error, "[TASKS] Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str()); + int task_id = -1; + switch (type) { + case TaskType::Task: + if (sequenceNumber == 0) + task_id = ActiveTask.TaskID; + break; + case TaskType::Quest: + if (sequenceNumber < MAXACTIVEQUESTS) + task_id = ActiveQuests[sequenceNumber].TaskID; + break; + case TaskType::Shared: // TODO: + default: + break; + } + + std::string query = StringFormat("DELETE FROM character_activities WHERE charid=%i AND taskid = %i", + characterID, task_id); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Log(Logs::General, Logs::Error, "[TASKS] Error in CientTaskState::CancelTask %s", + results.ErrorMessage().c_str()); return; } - Log(Logs::General, Logs::Tasks, "[UPDATE] CancelTask: %s", query.c_str()); + Log(Logs::General, Logs::Tasks, "[UPDATE] CancelTask: %s", query.c_str()); - query = StringFormat("DELETE FROM character_tasks WHERE charid=%i AND taskid = %i", - characterID, ActiveTasks[sequenceNumber].TaskID); + query = StringFormat("DELETE FROM character_tasks WHERE charid=%i AND taskid = %i AND type=%i", characterID, + task_id, static_cast(type)); results = database.QueryDatabase(query); - if(!results.Success()) - Log(Logs::General, Logs::Error, "[TASKS] Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str()); + if (!results.Success()) + Log(Logs::General, Logs::Error, "[TASKS] Error in CientTaskState::CancelTask %s", + results.ErrorMessage().c_str()); Log(Logs::General, Logs::Tasks, "[UPDATE] CancelTask: %s", query.c_str()); - ActiveTasks[sequenceNumber].TaskID = TASKSLOTEMPTY; - ActiveTaskCount--; + switch (type) { + case TaskType::Task: + ActiveTask.TaskID = TASKSLOTEMPTY; + break; + case TaskType::Shared: + break; // TODO: shared tasks + case TaskType::Quest: + ActiveQuests[sequenceNumber].TaskID = TASKSLOTEMPTY; + ActiveTaskCount--; + break; + default: + break; + } } - -void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement) { - - if(!taskmanager || TaskID<0 || TaskID>=MAXTASKS) { +void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement) +{ + if (!taskmanager || TaskID < 0 || TaskID >= MAXTASKS) { c->Message(13, "Task system not functioning, or TaskID %i out of range.", TaskID); return; - } - if(taskmanager->Tasks[TaskID] == nullptr) { + auto task = taskmanager->Tasks[TaskID]; + + if (task == nullptr) { c->Message(13, "Invalid TaskID %i", TaskID); return; } - if(ActiveTaskCount==MAXACTIVETASKS) { - c->Message(13, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVETASKS); + bool max_tasks = false; + + switch (task->type) { + case TaskType::Task: + if (ActiveTask.TaskID != TASKSLOTEMPTY) + max_tasks = true; + break; + case TaskType::Shared: // TODO: shared tasks + // if (something) + max_tasks = true; + break; + case TaskType::Quest: + if (ActiveTaskCount == MAXACTIVEQUESTS) + max_tasks = true; + break; + default: + break; + } + + if (max_tasks) { + c->Message(13, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVEQUESTS); return; } - for(int i=0; iMessage(13, "You have already been assigned this task."); - return; + // only Quests can have more than one, so don't need to check others + if (task->type == TaskType::Quest) { + for (int i = 0; i < MAXACTIVEQUESTS; i++) { + if (ActiveQuests[i].TaskID == TaskID) { + c->Message(13, "You have already been assigned this task."); + return; + } } } - if (enforce_level_requirement && !taskmanager->AppropriateLevel(TaskID, c->GetLevel())) - { + if (enforce_level_requirement && !taskmanager->AppropriateLevel(TaskID, c->GetLevel())) { c->Message(13, "You are outside the level range of this task."); return; } - if(!taskmanager->IsTaskRepeatable(TaskID) && IsTaskCompleted(TaskID)) return; + if (!taskmanager->IsTaskRepeatable(TaskID) && IsTaskCompleted(TaskID)) + return; // We do it this way, because when the Client cancels a task, it retains the sequence number of the remaining // tasks in it's window, until something causes the TaskDescription packets to be sent again. We could just // resend all the active task data to the client when it cancels a task, but that could be construed as a // waste of bandwidth. // - int FreeSlot = -1; - for(int i=0; itype) { + case TaskType::Task: + active_slot = &ActiveTask; + break; + case TaskType::Shared: // TODO: shared + active_slot = nullptr; + break; + case TaskType::Quest: + for (int i = 0; i < MAXACTIVEQUESTS; i++) { + Log(Logs::General, Logs::Tasks, + "[UPDATE] ClientTaskState Looking for free slot in slot %i, found TaskID of %i", i, + ActiveQuests[i].TaskID); + if (ActiveQuests[i].TaskID == 0) { + active_slot = &ActiveQuests[i]; + break; + } } + break; + default: + break; } // This shouldn't happen unless there is a bug in the handling of ActiveTaskCount somewhere - if(FreeSlot == -1) { - c->Message(13, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVETASKS); + if (active_slot == nullptr) { + c->Message(13, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVEQUESTS); return; } + active_slot->TaskID = TaskID; + active_slot->AcceptedTime = time(nullptr); + active_slot->Updated = true; + active_slot->CurrentStep = -1; - ActiveTasks[FreeSlot].TaskID = TaskID; - ActiveTasks[FreeSlot].AcceptedTime = time(nullptr); - ActiveTasks[FreeSlot].Updated = true; - ActiveTasks[FreeSlot].CurrentStep = -1; - - for(int i=0; iTasks[TaskID]->ActivityCount; i++) { - ActiveTasks[FreeSlot].Activity[i].ActivityID = i; - ActiveTasks[FreeSlot].Activity[i].DoneCount = 0; - ActiveTasks[FreeSlot].Activity[i].State = ActivityHidden; - ActiveTasks[FreeSlot].Activity[i].Updated = true; + for (int i = 0; i < taskmanager->Tasks[TaskID]->ActivityCount; i++) { + active_slot->Activity[i].ActivityID = i; + active_slot->Activity[i].DoneCount = 0; + active_slot->Activity[i].State = ActivityHidden; + active_slot->Activity[i].Updated = true; } - UnlockActivities(c->CharacterID(), FreeSlot); - ActiveTaskCount++; - taskmanager->SendSingleActiveTaskToClient(c, FreeSlot, false, true); - c->Message(0, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title); - char *buf = 0; - MakeAnyLenString(&buf, "%d", TaskID); + UnlockActivities(c->CharacterID(), *active_slot); + + if (task->type == TaskType::Quest) + ActiveTaskCount++; + + taskmanager->SendSingleActiveTaskToClient(c, *active_slot, false, true); + c->Message(0, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title.c_str()); + + std::string buf = std::to_string(TaskID); NPC *npc = entity_list.GetID(NPCID)->CastToNPC(); if(!npc) { c->Message(clientMessageYellow, "Task Giver ID is %i", NPCID); c->Message(clientMessageError, "Unable to find NPC to send EVENT_TASKACCEPTED to. Report this bug."); - safe_delete_array(buf); return; } - taskmanager->SaveClientState(c, this); - parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf, 0); - safe_delete_array(buf); + taskmanager->SaveClientState(c, this); + parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0); } void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) { @@ -3087,98 +3339,74 @@ void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float } } -TaskGoalListManager::TaskGoalListManager() { - - TaskGoalLists = nullptr; +TaskGoalListManager::TaskGoalListManager() +{ NumberOfLists = 0; - } -TaskGoalListManager::~TaskGoalListManager() { +TaskGoalListManager::~TaskGoalListManager() {} - for(int i=0; i< NumberOfLists; i++) { - - safe_delete_array(TaskGoalLists[i].GoalItemEntries); - - } - safe_delete_array(TaskGoalLists); -} - -bool TaskGoalListManager::LoadLists() { +bool TaskGoalListManager::LoadLists() +{ Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] TaskGoalListManager::LoadLists Called"); - for(int i=0; i< NumberOfLists; i++) - safe_delete_array(TaskGoalLists[i].GoalItemEntries); - safe_delete_array(TaskGoalLists); + TaskGoalLists.clear(); - const char *ERR_MYSQLERROR = "Error in TaskGoalListManager::LoadLists: %s %s"; + const char *ERR_MYSQLERROR = "Error in TaskGoalListManager::LoadLists: %s %s"; NumberOfLists = 0; - std::string query = "SELECT `listid`, COUNT(`entry`) " - "FROM `goallists` GROUP by `listid` " - "ORDER BY `listid`"; - auto results = database.QueryDatabase(query); - if (!results.Success()) { + std::string query = "SELECT `listid`, COUNT(`entry`) " + "FROM `goallists` GROUP by `listid` " + "ORDER BY `listid`"; + auto results = database.QueryDatabase(query); + if (!results.Success()) { return false; - } + } - NumberOfLists = results.RowCount(); - Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Database returned a count of %i lists", NumberOfLists); + NumberOfLists = results.RowCount(); + Log(Logs::General, Logs::Tasks, "[GLOBALLOAD] Database returned a count of %i lists", NumberOfLists); - TaskGoalLists = new TaskGoalList_Struct[NumberOfLists]; + TaskGoalLists.reserve(NumberOfLists); - int listIndex = 0; + int listIndex = 0; - for(auto row = results.begin(); row != results.end(); ++row) { - int listID = atoi(row[0]); - int listSize = atoi(row[1]); + for (auto row = results.begin(); row != results.end(); ++row) { + int listID = atoi(row[0]); + int listSize = atoi(row[1]); + TaskGoalLists.push_back({listID, 0, 0}); - TaskGoalLists[listIndex].ListID = listID; - TaskGoalLists[listIndex].Size = listSize; - TaskGoalLists[listIndex].Min = 0; - TaskGoalLists[listIndex].Max = 0; - TaskGoalLists[listIndex].GoalItemEntries = new int[listSize]; + TaskGoalLists[listIndex].GoalItemEntries.reserve(listSize); - listIndex++; - } + listIndex++; + } - for(int listIndex = 0; listIndex < NumberOfLists; listIndex++) { + for (int listIndex = 0; listIndex < NumberOfLists; listIndex++) { int listID = TaskGoalLists[listIndex].ListID; - unsigned int size = TaskGoalLists[listIndex].Size; - query = StringFormat("SELECT `entry` from `goallists` " - "WHERE `listid` = %i " - "ORDER BY `entry` ASC LIMIT %i", - listID, size); - results = database.QueryDatabase(query); - if (!results.Success()) { - TaskGoalLists[listIndex].Size = 0; + auto size = TaskGoalLists[listIndex].GoalItemEntries.capacity(); // this was only done for manual memory management, shouldn't need to do this + query = StringFormat("SELECT `entry` from `goallists` " + "WHERE `listid` = %i " + "ORDER BY `entry` ASC LIMIT %i", + listID, size); + results = database.QueryDatabase(query); + if (!results.Success()) { continue; - } + } - // This should only happen if a row is deleted in between us retrieving the counts - // at the start of this method and getting to here. It should not be possible for - // an INSERT to cause a problem, as the SELECT is used with a LIMIT - if(results.RowCount() < size) - TaskGoalLists[listIndex].Size = results.RowCount(); + for (auto row = results.begin(); row != results.end(); ++row) { - int entryIndex = 0; - for (auto row = results.begin(); row != results.end(); ++row, ++entryIndex) { + int entry = atoi(row[0]); - int entry = atoi(row[0]); + if (entry < TaskGoalLists[listIndex].Min) + TaskGoalLists[listIndex].Min = entry; - if(entry < TaskGoalLists[listIndex].Min) - TaskGoalLists[listIndex].Min = entry; - - if(entry > TaskGoalLists[listIndex].Max) - TaskGoalLists[listIndex].Max = entry; - - TaskGoalLists[listIndex].GoalItemEntries[entryIndex] = entry; - - } + if (entry > TaskGoalLists[listIndex].Max) + TaskGoalLists[listIndex].Max = entry; + TaskGoalLists[listIndex].GoalItemEntries.push_back(entry); + } } return true; @@ -3188,24 +3416,13 @@ bool TaskGoalListManager::LoadLists() { int TaskGoalListManager::GetListByID(int ListID) { // Find the list with the specified ListID and return the index + auto it = std::find_if(TaskGoalLists.begin(), TaskGoalLists.end(), + [ListID](const TaskGoalList_Struct &t) { return t.ListID == ListID; }); - int FirstEntry = 0; - int LastEntry = NumberOfLists - 1; - - while(FirstEntry <= LastEntry) { - int MiddleEntry = (FirstEntry + LastEntry) / 2; - - if(ListID > TaskGoalLists[MiddleEntry].ListID) - FirstEntry = MiddleEntry + 1; - else if(ListID < TaskGoalLists[MiddleEntry].ListID) - LastEntry = MiddleEntry - 1; - else - return MiddleEntry; - - } - - return -1; + if (it == TaskGoalLists.end()) + return -1; + return std::distance(TaskGoalLists.begin(), it); } int TaskGoalListManager::GetFirstEntry(int ListID) { @@ -3214,7 +3431,7 @@ int TaskGoalListManager::GetFirstEntry(int ListID) { if((ListIndex < 0) || (ListIndex >= NumberOfLists)) return -1; - if(TaskGoalLists[ListIndex].Size == 0) return -1; + if(TaskGoalLists[ListIndex].GoalItemEntries.empty()) return -1; return TaskGoalLists[ListIndex].GoalItemEntries[0]; } @@ -3227,45 +3444,35 @@ std::vector TaskGoalListManager::GetListContents(int ListID) { if((ListIndex < 0) || (ListIndex >= NumberOfLists)) return ListContents; - for(int i=0; i= NumberOfLists)) return false; + if ((ListIndex < 0) || (ListIndex >= NumberOfLists)) + return false; - if((Entry < TaskGoalLists[ListIndex].Min) || (Entry > TaskGoalLists[ListIndex].Max)) + if ((Entry < TaskGoalLists[ListIndex].Min) || (Entry > TaskGoalLists[ListIndex].Max)) return false; int FirstEntry = 0; - int LastEntry = TaskGoalLists[ListIndex].Size - 1; + auto &task = TaskGoalLists[ListIndex]; - while(FirstEntry <= LastEntry) { - int MiddleEntry = (FirstEntry + LastEntry) / 2; + auto it = std::find(task.GoalItemEntries.begin(), task.GoalItemEntries.end(), Entry); - if(Entry > TaskGoalLists[ListIndex].GoalItemEntries[MiddleEntry]) - FirstEntry = MiddleEntry + 1; - else if(Entry < TaskGoalLists[ListIndex].GoalItemEntries[MiddleEntry]) - LastEntry = MiddleEntry - 1; - else { - Log(Logs::General, Logs::Tasks, "[UPDATE] TaskGoalListManager::IsInList(%i, %i) returning true", ListIndex, Entry); - return true; - } - - } - - return false; + if (it == task.GoalItemEntries.end()) + return false; + Log(Logs::General, Logs::Tasks, "[UPDATE] TaskGoalListManager::IsInList(%i, %i) returning true", ListIndex, + Entry); + return true; } TaskProximityManager::TaskProximityManager() { diff --git a/zone/tasks.h b/zone/tasks.h index 5a6944639..1505a50a1 100644 --- a/zone/tasks.h +++ b/zone/tasks.h @@ -24,11 +24,12 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net) #include #include +#include #define MAXTASKS 10000 #define MAXTASKSETS 1000 -// The Client has a hard cap of 19 active tasks -#define MAXACTIVETASKS 19 +// The Client has a hard cap of 19 active quests, 29 in SoD+ +#define MAXACTIVEQUESTS 19 // The Max Chooser (Task Selector entries) is capped at 40 in the Titanium Client. #define MAXCHOOSERENTRIES 40 // The Client has a hard cap of 20 activities per task. @@ -53,9 +54,8 @@ namespace EQEmu struct TaskGoalList_Struct { int ListID; - int Size; int Min, Max; - int *GoalItemEntries; + std::vector GoalItemEntries; }; // This is used for handling lists, loading them from the database, searching them. @@ -75,7 +75,7 @@ public: private: - TaskGoalList_Struct *TaskGoalLists; + std::vector TaskGoalLists; int NumberOfLists; }; @@ -102,29 +102,52 @@ typedef enum { METHODSINGLEID = 0, METHODLIST = 1, METHODQUEST = 2 } TaskMethodT struct ActivityInformation { int StepNumber; int Type; - char *Text1; - char *Text2; - char *Text3; + std::string target_name; // name mob, location -- default empty + std::string item_list; // likely defaults to empty + std::string skill_list; // IDs ; separated -- default -1 + std::string spell_list; // IDs ; separated -- default 0 + std::string desc_override; // overrides auto generated description -- default empty + int skill_id; // older clients, first id from above + int spell_id; // older clients, first id from above int GoalID; TaskMethodType GoalMethod; int GoalCount; int DeliverToNPC; int ZoneID; + std::string zones; // IDs ; searated, ZoneID is the first in this list for older clients -- default empty string bool Optional; }; typedef enum { ActivitiesSequential = 0, ActivitiesStepped = 1 } SequenceType; +enum class TaskType { + Task = 0, // can have at max 1 + Shared = 1, // can have at max 1 + Quest = 2, // can have at max 19 or 29 depending on client + E = 3 // can have at max 19 or 29 depending on client, not present in live anymore +}; + +enum class DurationCode { + None = 0, + Short = 1, + Medium = 2, + Long = 3 +}; + struct TaskInformation { + TaskType type; int Duration; - char *Title; - char *Description; - char *Reward; + DurationCode dur_code; // description for time investment for when Duration == 0 + std::string Title; // max length 64 + std::string Description; // max length 4000, 2048 on Tit + std::string Reward; + std::string item_link; // max length 128 older clients, item link gets own string + std::string completion_emote; // emote after completing task, yellow. Maybe should make more generic ... but yellow for now! int RewardID; int CashReward; // Expressed in copper int XPReward; + int faction_reward; // just a npc_faction_id TaskMethodType RewardMethod; - int StartZone; int ActivityCount; SequenceType SequenceMode; int LastStep; @@ -137,8 +160,8 @@ struct TaskInformation { typedef enum { ActivityHidden = 0, ActivityActive = 1, ActivityCompleted = 2 } ActivityState; typedef enum { ActivityDeliver = 1, ActivityKill = 2, ActivityLoot = 3, ActivitySpeakWith = 4, ActivityExplore = 5, - ActivityTradeSkill = 6, ActivityFish = 7, ActivityForage = 8, ActivityUse1 = 9, ActivityUse2 = 10, - ActivityTouch = 11, ActivityGiveCash = 100 } ActivityType; + ActivityTradeSkill = 6, ActivityFish = 7, ActivityForage = 8, ActivityCastOn = 9, ActivitySkillOn = 10, + ActivityTouch = 11, ActivityCollect = 13, ActivityGiveCash = 100 } ActivityType; struct ClientActivityInformation { @@ -149,6 +172,7 @@ struct ClientActivityInformation { }; struct ClientTaskInformation { + int slot; // intrusive, but makes things easier :P int TaskID; int CurrentStep; int AcceptedTime; @@ -170,22 +194,22 @@ public: void ShowClientTasks(Client *c); inline int GetActiveTaskCount() { return ActiveTaskCount; } int GetActiveTaskID(int index); - bool IsTaskActivityCompleted(int index, int ActivityID); - int GetTaskActivityDoneCount(int index, int ActivityID); + bool IsTaskActivityCompleted(TaskType type, int index, int ActivityID); + int GetTaskActivityDoneCount(TaskType type, int index, int ActivityID); int GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID); - int GetTaskStartTime(int index); + int GetTaskStartTime(TaskType type, int index); void AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false); void FailTask(Client *c, int TaskID); int TaskTimeLeft(int TaskID); int IsTaskCompleted(int TaskID); bool IsTaskActive(int TaskID); bool IsTaskActivityActive(int TaskID, int ActivityID); - ActivityState GetTaskActivityState(int index, int ActivityID); + ActivityState GetTaskActivityState(TaskType type, int index, int ActivityID); void UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count, bool ignore_quest_update = false); void ResetTaskActivity(Client *c, int TaskID, int ActivityID); - void CancelTask(Client *c, int SequenceNumber, bool RemoveFromDB = true); + void CancelTask(Client *c, int SequenceNumber, TaskType type, bool RemoveFromDB = true); void CancelAllTasks(Client *c); - void RemoveTask(Client *c, int SequenceNumber); + void RemoveTask(Client *c, int SequenceNumber, TaskType type); bool UpdateTasksByNPC(Client *c, int ActivityType, int NPCTypeID); void UpdateTasksOnKill(Client *c, int NPCTypeID); void UpdateTasksForItem(Client *c, ActivityType Type, int ItemID, int Count=1); @@ -194,7 +218,7 @@ public: bool UpdateTasksOnDeliver(Client *c, std::list& Items, int Cash, int NPCTypeID); void UpdateTasksOnTouch(Client *c, int ZoneID); void ProcessTaskProximities(Client *c, float X, float Y, float Z); - bool TaskOutOfTime(int Index); + bool TaskOutOfTime(TaskType type, int Index); void TaskPeriodicChecks(Client *c); void SendTaskHistory(Client *c, int TaskIndex); void RewardTask(Client *c, TaskInformation *Task); @@ -206,14 +230,44 @@ public: int ActiveSpeakActivity(int NPCID, int TaskID); int ActiveTasksInSet(int TaskSetID); int CompletedTasksInSet(int TaskSetID); + bool HasSlotForTask(TaskInformation *task); + + inline bool HasFreeTaskSlot() { return ActiveTask.TaskID == TASKSLOTEMPTY; } + friend class TaskManager; private: - bool UnlockActivities(int CharID, int TaskIndex); + bool UnlockActivities(int CharID, ClientTaskInformation &task_info); void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count = 1, bool ignore_quest_update = false); + inline ClientTaskInformation *GetClientTaskInfo(TaskType type, int index) + { + ClientTaskInformation *info = nullptr; + switch (type) { + case TaskType::Task: + if (index == 0) + info = &ActiveTask; + break; + case TaskType::Shared: + break; + case TaskType::Quest: + if (index < MAXACTIVEQUESTS) + info = &ActiveQuests[index]; + break; + default: + break; + } + return info; + } int ActiveTaskCount; - ClientTaskInformation ActiveTasks[MAXACTIVETASKS]; - std::vectorEnabledTasks; + union { // easier to loop over + struct { + ClientTaskInformation ActiveTask; // only one + ClientTaskInformation ActiveQuests[MAXACTIVEQUESTS]; + }; + ClientTaskInformation ActiveTasks[MAXACTIVEQUESTS + 1]; + }; + // Shared tasks should be limited to 1 as well + std::vector EnabledTasks; std::vector CompletedTasks; int LastCompletedTaskLoaded; bool CheckedTouchActivities; @@ -239,8 +293,9 @@ public: int GetTaskMinLevel(int TaskID); int GetTaskMaxLevel(int TaskID); void TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID); + void TaskQuestSetSelector(Client *c, ClientTaskState *state, Mob *mob, int count, int *tasks); // task list provided by QuestManager (perl/lua) void SendActiveTasksToClient(Client *c, bool TaskComplete=false); - void SendSingleActiveTaskToClient(Client *c, int TaskIndex, bool TaskComplete, bool BringUpTaskJournal=false); + void SendSingleActiveTaskToClient(Client *c, ClientTaskInformation &task_info, bool TaskComplete, bool BringUpTaskJournal = false); void SendTaskActivityShort(Client *c, int TaskID, int ActivityID, int ClientTaskIndex); void SendTaskActivityLong(Client *c, int TaskID, int ActivityID, int ClientTaskIndex, bool Optional, bool TaskComplete=false); @@ -260,7 +315,7 @@ private: TaskProximityManager ProximityManager; TaskInformation* Tasks[MAXTASKS]; std::vector TaskSets[MAXTASKSETS]; - void SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal=false); + void SendActiveTaskDescription(Client *c, int TaskID, ClientTaskInformation &task_info, int StartTime, int Duration, bool BringUpTaskJournal=false); }; diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 262f46234..a6e0dbd34 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -69,7 +69,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme // Verify that no more than two items are in container to guarantee no inadvertant wipes. uint8 itemsFound = 0; - for (uint8 i = EQEmu::inventory::slotBegin; i < EQEmu::legacy::TYPE_WORLD_SIZE; i++) + for (uint8 i = EQEmu::invbag::SLOT_BEGIN; i < EQEmu::invtype::WORLD_SIZE; i++) { const EQEmu::ItemInstance* inst = container->GetItem(i); if (inst) @@ -222,7 +222,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme else { // Delete items in our inventory container... - for (uint8 i = EQEmu::inventory::slotBegin; i < EQEmu::legacy::TYPE_WORLD_SIZE; i++) + for (uint8 i = EQEmu::invbag::SLOT_BEGIN; i < EQEmu::invtype::WORLD_SIZE; i++) { const EQEmu::ItemInstance* inst = container->GetItem(i); if (inst) @@ -303,7 +303,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob const EQEmu::ItemData* new_weapon = inst->GetItem(); user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); - user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::inventory::slotCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2)); + user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::invslot::slotCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2)); user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name); if (RuleB(Inventory, DeleteTransformationMold)) user->DeleteItemInInventory(in_combine->container_slot, 0, true); @@ -323,7 +323,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob const EQEmu::ItemData* new_weapon = inst->GetItem(); user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); - user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::inventory::slotCursor, 0, 0); + user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::invslot::slotCursor, 0, 0); user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name); } else if (inst) { @@ -407,7 +407,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob safe_delete(outapp); database.DeleteWorldContainer(worldo->m_id, zone->GetZoneID()); } else{ - for (uint8 i = EQEmu::inventory::slotBegin; i < EQEmu::legacy::TYPE_WORLD_SIZE; i++) { + for (uint8 i = EQEmu::invbag::SLOT_BEGIN; i < EQEmu::invtype::WORLD_SIZE; i++) { const EQEmu::ItemInstance* inst = container->GetItem(i); if (inst) { user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, i), 0, true); @@ -1243,7 +1243,7 @@ bool ZoneDatabase::GetTradeRecipe(const EQEmu::ItemInstance* container, uint8 c_ for (auto row = results.begin(); row != results.end(); ++row) { int ccnt = 0; - for (int x = EQEmu::inventory::slotBegin; x < EQEmu::legacy::TYPE_WORLD_SIZE; x++) { + for (int x = EQEmu::invbag::SLOT_BEGIN; x < EQEmu::invtype::WORLD_SIZE; x++) { const EQEmu::ItemInstance* inst = container->GetItem(x); if(!inst) continue; diff --git a/zone/trading.cpp b/zone/trading.cpp index 70d5c85c1..d3456fbf2 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -99,7 +99,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { // Item always goes into trade bucket from cursor Client* client = owner->CastToClient(); - EQEmu::ItemInstance* inst = client->GetInv().GetItem(EQEmu::inventory::slotCursor); + EQEmu::ItemInstance* inst = client->GetInv().GetItem(EQEmu::invslot::slotCursor); if (!inst) { client->Message(13, "Error: Could not find item on your cursor!"); @@ -132,7 +132,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { if (_stack_size > 0) inst->SetCharges(_stack_size); else - client->DeleteItemInInventory(EQEmu::inventory::slotCursor); + client->DeleteItemInInventory(EQEmu::invslot::slotCursor); SendItemData(inst2, trade_slot_id); } @@ -147,7 +147,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { Log(Logs::Detail, Logs::Trading, "%s added item '%s' to trade slot %i", owner->GetName(), inst->GetItem()->Name, trade_slot_id); client->PutItemInInventory(trade_slot_id, *inst); - client->DeleteItemInInventory(EQEmu::inventory::slotCursor); + client->DeleteItemInInventory(EQEmu::invslot::slotCursor); } } @@ -172,13 +172,13 @@ void Trade::SendItemData(const EQEmu::ItemInstance* inst, int16 dest_slot_id) Client* with = mob->CastToClient(); Client* trader = owner->CastToClient(); if (with && with->IsClient()) { - with->SendItemPacket(dest_slot_id - EQEmu::legacy::TRADE_BEGIN, inst, ItemPacketTradeView); + with->SendItemPacket(dest_slot_id - EQEmu::invslot::TRADE_BEGIN, inst, ItemPacketTradeView); if (inst->GetItem()->ItemClass == 1) { - for (uint16 i = EQEmu::inventory::containerBegin; i < EQEmu::inventory::ContainerCount; i++) { + for (uint16 i = EQEmu::invbag::SLOT_BEGIN; i <= EQEmu::invbag::SLOT_END; i++) { uint16 bagslot_id = EQEmu::InventoryProfile::CalcSlotId(dest_slot_id, i); const EQEmu::ItemInstance* bagitem = trader->GetInv().GetItem(bagslot_id); if (bagitem) { - with->SendItemPacket(bagslot_id - EQEmu::legacy::TRADE_BEGIN, bagitem, ItemPacketTradeView); + with->SendItemPacket(bagslot_id - EQEmu::invslot::TRADE_BEGIN, bagitem, ItemPacketTradeView); } } } @@ -200,7 +200,7 @@ void Trade::LogTrade() uint8 item_count = 0; if (zone->tradevar != 0) { - for (uint16 i = EQEmu::legacy::TRADE_BEGIN; i <= EQEmu::legacy::TRADE_END; i++) { + for (uint16 i = EQEmu::invslot::TRADE_BEGIN; i <= EQEmu::invslot::TRADE_END; i++) { if (trader->GetInv().GetItem(i)) item_count++; } @@ -252,7 +252,7 @@ void Trade::LogTrade() if (item_count > 0) { strcat(logtext, "items {"); - for (uint16 i = EQEmu::legacy::TRADE_BEGIN; i <= EQEmu::legacy::TRADE_END; i++) { + for (uint16 i = EQEmu::invslot::TRADE_BEGIN; i <= EQEmu::invslot::TRADE_END; i++) { const EQEmu::ItemInstance* inst = trader->GetInv().GetItem(i); if (!comma) @@ -268,7 +268,7 @@ void Trade::LogTrade() strcat(logtext, item_num); if (inst->IsClassBag()) { - for (uint8 j = EQEmu::inventory::containerBegin; j < EQEmu::inventory::ContainerCount; j++) { + for (uint8 j = EQEmu::invbag::SLOT_BEGIN; j <= EQEmu::invbag::SLOT_END; j++) { inst = trader->GetInv().GetItem(i, j); if (inst) { strcat(logtext, ","); @@ -304,7 +304,7 @@ void Trade::DumpTrade() return; Client* trader = owner->CastToClient(); - for (uint16 i = EQEmu::legacy::TRADE_BEGIN; i <= EQEmu::legacy::TRADE_END; i++) { + for (uint16 i = EQEmu::invslot::TRADE_BEGIN; i <= EQEmu::invslot::TRADE_END; i++) { const EQEmu::ItemInstance* inst = trader->GetInv().GetItem(i); if (inst) { @@ -313,7 +313,7 @@ void Trade::DumpTrade() i, ((inst->IsClassBag()) ? "True" : "False")); if (inst->IsClassBag()) { - for (uint8 j = EQEmu::inventory::containerBegin; j < EQEmu::inventory::ContainerCount; j++) { + for (uint8 j = EQEmu::invbag::SLOT_BEGIN; j <= EQEmu::invbag::SLOT_END; j++) { inst = trader->GetInv().GetItem(i, j); if (inst) { Log(Logs::Detail, Logs::Trading, "\tBagItem %i (Charges=%i, Slot=%i)", @@ -333,7 +333,7 @@ void Client::ResetTrade() { AddMoneyToPP(trade->cp, trade->sp, trade->gp, trade->pp, true); // step 1: process bags - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_END; ++trade_slot) { const EQEmu::ItemInstance* inst = m_inv[trade_slot]; if (inst && inst->IsClassBag()) { @@ -352,7 +352,7 @@ void Client::ResetTrade() { } // step 2a: process stackables - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_END; ++trade_slot) { EQEmu::ItemInstance* inst = GetInv().GetItem(trade_slot); if (inst && inst->IsStackable()) { @@ -360,7 +360,7 @@ void Client::ResetTrade() { // there's no built-in safety check against an infinite loop..but, it should break on one of the conditional checks int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst); - if ((free_slot == EQEmu::inventory::slotCursor) || (free_slot == INVALID_INDEX)) + if ((free_slot == EQEmu::invslot::slotCursor) || (free_slot == INVALID_INDEX)) break; EQEmu::ItemInstance* partial_inst = GetInv().GetItem(free_slot); @@ -399,11 +399,11 @@ void Client::ResetTrade() { // step 2b: adjust trade stack bias // (if any partial stacks exist before the final stack, FindFreeSlotForTradeItem() will return that slot in step 3 and an overwrite will occur) - for (int16 trade_slot = EQEmu::legacy::TRADE_END; trade_slot >= EQEmu::legacy::TRADE_BEGIN; --trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_END; trade_slot >= EQEmu::invslot::TRADE_BEGIN; --trade_slot) { EQEmu::ItemInstance* inst = GetInv().GetItem(trade_slot); if (inst && inst->IsStackable()) { - for (int16 bias_slot = EQEmu::legacy::TRADE_BEGIN; bias_slot <= EQEmu::legacy::TRADE_END; ++bias_slot) { + for (int16 bias_slot = EQEmu::invslot::TRADE_BEGIN; bias_slot <= EQEmu::invslot::TRADE_END; ++bias_slot) { if (bias_slot >= trade_slot) break; @@ -433,7 +433,7 @@ void Client::ResetTrade() { } // step 3: process everything else - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_END; ++trade_slot) { const EQEmu::ItemInstance* inst = m_inv[trade_slot]; if (inst) { @@ -488,7 +488,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } // step 1: process bags - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_END; ++trade_slot) { const EQEmu::ItemInstance* inst = m_inv[trade_slot]; if (inst && inst->IsClassBag()) { @@ -523,7 +523,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st else qs_audit->char1_count += detail->charges; - for (uint8 sub_slot = EQEmu::inventory::containerBegin; (sub_slot < EQEmu::inventory::ContainerCount); ++sub_slot) { // this is to catch ALL items + for (uint8 sub_slot = EQEmu::invbag::SLOT_BEGIN; (sub_slot <= EQEmu::invbag::SLOT_END); ++sub_slot) { // this is to catch ALL items const EQEmu::ItemInstance* bag_inst = inst->GetItem(sub_slot); if (bag_inst) { @@ -571,7 +571,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } // step 2a: process stackables - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_END; ++trade_slot) { EQEmu::ItemInstance* inst = GetInv().GetItem(trade_slot); if (inst && inst->IsStackable()) { @@ -579,7 +579,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st // there's no built-in safety check against an infinite loop..but, it should break on one of the conditional checks int16 partial_slot = other->GetInv().FindFreeSlotForTradeItem(inst); - if ((partial_slot == EQEmu::inventory::slotCursor) || (partial_slot == INVALID_INDEX)) + if ((partial_slot == EQEmu::invslot::slotCursor) || (partial_slot == INVALID_INDEX)) break; EQEmu::ItemInstance* partial_inst = other->GetInv().GetItem(partial_slot); @@ -653,11 +653,11 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st // step 2b: adjust trade stack bias // (if any partial stacks exist before the final stack, FindFreeSlotForTradeItem() will return that slot in step 3 and an overwrite will occur) - for (int16 trade_slot = EQEmu::legacy::TRADE_END; trade_slot >= EQEmu::legacy::TRADE_BEGIN; --trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_END; trade_slot >= EQEmu::invslot::TRADE_BEGIN; --trade_slot) { EQEmu::ItemInstance* inst = GetInv().GetItem(trade_slot); if (inst && inst->IsStackable()) { - for (int16 bias_slot = EQEmu::legacy::TRADE_BEGIN; bias_slot <= EQEmu::legacy::TRADE_END; ++bias_slot) { + for (int16 bias_slot = EQEmu::invslot::TRADE_BEGIN; bias_slot <= EQEmu::invslot::TRADE_END; ++bias_slot) { if (bias_slot >= trade_slot) break; @@ -706,7 +706,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } // step 3: process everything else - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_END; ++trade_slot) { const EQEmu::ItemInstance* inst = m_inv[trade_slot]; if (inst) { @@ -742,7 +742,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st qs_audit->char1_count += detail->charges; // 'step 3' should never really see containers..but, just in case... - for (uint8 sub_slot = EQEmu::inventory::containerBegin; (sub_slot < EQEmu::inventory::ContainerCount); ++sub_slot) { // this is to catch ALL items + for (uint8 sub_slot = EQEmu::invbag::SLOT_BEGIN; (sub_slot <= EQEmu::invbag::SLOT_END); ++sub_slot) { // this is to catch ALL items const EQEmu::ItemInstance* bag_inst = inst->GetItem(sub_slot); if (bag_inst) { @@ -819,7 +819,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } if(qs_log) { // This can be incorporated below when revisions are made - for (int16 trade_slot = EQEmu::legacy::TRADE_BEGIN; trade_slot <= EQEmu::legacy::TRADE_NPC_END; ++trade_slot) { + for (int16 trade_slot = EQEmu::invslot::TRADE_BEGIN; trade_slot <= EQEmu::invslot::TRADE_NPC_END; ++trade_slot) { const EQEmu::ItemInstance* trade_inst = m_inv[trade_slot]; if(trade_inst) { @@ -840,7 +840,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st qs_audit->char_count += detail->charges; if (trade_inst->IsClassBag()) { - for (uint8 sub_slot = EQEmu::inventory::containerBegin; sub_slot < trade_inst->GetItem()->BagSlots; ++sub_slot) { + for (uint8 sub_slot = EQEmu::invbag::SLOT_BEGIN; sub_slot < trade_inst->GetItem()->BagSlots; ++sub_slot) { const EQEmu::ItemInstance* trade_baginst = trade_inst->GetItem(sub_slot); if(trade_baginst) { @@ -874,7 +874,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st std::vector item_list; std::list items; - for (int i = EQEmu::legacy::TRADE_BEGIN; i <= EQEmu::legacy::TRADE_NPC_END; ++i) { + for (int i = EQEmu::invslot::TRADE_BEGIN; i <= EQEmu::invslot::TRADE_NPC_END; ++i) { EQEmu::ItemInstance *inst = m_inv.GetItem(i); if(inst) { items.push_back(inst); @@ -894,7 +894,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st (item->NoDrop != 0 || isPetAndCanHaveNoDrop))) { // pets need to look inside bags and try to equip items found there if (item->IsClassBag() && item->BagSlots > 0) { - for (int16 bslot = EQEmu::inventory::containerBegin; bslot < item->BagSlots; bslot++) { + for (int16 bslot = EQEmu::invbag::SLOT_BEGIN; bslot < item->BagSlots; bslot++) { const EQEmu::ItemInstance* baginst = inst->GetItem(bslot); if (baginst) { const EQEmu::ItemData* bagitem = baginst->GetItem(); @@ -951,8 +951,8 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } EQEmu::ItemInstance *insts[4] = { 0 }; - for (int i = EQEmu::legacy::TRADE_BEGIN; i <= EQEmu::legacy::TRADE_NPC_END; ++i) { - insts[i - EQEmu::legacy::TRADE_BEGIN] = m_inv.PopItem(i); + for (int i = EQEmu::invslot::TRADE_BEGIN; i <= EQEmu::invslot::TRADE_NPC_END; ++i) { + insts[i - EQEmu::invslot::TRADE_BEGIN] = m_inv.PopItem(i); database.SaveInventory(CharacterID(), nullptr, i); } @@ -971,7 +971,7 @@ bool Client::CheckTradeLoreConflict(Client* other) if (!other) return true; - for (int16 index = EQEmu::legacy::TRADE_BEGIN; index <= EQEmu::legacy::TRADE_END; ++index) { + for (int16 index = EQEmu::invslot::TRADE_BEGIN; index <= EQEmu::invslot::TRADE_END; ++index) { const EQEmu::ItemInstance* inst = m_inv[index]; if (!inst || !inst->GetItem()) continue; @@ -980,7 +980,7 @@ bool Client::CheckTradeLoreConflict(Client* other) return true; } - for (int16 index = EQEmu::legacy::TRADE_BAGS_BEGIN; index <= EQEmu::legacy::TRADE_BAGS_END; ++index) { + for (int16 index = EQEmu::invbag::TRADE_BAGS_BEGIN; index <= EQEmu::invbag::TRADE_BAGS_END; ++index) { const EQEmu::ItemInstance* inst = m_inv[index]; if (!inst || !inst->GetItem()) continue; @@ -994,7 +994,7 @@ bool Client::CheckTradeLoreConflict(Client* other) bool Client::CheckTradeNonDroppable() { - for (int16 index = EQEmu::legacy::TRADE_BEGIN; index <= EQEmu::legacy::TRADE_END; ++index){ + for (int16 index = EQEmu::invslot::TRADE_BEGIN; index <= EQEmu::invslot::TRADE_END; ++index){ const EQEmu::ItemInstance* inst = m_inv[index]; if (!inst) continue; @@ -1213,7 +1213,7 @@ void Client::BulkSendTraderInventory(uint32 char_id) { TraderCharges_Struct* TraderItems = database.LoadTraderItemWithCharges(char_id); - for (uint8 i = 0;i < 80; i++) { + for (uint8 i = 0;i < 80; i++) { // need to transition away from 'magic number' if((TraderItems->ItemID[i] == 0) || (TraderItems->ItemCost[i] <= 0)) { continue; } @@ -1249,10 +1249,10 @@ uint32 Client::FindTraderItemSerialNumber(int32 ItemID) { EQEmu::ItemInstance* item = nullptr; uint16 SlotID = 0; - for (int i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++){ + for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++){ item = this->GetInv().GetItem(i); if (item && item->GetItem()->ID == 17899){ //Traders Satchel - for (int x = EQEmu::inventory::containerBegin; x < EQEmu::inventory::ContainerCount; x++) { + for (int x = EQEmu::invbag::SLOT_BEGIN; x <= EQEmu::invbag::SLOT_END; x++) { // we already have the parent bag and a contents iterator..why not just iterate the bag!?? SlotID = EQEmu::InventoryProfile::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); @@ -1272,10 +1272,10 @@ EQEmu::ItemInstance* Client::FindTraderItemBySerialNumber(int32 SerialNumber){ EQEmu::ItemInstance* item = nullptr; uint16 SlotID = 0; - for (int i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++){ + for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++){ item = this->GetInv().GetItem(i); if(item && item->GetItem()->ID == 17899){ //Traders Satchel - for (int x = EQEmu::inventory::containerBegin; x < EQEmu::inventory::ContainerCount; x++) { + for (int x = EQEmu::invbag::SLOT_BEGIN; x <= EQEmu::invbag::SLOT_END; x++) { // we already have the parent bag and a contents iterator..why not just iterate the bag!?? SlotID = EQEmu::InventoryProfile::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); @@ -1303,10 +1303,10 @@ GetItems_Struct* Client::GetTraderItems(){ uint8 ndx = 0; - for (int i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++) { + for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) { item = this->GetInv().GetItem(i); if(item && item->GetItem()->ID == 17899){ //Traders Satchel - for (int x = EQEmu::inventory::containerBegin; x < EQEmu::inventory::ContainerCount; x++) { + for (int x = EQEmu::invbag::SLOT_BEGIN; x <= EQEmu::invbag::SLOT_END; x++) { SlotID = EQEmu::InventoryProfile::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); @@ -1327,10 +1327,10 @@ uint16 Client::FindTraderItem(int32 SerialNumber, uint16 Quantity){ const EQEmu::ItemInstance* item= nullptr; uint16 SlotID = 0; - for (int i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; i++) { + for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) { item = this->GetInv().GetItem(i); if(item && item->GetItem()->ID == 17899){ //Traders Satchel - for (int x = EQEmu::inventory::containerBegin; x < EQEmu::inventory::ContainerCount; x++){ + for (int x = EQEmu::invbag::SLOT_BEGIN; x <= EQEmu::invbag::SLOT_END; x++){ SlotID = EQEmu::InventoryProfile::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); diff --git a/zone/tribute.cpp b/zone/tribute.cpp index 641549cda..ce1eb5f6d 100644 --- a/zone/tribute.cpp +++ b/zone/tribute.cpp @@ -66,7 +66,7 @@ void Client::ToggleTribute(bool enabled) { int r; uint32 cost = 0; uint32 level = GetLevel(); - for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { + for (r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { uint32 tid = m_pp.tributes[r].tribute; if(tid == TRIBUTE_NONE) continue; @@ -119,7 +119,7 @@ void Client::DoTributeUpdate() { tis->tribute_master_id = tribute_master_id; //Dont know what this is for int r; - for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { + for (r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { if(m_pp.tributes[r].tribute != TRIBUTE_NONE) { tis->tributes[r] = m_pp.tributes[r].tribute; tis->tiers[r] = m_pp.tributes[r].tier; @@ -134,24 +134,24 @@ void Client::DoTributeUpdate() { if(m_pp.tribute_active) { //send and equip tribute items... - for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { + for (r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { uint32 tid = m_pp.tributes[r].tribute; if(tid == TRIBUTE_NONE) { - if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) - DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); + if (m_inv[EQEmu::invslot::TRIBUTE_BEGIN + r]) + DeleteItemInInventory(EQEmu::invslot::TRIBUTE_BEGIN + r, 0, false); continue; } if(tribute_list.count(tid) != 1) { - if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) - DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); + if (m_inv[EQEmu::invslot::TRIBUTE_BEGIN + r]) + DeleteItemInInventory(EQEmu::invslot::TRIBUTE_BEGIN + r, 0, false); continue; } //sanity check if(m_pp.tributes[r].tier >= MAX_TRIBUTE_TIERS) { - if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) - DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); + if (m_inv[EQEmu::invslot::TRIBUTE_BEGIN + r]) + DeleteItemInInventory(EQEmu::invslot::TRIBUTE_BEGIN + r, 0, false); m_pp.tributes[r].tier = 0; continue; } @@ -165,15 +165,15 @@ void Client::DoTributeUpdate() { if(inst == nullptr) continue; - PutItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, *inst, false); - SendItemPacket(EQEmu::legacy::TRIBUTE_BEGIN + r, inst, ItemPacketTributeItem); + PutItemInInventory(EQEmu::invslot::TRIBUTE_BEGIN + r, *inst, false); + SendItemPacket(EQEmu::invslot::TRIBUTE_BEGIN + r, inst, ItemPacketTributeItem); safe_delete(inst); } } else { //unequip tribute items... - for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { - if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) - DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); + for (r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { + if (m_inv[EQEmu::invslot::TRIBUTE_BEGIN + r]) + DeleteItemInInventory(EQEmu::invslot::TRIBUTE_BEGIN + r, 0, false); } } CalcBonuses(); @@ -192,7 +192,7 @@ void Client::SendTributeTimer() { void Client::ChangeTributeSettings(TributeInfo_Struct *t) { int r; - for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { + for (r = 0; r < EQEmu::invtype::TRIBUTE_SIZE; r++) { m_pp.tributes[r].tribute = TRIBUTE_NONE; diff --git a/zone/tune.cpp b/zone/tune.cpp index 36be51905..c0510f94a 100644 --- a/zone/tune.cpp +++ b/zone/tune.cpp @@ -582,13 +582,13 @@ int32 Client::Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 mi int32 Client::GetMeleeDamage(Mob* other, bool GetMinDamage) { - int Hand = EQEmu::inventory::slotPrimary; + int Hand = EQEmu::invslot::slotPrimary; if (!other) return 0; EQEmu::ItemInstance* weapon; - weapon = GetInv().GetItem(EQEmu::inventory::slotPrimary); + weapon = GetInv().GetItem(EQEmu::invslot::slotPrimary); if(weapon != nullptr) { if (!weapon->IsWeapon()) { @@ -627,7 +627,7 @@ int32 Client::GetMeleeDamage(Mob* other, bool GetMinDamage) int ucDamageBonus = 0; - if (Hand == EQEmu::inventory::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) + if (Hand == EQEmu::invslot::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) { ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr); @@ -661,24 +661,24 @@ void Mob::Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_ch if (attacker->IsClient()) {//Will check first equiped weapon for skill. Ie. remove wepaons to assess bow. EQEmu::ItemInstance* weapon; - weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); + weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if(weapon && weapon->IsWeapon()){ - skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotPrimary, weapon); + skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::invslot::slotPrimary, weapon); } else { - weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary); + weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::invslot::slotSecondary); if (weapon && weapon->IsWeapon()) - skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotSecondary, weapon); + skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::invslot::slotSecondary, weapon); else { - weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotRange); + weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::invslot::slotRange); if (weapon && weapon->IsWeapon()) - skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotRange, weapon); + skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::invslot::slotRange, weapon); } } } - tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::inventory::slotPrimary, 0, 0, 0, avoid_override); + tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, 0, 0, avoid_override); Message(0, "#Tune - Begin Parse [Interval %i Max Loop Iterations %i]", interval, max_loop); @@ -690,7 +690,7 @@ void Mob::Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_ch for (int j=0; j < max_loop; j++) { - tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::inventory::slotPrimary, 0, false, 0, avoid_override, add_acc); + tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, false, 0, avoid_override, add_acc); if (Msg >= 3) Message(15, "#Tune - Processing... [%i] [ACCURACY %i] Hit Chance %.2f ",j,add_acc,tmp_hit_chance); @@ -705,7 +705,7 @@ void Mob::Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_ch if (end){ - Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::inventory::slotPrimary, 0, Msg, 0, avoid_override);//Display Stat Report + Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, Msg, 0, avoid_override);//Display Stat Report Message(0, " "); @@ -741,24 +741,24 @@ void Mob::Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_ if (attacker->IsClient()) {//Will check first equiped weapon for skill. Ie. remove wepaons to assess bow. EQEmu::ItemInstance* weapon; - weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotPrimary); + weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if(weapon && weapon->IsWeapon()){ - skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotPrimary, weapon); + skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::invslot::slotPrimary, weapon); } else { - weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotSecondary); + weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::invslot::slotSecondary); if (weapon && weapon->IsWeapon()) - skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotSecondary, weapon); + skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::invslot::slotSecondary, weapon); else { - weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::inventory::slotRange); + weapon = attacker->CastToClient()->GetInv().GetItem(EQEmu::invslot::slotRange); if (weapon && weapon->IsWeapon()) - skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::inventory::slotRange, weapon); + skillinuse = attacker->CastToClient()->AttackAnimation(EQEmu::invslot::slotRange, weapon); } } } - tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::inventory::slotPrimary, 0, 0, acc_override, 0); + tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, 0, acc_override, 0); Message(0, "#Tune - Begin Parse [Interval %i Max Loop Iterations %i]", interval, max_loop); Message(0, "#Tune - Processing... Find Avoidance for hit chance on defender of (%.0f) pct from attacker. [Current Hit Chance %.2f]", hit_chance, tmp_hit_chance); @@ -768,7 +768,7 @@ void Mob::Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_ for (int j=0; j < max_loop; j++) { - tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::inventory::slotPrimary, 0, 0, acc_override, 0, 0, add_avoid); + tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, 0, acc_override, 0, 0, add_avoid); if (Msg >= 3) Message(0, "#Tune - Processing... [%i] [AVOIDANCE %i] Hit Chance %.2f ",j,add_avoid,tmp_hit_chance); @@ -783,7 +783,7 @@ void Mob::Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_ if (end){ - Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::inventory::slotPrimary, 0, Msg, acc_override, 0);//Display Stat Report + Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, Msg, acc_override, 0);//Display Stat Report Message(0, " "); diff --git a/zone/water_map.cpp b/zone/water_map.cpp index f3b4c58d8..d6b84a802 100644 --- a/zone/water_map.cpp +++ b/zone/water_map.cpp @@ -3,6 +3,7 @@ #include "water_map.h" #include "water_map_v1.h" #include "water_map_v2.h" +#include "../common/eqemu_logsys.h" #include #include @@ -12,7 +13,7 @@ WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) { std::transform(zone_name.begin(), zone_name.end(), zone_name.begin(), ::tolower); - std::string file_path = Config->MapDir + zone_name + std::string(".wtr"); + std::string file_path = Config->MapDir + "water/" + zone_name + std::string(".wtr"); FILE *f = fopen(file_path.c_str(), "rb"); if(f) { char magic[10]; @@ -38,7 +39,9 @@ WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) { delete wm; wm = nullptr; } - + + Log(Logs::General, Logs::Status, "Loaded Water Map V%u file %s", version, file_path.c_str()); + fclose(f); return wm; } else if(version == 2) { @@ -47,7 +50,9 @@ WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) { delete wm; wm = nullptr; } - + + Log(Logs::General, Logs::Status, "Loaded Water Map V%u file %s", version, file_path.c_str()); + fclose(f); return wm; } else { diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 55a2cc511..2351e2686 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -420,7 +420,7 @@ void NPC::SaveGuardSpot(bool iClearGuardSpot) { } void NPC::NextGuardPosition() { - if (!CalculateNewPosition2(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, GetMovespeed())) { + if (!CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, GetMovespeed())) { SetHeading(m_GuardPoint.w); Log(Logs::Detail, Logs::AI, "Unable to move to next guard position. Probably rooted."); } @@ -615,89 +615,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo return true; } -bool Mob::CalculateNewPosition2(float x, float y, float z, int speed, bool checkZ, bool calcHeading) { - return MakeNewPositionAndSendUpdate(x, y, z, speed, checkZ, calcHeading); -} - bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ, bool calcHeading) { - if (GetID() == 0) - return true; - - float nx = m_Position.x; - float ny = m_Position.y; - float nz = m_Position.z; - - // if NPC is rooted - if (speed == 0) { - SetHeading(CalculateHeadingToTarget(x, y)); - if (moved) { - SetCurrentSpeed(0); - moved = false; - } - Log(Logs::Detail, Logs::AI, "Rooted while calculating new position to (%.3f, %.3f, %.3f)", x, y, z); - return true; - } - - float old_test_vector = test_vector; - m_TargetV.x = x - nx; - m_TargetV.y = y - ny; - m_TargetV.z = z - nz; - - if (m_TargetV.x == 0 && m_TargetV.y == 0) - return false; - SetCurrentSpeed((int8)(speed)); //*NPC_RUNANIM_RATIO); - //speed *= NPC_SPEED_MULTIPLIER; - - Log(Logs::Detail, Logs::AI, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z, speed, pRunAnimSpeed); - - // -------------------------------------------------------------------------- - // 2: get unit vector - // -------------------------------------------------------------------------- - test_vector = sqrtf(x*x + y*y + z*z); - tar_vector = speed / sqrtf(m_TargetV.x*m_TargetV.x + m_TargetV.y*m_TargetV.y + m_TargetV.z*m_TargetV.z); - m_Position.w = CalculateHeadingToTarget(x, y); - - if (tar_vector >= 1.0) { - if (IsNPC()) { - entity_list.ProcessMove(CastToNPC(), x, y, z); - } - - m_Position.x = x; - m_Position.y = y; - m_Position.z = z; - Log(Logs::Detail, Logs::AI, "Close enough, jumping to waypoint"); - } - else { - float new_x = m_Position.x + m_TargetV.x*tar_vector; - float new_y = m_Position.y + m_TargetV.y*tar_vector; - float new_z = m_Position.z + m_TargetV.z*tar_vector; - if (IsNPC()) { - entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); - } - - m_Position.x = new_x; - m_Position.y = new_y; - m_Position.z = new_z; - Log(Logs::Detail, Logs::AI, "Next position (%.3f, %.3f, %.3f)", m_Position.x, m_Position.y, m_Position.z); - } - - if (fix_z_timer.Check()) - this->FixZ(); - - //OP_MobUpdate - if ((old_test_vector != test_vector) || tar_ndx>20) { //send update - tar_ndx = 0; - this->SetMoving(true); - moved = true; - m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f); - SendPositionUpdate(); - } - tar_ndx++; - - // now get new heading - SetAppearance(eaStanding, false); // make sure they're standing - pLastChange = Timer::GetCurrentTime(); - return true; + return MakeNewPositionAndSendUpdate(x, y, z, speed); } void NPC::AssignWaypoints(int32 grid) @@ -827,61 +746,60 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) { } } -float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) -{ +float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) { BenchTimer timer; timer.reset(); float new_z = dest.z; - if (zone->HasMap() && RuleB(Map, FixZWhenMoving) && - (flymode != 1 && flymode != 2)) - { - if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() - || (zone->HasWaterMap() && - !zone->watermap->InWater(glm::vec3(m_Position)))) - { - /* Any more than 5 in the offset makes NPC's hop/snap to ceiling in small corridors */ - new_z = this->FindDestGroundZ(dest, z_find_offset); - if (new_z != BEST_Z_INVALID) - { - new_z += this->GetZOffset(); + if (zone->HasMap() && RuleB(Map, FixZWhenMoving)) { - // If bad new Z restore old one - if (new_z < -2000) { - new_z = m_Position.z; - } + if (flymode == 1 || flymode == 2) + return new_z; + + if (this->IsBoat()) + return new_z; + + if (zone->HasWaterMap() && zone->watermap->InWater(glm::vec3(m_Position))) + return new_z; + + /* + * Any more than 5 in the offset makes NPC's hop/snap to ceiling in small corridors + */ + new_z = this->FindDestGroundZ(dest, z_find_offset); + if (new_z != BEST_Z_INVALID) { + new_z += this->GetZOffset(); + + if (new_z < -2000) { + new_z = m_Position.z; } } auto duration = timer.elapsed(); Log(Logs::Moderate, Logs::FixZ, - "Mob::GetFixedZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", - this->GetCleanName(), new_z, dest.x, dest.y, dest.z, duration); + "Mob::GetFixedZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", + this->GetCleanName(), new_z, dest.x, dest.y, dest.z, duration); } return new_z; } -void Mob::FixZ(int32 z_find_offset /*= 5*/) -{ +void Mob::FixZ(int32 z_find_offset /*= 5*/) { glm::vec3 current_loc(m_Position); - float new_z = GetFixedZ(current_loc, z_find_offset); + float new_z = GetFixedZ(current_loc, z_find_offset); - if (!IsClient() && new_z != m_Position.z) - { + if (!IsClient() && new_z != m_Position.z) { if ((new_z > -2000) && new_z != BEST_Z_INVALID) { if (RuleB(Map, MobZVisualDebug)) this->SendAppearanceEffect(78, 0, 0, 0, 0); m_Position.z = new_z; - } - else { + } else { if (RuleB(Map, MobZVisualDebug)) this->SendAppearanceEffect(103, 0, 0, 0, 0); Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f", - this->GetCleanName(), std::abs(m_Position.z - new_z)); + this->GetCleanName(), std::abs(m_Position.z - new_z)); } } } @@ -890,107 +808,109 @@ float Mob::GetZOffset() const { float offset = 3.125f; switch (race) { - case 436: + case RACE_BASILISK_436: offset = 0.577f; break; - case 430: + case RACE_DRAKE_430: offset = 0.5f; break; - case 432: + case RACE_DRAKE_432: offset = 1.9f; break; - case 435: + case RACE_DRAGON_435: offset = 0.93f; break; - case 450: + case RACE_LAVA_SPIDER_450: offset = 0.938f; break; - case 479: + case RACE_ALLIGATOR_479: offset = 0.8f; break; - case 451: + case RACE_LAVA_SPIDER_QUEEN_451: offset = 0.816f; break; - case 437: + case RACE_DRAGON_437: offset = 0.527f; break; - case 439: + case RACE_PUMA_439: offset = 1.536f; break; - case 415: + case RACE_RAT_415: offset = 1.0f; break; - case 438: + case RACE_DRAGON_438: offset = 0.776f; break; - case 452: + case RACE_DRAGON_452: offset = 0.776f; break; - case 441: + case RACE_SPIDER_QUEEN_441: offset = 0.816f; break; - case 440: + case RACE_SPIDER_440: offset = 0.938f; break; - case 468: + case RACE_SNAKE_468: offset = 1.0f; break; - case 459: + case RACE_CORATHUS_459: offset = 1.0f; break; - case 462: + case RACE_DRACHNID_COCOON_462: offset = 1.5f; break; - case 530: + case RACE_DRAGON_530: offset = 1.2f; break; - case 549: + case RACE_GOO_549: offset = 0.5f; break; - case 548: + case RACE_GOO_548: offset = 0.5f; break; - case 547: + case RACE_GOO_547: offset = 0.5f; break; - case 604: + case RACE_DRACOLICH_604: offset = 1.2f; break; - case 653: + case RACE_TELMIRA_653: offset = 5.9f; break; - case 658: + case RACE_MORELL_THULE_658: offset = 4.0f; break; - case 323: + case RACE_ARMOR_OF_MARR_323: offset = 5.0f; break; - case 663: + case RACE_AMYGDALAN_663: offset = 5.0f; break; - case 664: + case RACE_SANDMAN_664: offset = 4.0f; break; - case 703: + case RACE_ALARAN_SENTRY_STONE_703: offset = 9.0f; break; - case 688: + case RACE_RABBIT_668: offset = 5.0f; break; - case 669: + case RACE_BLIND_DREAMER_669: offset = 7.0f; break; - case 687: + case RACE_GORAL_687: offset = 2.0f; break; - case 686: + case RACE_SELYRAH_686: offset = 2.0f; break; default: offset = 3.125f; } - return 0.2 * GetSize() * offset; + float mob_size = (GetSize() > 0 ? GetSize() : GetDefaultRaceSize()); + + return static_cast(0.2 * mob_size * offset); } // This function will try to move the mob along the relative angle a set distance diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 7c60bffe0..7b5524605 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1765,8 +1765,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } break; } - case ServerOP_ReloadRules: - { + case ServerOP_ReloadRules: { + worldserver.SendEmoteMessage( + 0, 0, 0, 15, + "Rules reloaded for Zone: '%s' Instance ID: %u", + zone->GetLongName(), + zone->GetInstanceID() + ); RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset()); break; } diff --git a/zone/zone.cpp b/zone/zone.cpp index 90d59e17e..d43527c4f 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -42,7 +42,9 @@ #include "net.h" #include "npc.h" #include "object.h" -#include "pathing.h" +#include "pathfinder_null.h" +#include "pathfinder_nav_mesh.h" +#include "pathfinder_waypoint.h" #include "petitions.h" #include "quest_parser_collection.h" #include "spawn2.h" @@ -148,8 +150,15 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { zone->RequestUCSServerStatus(); - /* Set Logging */ + /** + * Set Shutdown timer + */ + uint32 shutdown_timer = static_cast(database.getZoneShutDownDelay(zone->GetZoneID(), zone->GetInstanceVersion())); + zone->StartShutdownTimer(shutdown_timer); + /* + * Set Logging + */ LogSys.StartFileLogs(StringFormat("%s_version_%u_inst_id_%u_port_%u", zone->GetShortName(), zone->GetInstanceVersion(), zone->GetInstanceID(), ZoneConfig::get()->ZonePort)); return true; @@ -898,7 +907,7 @@ bool Zone::Init(bool iStaticZone) { zone->zonemap = Map::LoadMapFile(zone->map_name); zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name); - zone->pathing = PathManager::LoadPathFile(zone->map_name); + zone->pathing = IPathfinder::Load(zone->map_name); Log(Logs::General, Logs::Status, "Loading spawn conditions..."); if(!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) { @@ -1425,11 +1434,18 @@ bool Zone::HasWeather() void Zone::StartShutdownTimer(uint32 set_time) { if (set_time > autoshutdown_timer.GetRemainingTime()) { if (set_time == (RuleI(Zone, AutoShutdownDelay))) { - set_time = database.getZoneShutDownDelay(GetZoneID(), GetInstanceVersion()); + set_time = static_cast(database.getZoneShutDownDelay(GetZoneID(), GetInstanceVersion())); } autoshutdown_timer.SetTimer(set_time); Log(Logs::General, Logs::Zone_Server, "Zone::StartShutdownTimer set to %u", set_time); } + + Log(Logs::Detail, Logs::Zone_Server, + "Zone::StartShutdownTimer trigger - set_time: %u remaining_time: %u diff: %i", + set_time, + autoshutdown_timer.GetRemainingTime(), + (set_time - autoshutdown_timer.GetRemainingTime()) + ); } bool Zone::Depop(bool StartSpawnTimer) { diff --git a/zone/zone.h b/zone/zone.h index bbd070305..c3d5fe8a6 100644 --- a/zone/zone.h +++ b/zone/zone.h @@ -28,6 +28,7 @@ #include "spawn2.h" #include "spawngroup.h" #include "aa_ability.h" +#include "pathfinder_interface.h" #include "global_loot_manager.h" struct ZonePoint @@ -74,7 +75,6 @@ struct item_tick_struct { class Client; class Map; class Mob; -class PathManager; class WaterMap; extern EntityList entity_list; struct NPCType; @@ -214,7 +214,7 @@ public: Map* zonemap; WaterMap* watermap; - PathManager *pathing; + IPathfinder *pathing; NewZone_Struct newzone_data; SpawnConditionManager spawn_conditions; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index cef24a649..f79288126 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -673,7 +673,7 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, EQEmu::ItemInstance* cont uint8 index = (uint8)atoi(row[0]); uint32 item_id = (uint32)atoi(row[1]); int8 charges = (int8)atoi(row[2]); - uint32 aug[EQEmu::inventory::SocketCount]; + uint32 aug[EQEmu::invaug::SOCKET_COUNT]; aug[0] = (uint32)atoi(row[3]); aug[1] = (uint32)atoi(row[4]); aug[2] = (uint32)atoi(row[5]); @@ -683,7 +683,7 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, EQEmu::ItemInstance* cont EQEmu::ItemInstance* inst = database.CreateItem(item_id, charges); if (inst && inst->GetItem()->IsClassCommon()) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) if (aug[i]) inst->PutAugment(&database, i, aug[i]); // Put item inside world container @@ -706,17 +706,17 @@ void ZoneDatabase::SaveWorldContainer(uint32 zone_id, uint32 parent_id, const EQ DeleteWorldContainer(parent_id,zone_id); // Save all 10 items, if they exist - for (uint8 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; index++) { + for (uint8 index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; index++) { EQEmu::ItemInstance* inst = container->GetItem(index); if (!inst) continue; uint32 item_id = inst->GetItem()->ID; - uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 }; + uint32 augslot[EQEmu::invaug::SOCKET_COUNT] = { 0, 0, 0, 0, 0, 0 }; if (inst->IsType(EQEmu::item::ItemClassCommon)) { - for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) { + for (int i = EQEmu::invaug::SOCKET_BEGIN; i <= EQEmu::invaug::SOCKET_END; i++) { EQEmu::ItemInstance *auginst=inst->GetAugment(i); augslot[i]=(auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0; } @@ -1367,11 +1367,11 @@ bool ZoneDatabase::LoadCharacterMaterialColor(uint32 character_id, PlayerProfile bool ZoneDatabase::LoadCharacterBandolier(uint32 character_id, PlayerProfile_Struct* pp) { std::string query = StringFormat("SELECT `bandolier_id`, `bandolier_slot`, `item_id`, `icon`, `bandolier_name` FROM `character_bandolier` WHERE `id` = %u LIMIT %u", - character_id, EQEmu::legacy::BANDOLIERS_SIZE); + character_id, EQEmu::profile::BANDOLIERS_SIZE); auto results = database.QueryDatabase(query); int i = 0; int r = 0; int si = 0; - for (i = 0; i < EQEmu::legacy::BANDOLIERS_SIZE; i++) { + for (i = 0; i < EQEmu::profile::BANDOLIERS_SIZE; i++) { pp->bandoliers[i].Name[0] = '\0'; - for (int si = 0; si < EQEmu::legacy::BANDOLIER_ITEM_COUNT; si++) { + for (int si = 0; si < EQEmu::profile::BANDOLIER_ITEM_COUNT; si++) { pp->bandoliers[i].Items[si].ID = 0; pp->bandoliers[i].Items[si].Icon = 0; pp->bandoliers[i].Items[si].Name[0] = '\0'; @@ -1405,7 +1405,7 @@ bool ZoneDatabase::LoadCharacterTribute(uint32 character_id, PlayerProfile_Struc std::string query = StringFormat("SELECT `tier`, `tribute` FROM `character_tribute` WHERE `id` = %u", character_id); auto results = database.QueryDatabase(query); int i = 0; - for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++){ + for (i = 0; i < EQEmu::invtype::TRIBUTE_SIZE; i++){ pp->tributes[i].tribute = 0xFFFFFFFF; pp->tributes[i].tier = 0; } @@ -1424,10 +1424,10 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc { std::string query = StringFormat("SELECT `potion_id`, `item_id`, `icon` FROM `character_potionbelt` WHERE `id` = %u LIMIT %u", - character_id, EQEmu::legacy::POTION_BELT_ITEM_COUNT); + character_id, EQEmu::profile::POTION_BELT_SIZE); auto results = database.QueryDatabase(query); int i = 0; - for (i = 0; i < EQEmu::legacy::POTION_BELT_ITEM_COUNT; i++) { + for (i = 0; i < EQEmu::profile::POTION_BELT_SIZE; i++) { pp->potionbelt.Items[i].Icon = 0; pp->potionbelt.Items[i].ID = 0; pp->potionbelt.Items[i].Name[0] = '\0'; @@ -1525,7 +1525,7 @@ bool ZoneDatabase::SaveCharacterTribute(uint32 character_id, PlayerProfile_Struc std::string query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", character_id); QueryDatabase(query); /* Save Tributes only if we have values... */ - for (int i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++){ + for (int i = 0; i < EQEmu::invtype::TRIBUTE_SIZE; i++){ if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != TRIBUTE_NONE){ std::string query = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); QueryDatabase(query); @@ -2906,7 +2906,7 @@ void ZoneDatabase::LoadMercEquipment(Merc *merc) { int itemCount = 0; for(auto row = results.begin(); row != results.end(); ++row) { - if (itemCount == EQEmu::legacy::EQUIPMENT_SIZE) + if (itemCount == EQEmu::invslot::EQUIPMENT_COUNT) break; if(atoi(row[0]) == 0) @@ -3456,7 +3456,7 @@ void ZoneDatabase::SavePetInfo(Client *client) query.clear(); // pet inventory! - for (int index = EQEmu::legacy::EQUIPMENT_BEGIN; index <= EQEmu::legacy::EQUIPMENT_END; index++) { + for (int index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::EQUIPMENT_END; index++) { if (!petinfo->Items[index]) continue; @@ -3588,7 +3588,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) continue; int slot = atoi(row[1]); - if (slot < EQEmu::legacy::EQUIPMENT_BEGIN || slot > EQEmu::legacy::EQUIPMENT_END) + if (slot < EQEmu::invslot::EQUIPMENT_BEGIN || slot > EQEmu::invslot::EQUIPMENT_END) continue; pi->Items[slot] = atoul(row[2]); @@ -3842,12 +3842,16 @@ uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, const glm:: return 0; } uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, const glm::vec4& position) { + + double xcorpse = (position.x + zone->random.Real(-20,20)); + double ycorpse = (position.y + zone->random.Real(-20,20)); + std::string query = StringFormat("UPDATE `character_corpses` " "SET `zone_id` = %u, `instance_id` = 0, " "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, " "`was_at_graveyard` = 1 " "WHERE `id` = %d", - zone_id, position.x, position.y, position.z, position.w, dbid); + zone_id, xcorpse, ycorpse, position.z, position.w, dbid); QueryDatabase(query); return dbid; } diff --git a/zone/zonedb.h b/zone/zonedb.h index d0e7b1a99..8943f6f01 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -148,7 +148,7 @@ struct PetInfo { uint32 Mana; float size; SpellBuff_Struct Buffs[PET_BUFF_COUNT]; - uint32 Items[EQEmu::legacy::EQUIPMENT_SIZE]; + uint32 Items[EQEmu::invslot::EQUIPMENT_COUNT]; char Name[64]; }; @@ -469,7 +469,7 @@ public: /* Doors */ bool DoorIsOpen(uint8 door_id,const char* zone_name); void SetDoorPlace(uint8 value,uint8 door_id,const char* zone_name); - bool LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version); + bool LoadDoors(int32 door_count, Door *into, const char *zone_name, int16 version); bool CheckGuildDoor(uint8 doorid,uint16 guild_id, const char* zone); bool SetGuildDoor(uint8 doorid,uint16 guild_id, const char* zone); uint32 GetGuildEQID(uint32 guilddbid);